diff options
author | des <des@FreeBSD.org> | 1998-09-19 09:45:42 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 1998-09-19 09:45:42 +0000 |
commit | 69cb5ab66dbe63a626c7934cc37d7ed016b9475e (patch) | |
tree | c5c7bd3189e367768a7ff5f33d3403e5ba94a695 /usr.bin/script | |
parent | c8dca54f6ba03d51d5450c3da6c4b99a12bba833 (diff) | |
download | FreeBSD-src-69cb5ab66dbe63a626c7934cc37d7ed016b9475e.zip FreeBSD-src-69cb5ab66dbe63a626c7934cc37d7ed016b9475e.tar.gz |
Fix the following bugs:
- if a command was specified and script(1) failed to execute it,
it would print the name of your shell in the error message
instead of that of the command that failed.
- since finish() was installed as a SIGCHLD handler, it would
often run before the main loop had had time to process the
last few bytes of output. This resulted in very strange
truncated error messages.
- script(1) would almost always return with an exit status of 0,
even if the command returned a non-zero exit status. This broke
my 'build world, install it and rebuild the kernel' scripts
because 'make installworld' would run even if 'make buildworld'
had failed.
Diffstat (limited to 'usr.bin/script')
-rw-r--r-- | usr.bin/script/script.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c index 5e8d8e7..9f83627 100644 --- a/usr.bin/script/script.c +++ b/usr.bin/script/script.c @@ -42,7 +42,7 @@ static const char copyright[] = static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$Id: script.c,v 1.7 1997/12/30 01:20:08 peter Exp $"; + "$Id: script.c,v 1.8 1998/03/08 14:19:18 peter Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -71,11 +71,11 @@ int qflg; struct termios tt; -void done __P((void)) __dead2; +void done __P((int)) __dead2; void dooutput __P((void)); void doshell __P((char **)); void fail __P((void)); -void finish __P((int)); +void finish __P((void)); static void usage __P((void)); int @@ -145,11 +145,10 @@ main(argc, argv) rtt.c_lflag &= ~ECHO; (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt); - (void)signal(SIGCHLD, finish); child = fork(); if (child < 0) { warn("fork"); - fail(); + done(1); } if (child == 0) doshell(argv); @@ -196,7 +195,8 @@ main(argc, argv) start = tvec; } } - done(); + finish(); + done(0); } static void @@ -208,19 +208,25 @@ usage() } void -finish(signo) - int signo; +finish() { - register int die, pid; + int die, e, pid; union wait status; - die = 0; + die = e = 0; while ((pid = wait3((int *)&status, WNOHANG, 0)) > 0) - if (pid == child) + if (pid == child) { die = 1; + if (WIFEXITED(status)) + e = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + e = WTERMSIG(status); + else /* can't happen */ + e = 1; + } if (die) - done(); + done(e); } void @@ -236,24 +242,26 @@ doshell(av) (void)close(master); (void)fclose(fscript); login_tty(slave); - if (av[0]) + if (av[0]) { execvp(av[0], av); - else + warn(av[0]); + } else { execl(shell, "sh", "-i", NULL); - warn(shell); + warn(shell); + } fail(); } void fail() { - (void)kill(0, SIGTERM); - done(); + done(1); } void -done() +done(eno) + int eno; { time_t tvec; @@ -265,5 +273,5 @@ done() } (void)fclose(fscript); (void)close(master); - exit(0); + exit(eno); } |