From 6343ee8c10a8302740b2b8ef208c27846f7ae16f Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 14 May 2018 13:51:01 +0200 Subject: script: record exit code Signed-off-by: Karel Zak --- term-utils/script.1 | 3 ++- term-utils/script.c | 53 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'term-utils') diff --git a/term-utils/script.1 b/term-utils/script.1 index 041b7620b..0fb4c4fd7 100644 --- a/term-utils/script.1 +++ b/term-utils/script.1 @@ -75,7 +75,8 @@ tty. .TP \fB\-e\fR, \fB\-\-return\fR Return the exit code of the child process. Uses the same format as bash -termination on signal termination exit code is 128+n. +termination on signal termination exit code is 128+n. The exit code of +the child process is always stored in type script file too. .TP \fB\-f\fR, \fB\-\-flush\fR Flush output after each write. This is nice for telecooperation: one person diff --git a/term-utils/script.c b/term-utils/script.c index b7bec7e76..506f0bb38 100644 --- a/term-utils/script.c +++ b/term-utils/script.c @@ -212,6 +212,24 @@ static void typescript_message_start(const struct script_control *ctl, time_t *t fputs("]\n", ctl->typescriptfp); } +static void typescript_message_done(const struct script_control *ctl, int status, const char *msg) +{ + char buf[FORMAT_TIMESTAMP_MAX]; + time_t tvec; + + if (!ctl->typescriptfp) + return; + + tvec = script_time((time_t *)NULL); + + strtime_iso(&tvec, ISO_TIMESTAMP, buf, sizeof(buf)); + + if (msg) + fprintf(ctl->typescriptfp, _("\nScript done on %s [<%s>]\n"), buf, msg); + else + fprintf(ctl->typescriptfp, _("\nScript done on %s [COMMAND_EXIT_CODE=\"%d\"]\n"), buf, status); +} + static void die_if_link(const struct script_control *ctl) { struct stat s; @@ -249,22 +267,24 @@ static void enable_rawmode_tty(struct script_control *ctl) tcsetattr(STDIN_FILENO, TCSANOW, &rtt); } -static void __attribute__((__noreturn__)) done(struct script_control *ctl) +static void __attribute__((__noreturn__)) done_log(struct script_control *ctl, const char *log_msg) { + int childstatus; + DBG(MISC, ul_debug("done!")); restore_tty(ctl, TCSADRAIN); - if (ctl->typescriptfp) { - char buf[FORMAT_TIMESTAMP_MAX]; - time_t tvec = script_time((time_t *)NULL); + if (WIFSIGNALED(ctl->childstatus)) + childstatus = WTERMSIG(ctl->childstatus) + 0x80; + else + childstatus = WEXITSTATUS(ctl->childstatus); - strtime_iso(&tvec, ISO_TIMESTAMP, buf, sizeof(buf)); - fprintf(ctl->typescriptfp, _("\nScript done on %s\n"), buf); + if (ctl->typescriptfp) { + typescript_message_done(ctl, childstatus, log_msg); + if (!ctl->quiet) + printf(_("Script done, file is %s\n"), ctl->fname); } - - if (!ctl->quiet && ctl->typescriptfp) - printf(_("Script done, file is %s\n"), ctl->fname); #ifdef HAVE_LIBUTEMPTER if (ctl->master >= 0) utempter_remove_record(ctl->master); @@ -276,13 +296,12 @@ static void __attribute__((__noreturn__)) done(struct script_control *ctl) if (ctl->typescriptfp && close_stream(ctl->typescriptfp) != 0) err(EXIT_FAILURE, "write failed: %s", ctl->fname); - if (ctl->rc_wanted) { - if (WIFSIGNALED(ctl->childstatus)) - exit(WTERMSIG(ctl->childstatus) + 0x80); - else - exit(WEXITSTATUS(ctl->childstatus)); - } - exit(EXIT_SUCCESS); + exit(ctl->rc_wanted ? childstatus : EXIT_SUCCESS); +} + +static void __attribute__((__noreturn__)) done(struct script_control *ctl) +{ + done_log(ctl, NULL); } static void __attribute__((__noreturn__)) fail(struct script_control *ctl) @@ -437,7 +456,7 @@ static void handle_io(struct script_control *ctl, int fd, int *eof) if (!ctl->quiet) printf(_("Script terminated, max output file size %zd exceeded.\n"), ctl->maxsz); DBG(IO, ul_debug("output size %zd, exceeded limit %zd", ctl->outsz, ctl->maxsz)); - done(ctl); + done_log(ctl, _("max output size exceeded")); } } } -- cgit v1.2.3-55-g7522