1 /* 2 * This code is in the public domain; do with it what you wish. 3 * 4 * Written by Karel Zak <kzak@redhat.com> in Jul 2019 5 */ 6 #ifndef UTIL_LINUX_PTY_SESSION_H 7 #define UTIL_LINUX_PTY_SESSION_H 8 9 #include <pty.h> 10 #include <termios.h> 11 #include <signal.h> 12 #include <sys/time.h> 13 14 #include <sys/signalfd.h> 15 16 /* 17 * Callbacks -- the first argument is always callback data, see 18 * ul_pty_set_callback_data(). 19 */ 20 struct ul_pty_callbacks { 21 /* 22 * Optional. Executed on SIGCHLD when ssi_code is EXITED, KILLED or 23 * DUMPED; The callback has to call ul_pty_set_child(pty, (pid_t) -1) 24 * if child is no more alive. 25 */ 26 void (*child_wait)(void *, pid_t); 27 28 /* 29 * Used when child_wait() undefined to informa about child status 30 */ 31 void (*child_die)(void *, pid_t, int); 32 33 /* 34 * Executed on SIGCHLD when ssi_status is SIGSTOP 35 */ 36 void (*child_sigstop)(void *, pid_t); 37 38 /* 39 * Executed in master loop before ul_pty enter poll() and in time set by 40 * ul_pty_set_mainloop_time(). The callback is no used when time is not set. 41 */ 42 int (*mainloop)(void *); 43 44 /* 45 * Executed on master or stdin activity, arguments: 46 * 2nd - file descriptor 47 * 3rd - buffer with data 48 * 4th - size of the data 49 */ 50 int (*log_stream_activity)(void *, int, char *, size_t); 51 52 /* 53 * Executed on signal, arguments: 54 * 2nd - signal info 55 * 3rd - NULL or signal specific data (e.g. struct winsize on SIGWINCH 56 */ 57 int (*log_signal)(void *, struct signalfd_siginfo *, void *); 58 59 /* 60 * Executed on SIGUSR1 61 */ 62 int (*flush_logs)(void *); 63 }; 64 65 struct ul_pty { 66 struct termios stdin_attrs; /* stdin and slave terminal runtime attributes */ 67 int master; /* parent side */ 68 int slave; /* child side */ 69 int sigfd; /* signalfd() */ 70 int poll_timeout; 71 struct winsize win; /* terminal window size */ 72 sigset_t orgsig; /* original signal mask */ 73 74 int delivered_signal; 75 76 struct ul_pty_callbacks callbacks; 77 void *callback_data; 78 79 pid_t child; 80 81 struct timeval next_callback_time; 82 83 unsigned int isterm:1, /* is stdin terminal? */ 84 slave_echo:1; /* keep ECHO on stdin */ 85 }; 86 87 void ul_pty_init_debug(int mask); 88 struct ul_pty *ul_new_pty(int is_stdin_tty); 89 void ul_free_pty(struct ul_pty *pty); 90 91 void ul_pty_slave_echo(struct ul_pty *pty, int enable); 92 int ul_pty_get_delivered_signal(struct ul_pty *pty); 93 94 void ul_pty_set_callback_data(struct ul_pty *pty, void *data); 95 void ul_pty_set_child(struct ul_pty *pty, pid_t child); 96 97 struct ul_pty_callbacks *ul_pty_get_callbacks(struct ul_pty *pty); 98 int ul_pty_is_running(struct ul_pty *pty); 99 int ul_pty_setup(struct ul_pty *pty); 100 void ul_pty_cleanup(struct ul_pty *pty); 101 void ul_pty_init_slave(struct ul_pty *pty); 102 int ul_pty_proxy_master(struct ul_pty *pty); 103 104 void ul_pty_set_mainloop_time(struct ul_pty *pty, struct timeval *tv); 105 int ul_pty_get_childfd(struct ul_pty *pty); 106 void ul_pty_wait_for_child(struct ul_pty *pty); 107 pid_t ul_pty_get_child(struct ul_pty *pty); 108 void ul_pty_write_eof_to_child(struct ul_pty *pty); 109 110 #endif /* UTIL_LINUX_PTY_H */ 111