2020-11-09 05:23:58 +01:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2015-04-10 23:15:59 +02:00
# pragma once
# include <stdarg.h>
2015-11-18 22:46:33 +01:00
# include <stdbool.h>
2015-04-10 23:15:59 +02:00
# include <stdio.h>
2019-04-26 12:27:33 +02:00
# include <syslog.h>
2015-11-30 21:43:37 +01:00
# include <sys/types.h>
2015-04-10 23:15:59 +02:00
# include "macro.h"
# include "time-util.h"
2018-03-01 18:23:05 +01:00
/* Regular colors */
2020-07-23 10:13:58 +02:00
# define ANSI_BLACK "\x1B[0;30m" /* Some type of grey usually. */
2018-03-01 18:23:05 +01:00
# define ANSI_RED "\x1B[0;31m"
# define ANSI_GREEN "\x1B[0;32m"
# define ANSI_YELLOW "\x1B[0;33m"
# define ANSI_BLUE "\x1B[0;34m"
# define ANSI_MAGENTA "\x1B[0;35m"
2020-07-23 10:13:58 +02:00
# define ANSI_CYAN "\x1B[0;36m"
# define ANSI_WHITE "\x1B[0;37m" / * This is actually rendered as light grey, legible even on a white
* background . See ANSI_HIGHLIGHT_WHITE for real white . */
# define ANSI_BRIGHT_BLACK "\x1B[0;90m"
# define ANSI_BRIGHT_RED "\x1B[0;91m"
# define ANSI_BRIGHT_GREEN "\x1B[0;92m"
# define ANSI_BRIGHT_YELLOW "\x1B[0;93m"
# define ANSI_BRIGHT_BLUE "\x1B[0;94m"
# define ANSI_BRIGHT_MAGENTA "\x1B[0;95m"
# define ANSI_BRIGHT_CYAN "\x1B[0;96m"
# define ANSI_BRIGHT_WHITE "\x1B[0;97m"
2019-05-10 20:52:05 +02:00
# define ANSI_GREY "\x1B[0;38;5;245m"
2018-03-01 18:23:05 +01:00
/* Bold/highlighted */
2020-07-23 10:53:48 +02:00
# define ANSI_HIGHLIGHT_BLACK "\x1B[0;1;30m"
# define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
# define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
# define _ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m" /* This yellow is currently not displayed well by some terminals */
# define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
# define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m"
# define ANSI_HIGHLIGHT_CYAN "\x1B[0;1;36m"
# define ANSI_HIGHLIGHT_WHITE "\x1B[0;1;37m"
# define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38;5;100m"
# define ANSI_HIGHLIGHT_KHAKI3 "\x1B[0;1;38;5;185m"
# define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38;5;245m"
# define ANSI_HIGHLIGHT_YELLOW ANSI_HIGHLIGHT_KHAKI3 /* Replacement yellow that is more legible */
2018-03-01 18:23:05 +01:00
/* Underlined */
2020-05-06 14:56:37 +02:00
# define ANSI_GREY_UNDERLINE "\x1B[0;4;38;5;245m"
2018-03-01 18:23:05 +01:00
# define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m"
# define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m"
2020-04-08 19:43:44 +02:00
# define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38;5;185m"
2018-03-01 18:23:05 +01:00
# define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m"
# define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m"
2019-05-10 20:55:59 +02:00
# define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38;5;245m"
2018-03-01 18:23:05 +01:00
/* Other ANSI codes */
2015-09-19 00:45:05 +02:00
# define ANSI_UNDERLINE "\x1B[0;4m"
# define ANSI_HIGHLIGHT "\x1B[0;1;39m"
# define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m"
2018-03-01 18:23:05 +01:00
/* Reset/clear ANSI styles */
2015-09-19 00:45:05 +02:00
# define ANSI_NORMAL "\x1B[0m"
2018-03-01 18:23:05 +01:00
/* Erase characters until the end of the line */
2015-04-10 23:15:59 +02:00
# define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
2018-05-20 17:58:58 +02:00
/* Move cursor up one line */
# define ANSI_REVERSE_LINEFEED "\x1BM"
2015-09-19 00:45:05 +02:00
/* Set cursor to top left corner and clear screen */
# define ANSI_HOME_CLEAR "\x1B[H\x1B[2J"
2015-04-10 23:15:59 +02:00
int reset_terminal_fd ( int fd , bool switch_to_text ) ;
int reset_terminal ( const char * name ) ;
int open_terminal ( const char * name , int mode ) ;
2018-02-13 21:24:37 +01:00
/* Flags for tweaking the way we become the controlling process of a terminal. */
typedef enum AcquireTerminalFlags {
/* Try to become the controlling process of the TTY. If we can't return -EPERM. */
2018-06-07 16:03:43 +02:00
ACQUIRE_TERMINAL_TRY = 0 ,
2018-02-13 21:24:37 +01:00
/* Tell the kernel to forcibly make us the controlling process of the TTY. Returns -EPERM if the kernel doesn't allow that. */
2018-06-07 16:03:43 +02:00
ACQUIRE_TERMINAL_FORCE = 1 ,
2018-02-13 21:24:37 +01:00
/* If we can't become the controlling process of the TTY right-away, then wait until we can. */
2018-06-07 16:03:43 +02:00
ACQUIRE_TERMINAL_WAIT = 2 ,
2018-02-13 21:24:37 +01:00
/* Pick one of the above, and then OR this flag in, in order to request permissive behaviour, if we can't become controlling process then don't mind */
2018-06-07 16:03:43 +02:00
ACQUIRE_TERMINAL_PERMISSIVE = 1 < < 2 ,
2018-02-13 21:24:37 +01:00
} AcquireTerminalFlags ;
int acquire_terminal ( const char * name , AcquireTerminalFlags flags , usec_t timeout ) ;
2015-04-10 23:15:59 +02:00
int release_terminal ( void ) ;
int terminal_vhangup_fd ( int fd ) ;
int terminal_vhangup ( const char * name ) ;
int chvt ( int vt ) ;
int read_one_char ( FILE * f , char * ret , usec_t timeout , bool * need_nl ) ;
int ask_char ( char * ret , const char * replies , const char * text , . . . ) _printf_ ( 3 , 4 ) ;
int ask_string ( char * * ret , const char * text , . . . ) _printf_ ( 2 , 3 ) ;
int vt_disallocate ( const char * name ) ;
2018-02-14 17:30:37 +01:00
int resolve_dev_console ( char * * ret ) ;
2018-02-14 14:56:17 +01:00
int get_kernel_consoles ( char * * * ret ) ;
2015-04-10 23:15:59 +02:00
bool tty_is_vc ( const char * tty ) ;
bool tty_is_vc_resolve ( const char * tty ) ;
bool tty_is_console ( const char * tty ) _pure_ ;
int vtnr_from_tty ( const char * tty ) ;
const char * default_term_for_tty ( const char * tty ) ;
int make_console_stdio ( void ) ;
int fd_columns ( int fd ) ;
unsigned columns ( void ) ;
int fd_lines ( int fd ) ;
unsigned lines ( void ) ;
2018-02-13 23:50:26 +01:00
2015-04-10 23:15:59 +02:00
void columns_lines_cache_reset ( int _unused_ signum ) ;
2018-02-13 23:50:26 +01:00
void reset_terminal_feature_caches ( void ) ;
2015-04-10 23:15:59 +02:00
bool on_tty ( void ) ;
2016-05-30 18:23:54 +02:00
bool terminal_is_dumb ( void ) ;
2016-01-19 10:17:19 +01:00
bool colors_enabled ( void ) ;
2017-09-09 22:48:35 +02:00
bool underline_enabled ( void ) ;
2018-02-14 14:30:30 +01:00
bool dev_console_colors_enabled ( void ) ;
2015-04-10 23:15:59 +02:00
2016-10-17 17:48:12 +02:00
# define DEFINE_ANSI_FUNC(name, NAME) \
static inline const char * ansi_ # # name ( void ) { \
return colors_enabled ( ) ? ANSI_ # # NAME : " " ; \
2018-03-06 09:34:03 +01:00
}
2016-10-17 17:48:12 +02:00
2017-09-09 22:48:35 +02:00
# define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME, REPLACEMENT) \
static inline const char * ansi_ # # name ( void ) { \
return underline_enabled ( ) ? ANSI_ # # NAME : \
colors_enabled ( ) ? ANSI_ # # REPLACEMENT : " " ; \
2018-03-06 09:34:03 +01:00
}
2017-09-09 22:48:35 +02:00
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC ( normal , NORMAL ) ;
DEFINE_ANSI_FUNC ( highlight , HIGHLIGHT ) ;
2020-07-23 10:13:58 +02:00
DEFINE_ANSI_FUNC ( black , BLACK ) ;
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC ( red , RED ) ;
DEFINE_ANSI_FUNC ( green , GREEN ) ;
DEFINE_ANSI_FUNC ( yellow , YELLOW ) ;
DEFINE_ANSI_FUNC ( blue , BLUE ) ;
DEFINE_ANSI_FUNC ( magenta , MAGENTA ) ;
2020-07-23 10:13:58 +02:00
DEFINE_ANSI_FUNC ( cyan , CYAN ) ;
DEFINE_ANSI_FUNC ( white , WHITE ) ;
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC ( grey , GREY ) ;
2020-07-23 10:13:58 +02:00
DEFINE_ANSI_FUNC ( bright_black , BRIGHT_BLACK ) ;
DEFINE_ANSI_FUNC ( bright_red , BRIGHT_RED ) ;
DEFINE_ANSI_FUNC ( bright_green , BRIGHT_GREEN ) ;
DEFINE_ANSI_FUNC ( bright_yellow , BRIGHT_YELLOW ) ;
DEFINE_ANSI_FUNC ( bright_blue , BRIGHT_BLUE ) ;
DEFINE_ANSI_FUNC ( bright_magenta , BRIGHT_MAGENTA ) ;
DEFINE_ANSI_FUNC ( bright_cyan , BRIGHT_CYAN ) ;
DEFINE_ANSI_FUNC ( bright_white , BRIGHT_WHITE ) ;
DEFINE_ANSI_FUNC ( highlight_black , HIGHLIGHT_BLACK ) ;
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC ( highlight_red , HIGHLIGHT_RED ) ;
DEFINE_ANSI_FUNC ( highlight_green , HIGHLIGHT_GREEN ) ;
DEFINE_ANSI_FUNC ( highlight_yellow , HIGHLIGHT_YELLOW ) ;
DEFINE_ANSI_FUNC ( highlight_blue , HIGHLIGHT_BLUE ) ;
DEFINE_ANSI_FUNC ( highlight_magenta , HIGHLIGHT_MAGENTA ) ;
2020-07-23 10:13:58 +02:00
DEFINE_ANSI_FUNC ( highlight_cyan , HIGHLIGHT_CYAN ) ;
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC ( highlight_grey , HIGHLIGHT_GREY ) ;
2020-07-23 10:13:58 +02:00
DEFINE_ANSI_FUNC ( highlight_white , HIGHLIGHT_WHITE ) ;
2019-05-10 20:57:01 +02:00
2020-07-23 10:53:48 +02:00
static inline const char * _ansi_highlight_yellow ( void ) {
return colors_enabled ( ) ? _ANSI_HIGHLIGHT_YELLOW : " " ;
}
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC_UNDERLINE ( underline , UNDERLINE , NORMAL ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_underline , HIGHLIGHT_UNDERLINE , HIGHLIGHT ) ;
2020-05-06 14:56:37 +02:00
DEFINE_ANSI_FUNC_UNDERLINE ( grey_underline , GREY_UNDERLINE , GREY ) ;
2019-05-10 20:57:01 +02:00
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_red_underline , HIGHLIGHT_RED_UNDERLINE , HIGHLIGHT_RED ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_green_underline , HIGHLIGHT_GREEN_UNDERLINE , HIGHLIGHT_GREEN ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_yellow_underline , HIGHLIGHT_YELLOW_UNDERLINE , HIGHLIGHT_YELLOW ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_blue_underline , HIGHLIGHT_BLUE_UNDERLINE , HIGHLIGHT_BLUE ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_magenta_underline , HIGHLIGHT_MAGENTA_UNDERLINE , HIGHLIGHT_MAGENTA ) ;
DEFINE_ANSI_FUNC_UNDERLINE ( highlight_grey_underline , HIGHLIGHT_GREY_UNDERLINE , HIGHLIGHT_GREY ) ;
2017-09-09 22:48:35 +02:00
2015-04-10 23:15:59 +02:00
int get_ctty_devnr ( pid_t pid , dev_t * d ) ;
int get_ctty ( pid_t , dev_t * _devnr , char * * r ) ;
int getttyname_malloc ( int fd , char * * r ) ;
int getttyname_harder ( int fd , char * * r ) ;
2015-09-01 20:12:25 +02:00
2015-10-07 22:45:48 +02:00
int ptsname_malloc ( int fd , char * * ret ) ;
2019-06-07 10:17:11 +02:00
int openpt_allocate ( int flags , char * * ret_slave ) ;
int openpt_allocate_in_namespace ( pid_t pid , int flags , char * * ret_slave ) ;
2015-10-07 23:38:20 +02:00
int open_terminal_in_namespace ( pid_t pid , const char * name , int mode ) ;
2017-09-01 02:09:32 +02:00
int vt_default_utf8 ( void ) ;
int vt_reset_keyboard ( int fd ) ;
2018-08-27 22:33:44 +02:00
int vt_restore ( int fd ) ;
2018-08-27 22:42:00 +02:00
int vt_release ( int fd , bool restore_vt ) ;
2019-04-26 12:27:33 +02:00
void get_log_colors ( int priority , const char * * on , const char * * off , const char * * highlight ) ;
2019-04-30 19:26:14 +02:00
/* This assumes there is a 'tty' group */
# define TTY_MODE 0620