]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
script: listen to SIGUSR1, flush logs on the signal
authorKarel Zak <kzak@redhat.com>
Mon, 9 Dec 2019 15:04:18 +0000 (16:04 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 9 Dec 2019 15:04:18 +0000 (16:04 +0100)
Based on pull request: https://github.com/karelzak/util-linux/pull/815

Signed-off-by: Karel Zak <kzak@redhat.com>
include/pty-session.h
lib/pty-session.c
term-utils/script.c

index 9681bcc7793a22a5821abaf2f1a8c74e26b03e6f..19656f908e09d454311f9cc39aa3c1a259b18c66 100644 (file)
@@ -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 {
index b668e953fc96bf11f91027b3919a211a0d19d0c9..68cd9e6c0a7585e7675bf4335e39017ba9878898 100644 (file)
@@ -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();
        }
index d5a3836320ba1382688a5f0ed15c28920fbb75f1..de95645903346c3a2d0398c75d7ab70159f3f1a0 100644 (file)
@@ -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"));