From b1c669700c0f52b1c3c886958fe6d75b8ac389f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 19 Sep 1998 09:45:42 +0000 Subject: [PATCH] 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. --- usr.bin/script/script.c | 46 ++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c index 5e8d8e7e84de..9f83627f99df 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 @@ -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); }