CVS commit: src/usr.bin/script
Module Name:src Committed By: hgutch Date: Tue May 9 15:43:39 UTC 2023 Modified Files: src/usr.bin/script: script.c Log Message: Reset SIGCHLD handler to SIG_DFL. If run with "-c", both child and parent script processes will handle SIGCHLD resulting in a possible duplicate "Script done" line in the output. This fixes bin/54514. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.33 src/usr.bin/script/script.c:1.34 --- src/usr.bin/script/script.c:1.33 Sun Feb 13 19:40:14 2022 +++ src/usr.bin/script/script.c Tue May 9 15:43:39 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.33 2022/02/13 19:40:14 christos Exp $ */ +/* $NetBSD: script.c,v 1.34 2023/05/09 15:43:39 hgutch Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.33 2022/02/13 19:40:14 christos Exp $"); +__RCSID("$NetBSD: script.c,v 1.34 2023/05/09 15:43:39 hgutch Exp $"); #endif /* not lint */ #include @@ -192,6 +192,7 @@ main(int argc, char *argv[]) fail(); } if (child == 0) { + (void)xsignal(SIGCHLD, SIG_DFL); subchild = child = fork(); if (child == -1) { warn("fork");
CVS commit: src/usr.bin/script
Module Name:src Committed By: hgutch Date: Tue May 9 15:43:39 UTC 2023 Modified Files: src/usr.bin/script: script.c Log Message: Reset SIGCHLD handler to SIG_DFL. If run with "-c", both child and parent script processes will handle SIGCHLD resulting in a possible duplicate "Script done" line in the output. This fixes bin/54514. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Sun Feb 13 19:40:14 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: 1. restore the previous finish() logic to make: script -e -c /usr/bin/true script -e -c /usr/bin/false exit with the proper exit code. 2. handle system return value correctly (nabijaczleweli) 3. factor out the conversion of wait status -> shell return code. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.32 src/usr.bin/script/script.c:1.33 --- src/usr.bin/script/script.c:1.32 Sat Feb 12 18:03:52 2022 +++ src/usr.bin/script/script.c Sun Feb 13 14:40:14 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.32 2022/02/12 23:03:52 rillig Exp $ */ +/* $NetBSD: script.c,v 1.33 2022/02/13 19:40:14 christos Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.32 2022/02/12 23:03:52 rillig Exp $"); +__RCSID("$NetBSD: script.c,v 1.33 2022/02/13 19:40:14 christos Exp $"); #endif /* not lint */ #include @@ -231,23 +231,30 @@ xsignal(int signo, sig_t handler) return osa.sa_handler; } +static int +getshellstatus(int status) +{ + if (WIFEXITED(status)) + return WEXITSTATUS(status); + if (WIFSIGNALED(status)) + return 128 + WTERMSIG(status); + return EXIT_FAILURE; +} + static void finish(int signo) { int pid, status; + die = 0; while ((pid = wait()) > 0) if (pid == child) { - cstat = status; die = 1; } - if (!eflag) - cstat = EXIT_SUCCESS; - else if (WIFEXITED(cstat)) - cstat = WEXITSTATUS(cstat); - else - cstat = 128 + WTERMSIG(cstat); + if (!die) + return; + done(eflag ? getshellstatus(status) : EXIT_SUCCESS); } static void @@ -312,8 +319,11 @@ doshell(const char *command) execl(shell, shell, "-i", NULL); warn("execl `%s'", shell); } else { - if (system(command) == -1) + int ret = system(command); + if (ret == -1) warn("system `%s'", command); + else + exit(eflag ? getshellstatus(ret) : EXIT_FAILURE); } fail();
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Sun Feb 13 19:40:14 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: 1. restore the previous finish() logic to make: script -e -c /usr/bin/true script -e -c /usr/bin/false exit with the proper exit code. 2. handle system return value correctly (nabijaczleweli) 3. factor out the conversion of wait status -> shell return code. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/usr.bin/script
Module Name:src Committed By: rillig Date: Sat Feb 12 23:03:52 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: script: declare dooutput as __dead This fixes the Clang build, which failed with: usr.bin/script/script.c:255:1: error: function 'dooutput' could be declared with attribute 'noreturn' [-Werror,-Wmissing-noreturn] To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/usr.bin/script
Module Name:src Committed By: rillig Date: Sat Feb 12 23:03:52 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: script: declare dooutput as __dead This fixes the Clang build, which failed with: usr.bin/script/script.c:255:1: error: function 'dooutput' could be declared with attribute 'noreturn' [-Werror,-Wmissing-noreturn] To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.31 src/usr.bin/script/script.c:1.32 --- src/usr.bin/script/script.c:1.31 Fri Feb 11 21:15:25 2022 +++ src/usr.bin/script/script.c Sat Feb 12 23:03:52 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $ */ +/* $NetBSD: script.c,v 1.32 2022/02/12 23:03:52 rillig Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $"); +__RCSID("$NetBSD: script.c,v 1.32 2022/02/12 23:03:52 rillig Exp $"); #endif /* not lint */ #include @@ -91,7 +91,7 @@ __dead static void done(int); __dead static void doshell(const char *); __dead static void fail(void); static sig_t xsignal(int, sig_t); -static void dooutput(void); +__dead static void dooutput(void); static void finish(int); static void scriptflush(int); static void record(FILE *, char *, size_t, int);
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Fri Feb 11 21:15:25 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: PR/56254: RVP: Don't call non-async-signal-safe functions from signal handlers. Establish a non-restart signal handler to avoid blocking in long I/Os. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.30 src/usr.bin/script/script.c:1.31 --- src/usr.bin/script/script.c:1.30 Thu Jan 20 14:49:51 2022 +++ src/usr.bin/script/script.c Fri Feb 11 16:15:25 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $ */ +/* $NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $"); +__RCSID("$NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $"); #endif /* not lint */ #include @@ -81,6 +81,8 @@ static int usesleep, rawout; static int quiet, flush; static const char *fname; +static volatile sig_atomic_t die = 0; /* exit if 1 */ +static int cstat = EXIT_SUCCESS; /* cmd. exit status */ static int eflag; static int isterm; static struct termios tt; @@ -88,6 +90,7 @@ static struct termios tt; __dead static void done(int); __dead static void doshell(const char *); __dead static void fail(void); +static sig_t xsignal(int, sig_t); static void dooutput(void); static void finish(int); static void scriptflush(int); @@ -182,7 +185,7 @@ main(int argc, char *argv[]) (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, ); } - (void)signal(SIGCHLD, finish); + (void)xsignal(SIGCHLD, finish); child = fork(); if (child == -1) { warn("fork"); @@ -202,35 +205,49 @@ main(int argc, char *argv[]) if (!rawout) (void)fclose(fscript); - while ((scc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) { + while (!die && (scc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) { cc = (size_t)scc; if (rawout) record(fscript, ibuf, cc, 'i'); (void)write(master, ibuf, cc); } - finish(-1); + done(cstat); +} + +/** + * wrapper around sigaction() because we want POSIX semantics: + * no auto-restarting of interrupted slow syscalls. + */ +static sig_t +xsignal(int signo, sig_t handler) +{ + struct sigaction sa, osa; + + sa.sa_handler = handler; + sa.sa_flags = 0; + sigemptyset(_mask); + if (sigaction(signo, , ) == -1) + return SIG_ERR; + return osa.sa_handler; } static void finish(int signo) { - int die, pid, status, cstat; + int pid, status; - die = 0; while ((pid = wait()) > 0) if (pid == child) { cstat = status; die = 1; } - if (!die) - return; if (!eflag) - done(EXIT_SUCCESS); + cstat = EXIT_SUCCESS; else if (WIFEXITED(cstat)) - done(WEXITSTATUS(cstat)); + cstat = WEXITSTATUS(cstat); else - done(128 + WTERMSIG(cstat)); + cstat = 128 + WTERMSIG(cstat); } static void @@ -268,7 +285,7 @@ dooutput(void) if (flush) (void)fflush(fscript); } - finish(-1); + done(cstat); } static void
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Fri Feb 11 21:15:25 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: PR/56254: RVP: Don't call non-async-signal-safe functions from signal handlers. Establish a non-restart signal handler to avoid blocking in long I/Os. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Thu Jan 20 19:49:51 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: dooutput can return if finish() does not find a chile process. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.29 src/usr.bin/script/script.c:1.30 --- src/usr.bin/script/script.c:1.29 Sun Jan 16 14:04:00 2022 +++ src/usr.bin/script/script.c Thu Jan 20 14:49:51 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.29 2022/01/16 19:04:00 christos Exp $ */ +/* $NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.29 2022/01/16 19:04:00 christos Exp $"); +__RCSID("$NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $"); #endif /* not lint */ #include @@ -86,9 +86,9 @@ static int isterm; static struct termios tt; __dead static void done(int); -__dead static void dooutput(void); __dead static void doshell(const char *); __dead static void fail(void); +static void dooutput(void); static void finish(int); static void scriptflush(int); static void record(FILE *, char *, size_t, int);
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Thu Jan 20 19:49:51 UTC 2022 Modified Files: src/usr.bin/script: script.c Log Message: dooutput can return if finish() does not find a chile process. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Sun Jan 16 19:04:00 UTC 2022 Modified Files: src/usr.bin/script: script.1 script.c Log Message: If -e is specified exit with the exit status of the child process in a shell-like format (nabijaczleweli) To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/usr.bin/script/script.1 cvs rdiff -u -r1.28 -r1.29 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/usr.bin/script/script.1 diff -u src/usr.bin/script/script.1:1.13 src/usr.bin/script/script.1:1.14 --- src/usr.bin/script/script.1:1.13 Wed Jun 8 09:54:16 2011 +++ src/usr.bin/script/script.1 Sun Jan 16 14:04:00 2022 @@ -1,4 +1,4 @@ -.\" $NetBSD: script.1,v 1.13 2011/06/08 13:54:16 yamt Exp $ +.\" $NetBSD: script.1,v 1.14 2022/01/16 19:04:00 christos Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)script.1 8.1 (Berkeley) 6/6/93 .\" -.Dd October 17, 2009 +.Dd January 16, 2022 .Dt SCRIPT 1 .Os .Sh NAME @@ -37,7 +37,7 @@ .Nd make typescript of terminal session .Sh SYNOPSIS .Nm -.Op Fl adfpqr +.Op Fl adefpqr .Op Fl c Ar command .Op Ar file .Sh DESCRIPTION @@ -75,6 +75,10 @@ associated with a tty. When playing back a session with the .Fl p flag, don't sleep between records when playing back a timestamped session. +.It Fl e +Exit with the shell-style exit status of the shell or +.Ar command , +instead of always exiting successfully. .It Fl f Flush output after each write. This is useful for watching the script output in real time. Index: src/usr.bin/script/script.c diff -u src/usr.bin/script/script.c:1.28 src/usr.bin/script/script.c:1.29 --- src/usr.bin/script/script.c:1.28 Mon Aug 31 11:32:15 2020 +++ src/usr.bin/script/script.c Sun Jan 16 14:04:00 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: script.c,v 1.28 2020/08/31 15:32:15 christos Exp $ */ +/* $NetBSD: script.c,v 1.29 2022/01/16 19:04:00 christos Exp $ */ /* * Copyright (c) 1980, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif -__RCSID("$NetBSD: script.c,v 1.28 2020/08/31 15:32:15 christos Exp $"); +__RCSID("$NetBSD: script.c,v 1.29 2022/01/16 19:04:00 christos Exp $"); #endif /* not lint */ #include @@ -81,10 +81,11 @@ static int usesleep, rawout; static int quiet, flush; static const char *fname; +static int eflag; static int isterm; static struct termios tt; -__dead static void done(void); +__dead static void done(int); __dead static void dooutput(void); __dead static void doshell(const char *); __dead static void fail(void); @@ -92,7 +93,6 @@ static void finish(int); static void scriptflush(int); static void record(FILE *, char *, size_t, int); static void consume(FILE *, off_t, char *, int); -static void childwait(void); __dead static void playback(FILE *); int @@ -113,7 +113,7 @@ main(int argc, char *argv[]) quiet = 0; flush = 0; command = NULL; - while ((ch = getopt(argc, argv, "ac:dfpqr")) != -1) + while ((ch = getopt(argc, argv, "ac:defpqr")) != -1) switch(ch) { case 'a': aflg = 1; @@ -124,6 +124,9 @@ main(int argc, char *argv[]) case 'd': usesleep = 0; break; + case 'e': + eflag = 1; + break; case 'f': flush = 1; break; @@ -139,7 +142,7 @@ main(int argc, char *argv[]) case '?': default: (void)fprintf(stderr, - "Usage: %s [-c ][-adfpqr] [file]\n", + "Usage: %s [-c ][-adefpqr] [file]\n", getprogname()); exit(EXIT_FAILURE); } @@ -205,31 +208,29 @@ main(int argc, char *argv[]) record(fscript, ibuf, cc, 'i'); (void)write(master, ibuf, cc); } - childwait(); - return EXIT_SUCCESS; -} - -static void -childwait(void) -{ - sigset_t set; - - sigemptyset(); - sigsuspend(); + finish(-1); } static void finish(int signo) { - int die, pid, status; + int die, pid, status, cstat; die = 0; - while ((pid = wait3(, WNOHANG, 0)) > 0) - if (pid == child) + while ((pid = wait()) > 0) + if (pid == child) { + cstat = status; die = 1; + } - if (die) - done(); + if (!die) + return; + if (!eflag) + done(EXIT_SUCCESS); + else if (WIFEXITED(cstat)) + done(WEXITSTATUS(cstat)); + else + done(128 + WTERMSIG(cstat)); } static void @@ -267,8 +268,7 @@ dooutput(void) if (flush) (void)fflush(fscript); } - childwait(); - exit(EXIT_SUCCESS); + finish(-1); } static void @@ -307,11 +307,11 @@ fail(void) { (void)kill(0, SIGTERM); - done(); + done(EXIT_FAILURE); } static void -done(void) +done(int status) { time_t tvec; @@ -330,7 +330,7 @@ done(void) if (!quiet) (void)printf("Script done, output file is %s\n", fname); } - exit(EXIT_SUCCESS); + exit(status); } static void
CVS commit: src/usr.bin/script
Module Name:src Committed By: christos Date: Sun Jan 16 19:04:00 UTC 2022 Modified Files: src/usr.bin/script: script.1 script.c Log Message: If -e is specified exit with the exit status of the child process in a shell-like format (nabijaczleweli) To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/usr.bin/script/script.1 cvs rdiff -u -r1.28 -r1.29 src/usr.bin/script/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.