diff --git a/include/pty-session.h b/include/pty-session.h index 9681bcc77..19656f908 100644 --- a/include/pty-session.h +++ b/include/pty-session.h @@ -55,6 +55,11 @@ struct ul_pty_callbacks { * 3rd - NULL or signal specific data (e.g. struct winsize on SIGWINCH */ int (*log_signal)(void *, struct signalfd_siginfo *, void *); + + /* + * Executed on SIGUSR1 + */ + int (*flush_logs)(void *); }; struct ul_pty { diff --git a/lib/pty-session.c b/lib/pty-session.c index b668e953f..68cd9e6c0 100644 --- a/lib/pty-session.c +++ b/lib/pty-session.c @@ -210,6 +210,9 @@ int ul_pty_setup(struct ul_pty *pty) sigaddset(&ourset, SIGINT); sigaddset(&ourset, SIGQUIT); + if (pty->callbacks.flush_logs) + sigaddset(&ourset, SIGUSR1); + if ((pty->sigfd = signalfd(-1, &ourset, SFD_CLOEXEC)) < 0) rc = -errno; done: @@ -484,6 +487,11 @@ static int handle_signal(struct ul_pty *pty, int fd) rc = pty->callbacks.log_signal(pty->callback_data, &info, (void *) &pty->win); break; + case SIGUSR1: + DBG(SIG, ul_debugobj(pty, " get signal SIGUSR1")); + if (pty->callbacks.flush_logs) + rc = pty->callbacks.flush_logs(pty->callback_data); + break; default: abort(); } diff --git a/term-utils/script.c b/term-utils/script.c index d5a383632..de9564590 100644 --- a/term-utils/script.c +++ b/term-utils/script.c @@ -325,6 +325,18 @@ static int log_close(struct script_control *ctl, return rc; } +static int log_flush(struct script_control *ctl __attribute__((__unused__)), struct script_log *log) +{ + + if (!log || !log->initialized) + return 0; + + DBG(MISC, ul_debug("flushing %s", log->filename)); + + fflush(log->fp); + return 0; +} + static void log_free(struct script_control *ctl, struct script_log *log) { size_t i; @@ -701,6 +713,25 @@ static int callback_log_signal(void *data, struct signalfd_siginfo *info, void * return ssz < 0 ? ssz : 0; } +static int callback_flush_logs(void *data) +{ + struct script_control *ctl = (struct script_control *) data; + size_t i; + + for (i = 0; i < ctl->out.nlogs; i++) { + int rc = log_flush(ctl, ctl->out.logs[i]); + if (rc) + return rc; + } + + for (i = 0; i < ctl->in.nlogs; i++) { + int rc = log_flush(ctl, ctl->in.logs[i]); + if (rc) + return rc; + } + return 0; +} + static void die_if_link(struct script_control *ctl, const char *filename) { struct stat s; @@ -901,6 +932,7 @@ int main(int argc, char **argv) cb->child_sigstop = callback_child_sigstop; cb->log_stream_activity = callback_log_stream_activity; cb->log_signal = callback_log_signal; + cb->flush_logs = callback_flush_logs; if (!ctl.quiet) { printf(_("Script started"));