script: record exit code

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2018-05-14 13:51:01 +02:00
parent 400c1c574b
commit 6343ee8c10
3 changed files with 38 additions and 20 deletions

View File

@ -15,8 +15,6 @@ column
script
------
- (!) add [exit=<command-exit-code>] to the "done" typescript message
- think about optional "event" records in timing file to save information
about non-data changes like signals (SIGWINCH, SIGSTOP, SIGCONT, etc.)
in format:

View File

@ -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

View File

@ -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 (WIFSIGNALED(ctl->childstatus))
childstatus = WTERMSIG(ctl->childstatus) + 0x80;
else
childstatus = WEXITSTATUS(ctl->childstatus);
if (ctl->typescriptfp) {
char buf[FORMAT_TIMESTAMP_MAX];
time_t tvec = script_time((time_t *)NULL);
strtime_iso(&tvec, ISO_TIMESTAMP, buf, sizeof(buf));
fprintf(ctl->typescriptfp, _("\nScript done on %s\n"), buf);
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"));
}
}
}