* 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 {
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:
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();
}
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;
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;
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"));