Date: Sun, 15 Jul 2001 12:59:35 -0400 (EDT) From: Mike Barcroft <mike@q9media.com> To: Bruce Evans <bde@zeta.org.au> Cc: audit@FreeBSD.org Subject: Re: nohup(1) enhancements patch Message-ID: <200107151659.f6FGxZe30439@coffee.q9media.com>
next in thread | raw e-mail | index | archive | help
Bruce, This patch resolves all the remaining issues with my previous patches. Would you mind committing this for me? New patch at the end of this message. Also at: http://testbed.q9media.net/freebsd/nohup.20010715.patch Best regards, Mike Barcroft ---------------------------------------------------------------------- nohup.20010715.patch o Integrate security enhancements from OpenBSD. - Don't assume environment variable HOME is not NULL. o Integrate standards compliance from NetBSD. - Allow -- before the command. - Blocking SIGQUIT isn't standards compliant. - Proper exit(3) levels. - Actually append to nohup.out (as documented and required by standard) instead of clobbering it. o Remove some FreeBSD specific access(2) cruft (relating to incorrect appending). o Document the fact that two or more instances of nohup can append to the same file. o Constify; Staticize functions; Set WARNS?=2 o Tested on i386, and alpha. Index: nohup/Makefile =================================================================== RCS file: /home/ncvs/src/usr.bin/nohup/Makefile,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 Makefile --- nohup/Makefile 1994/05/27 12:32:27 1.1.1.1 +++ nohup/Makefile 2001/07/15 16:24:04 @@ -1,5 +1,6 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= nohup +WARNS?= 2 .include <bsd.prog.mk> Index: nohup/nohup.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/nohup/nohup.1,v retrieving revision 1.8 diff -u -r1.8 nohup.1 --- nohup/nohup.1 2000/11/20 19:21:00 1.8 +++ nohup/nohup.1 2001/07/15 16:24:04 @@ -43,6 +43,7 @@ .Nd invoke a command immune to hangups .Sh SYNOPSIS .Nm +.Op Ar -- .Ar command .Op Ar arguments .Sh DESCRIPTION @@ -50,16 +51,11 @@ .Nm utility invokes .Ar command -with -its +with its .Ar arguments and at this time sets the signal .Dv SIGHUP to be ignored. -The signal -.Dv SIGQUIT -may also be set -to be ignored. If the standard output is a terminal, the standard output is appended to the file .Pa nohup.out @@ -67,10 +63,6 @@ If standard error is a terminal, it is directed to the same place as the standard output. .Pp -.Nm Nohup -exits 1 if an error occurs, otherwise the exit status is that of -.Ar command . -.Pp Some shells may provide a builtin .Nm command which is similar or identical to this utility. @@ -90,6 +82,26 @@ .Ev HOME to create the file. .El +.Sh DIAGNOSTICS +The +.Nm +utility exits with one of the following values: +.Bl -tag -width Ds +.It 126 +The +.Ar command +was found, but could not be invoked. +.It 127 +The +.Ar command +could not be found or an error occurred in +.Nm . +.El +.Pp +Otherwise, the exit status of +.Nm +will be that of +.Ar command . .Sh SEE ALSO .Xr builtin 1 , .Xr csh 1 , @@ -100,3 +112,7 @@ utility is expected to be .St -p1003.2 compatible. +.Sh BUGS +Two or more instances of +.Nm +can append to the same file, which makes for a confusing output. Index: nohup/nohup.c =================================================================== RCS file: /home/ncvs/src/usr.bin/nohup/nohup.c,v retrieving revision 1.5 diff -u -r1.5 nohup.c --- nohup/nohup.c 2000/03/26 14:46:41 1.5 +++ nohup/nohup.c 2001/07/15 16:24:04 @@ -57,67 +57,84 @@ #include <string.h> #include <unistd.h> -void dofile __P((void)); +static void dofile __P((void)); static void usage __P((void)); +#define FILENAME "nohup.out" +/* + * POSIX mandates that we exit with: + * 126 - If the utility was found, but failed to execute. + * 127 - If any other error occurred. + */ +#define EXIT_NOEXEC 126 +#define EXIT_NOTFOUND 127 +#define EXIT_MISC 127 + int main(argc, argv) int argc; char *argv[]; { - if (argc < 2) + int exit_status; + + while (getopt(argc, argv, "") != -1) usage(); + argc -= optind; + argv += optind; + if (argc < 1) + usage(); if (isatty(STDOUT_FILENO)) dofile(); - if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) { + if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) /* may have just closed stderr */ - (void)fprintf(stdin, "nohup: %s\n", strerror(errno)); - exit(1); - } + err(EXIT_MISC, "%s", argv[0]); (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - execvp(argv[1], &argv[1]); - err(1, "%s", argv[1]); + execvp(argv[0], &argv[0]); + exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC; + err(exit_status, "%s", argv[0]); } -void +static void dofile() { - int append; int fd; - char *p, path[MAXPATHLEN]; + char path[MAXPATHLEN]; + const char *p; -#define FILENAME "nohup.out" + /* + * POSIX mandates if the standard output is a terminal, the standard + * output is appended to nohup.out in the working directory. Failing + * that, it will be appended to nohup.out in the directory obtained + * from the HOME environment variable. If file creation is required, + * the mode_t is set to S_IRUSR | S_IWUSR. + */ p = FILENAME; - append = !access(p, F_OK); - if ((fd = open(p, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) + fd = open(p, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); + if (fd != -1) goto dupit; - if ((p = getenv("HOME"))) { - (void)strcpy(path, p); - (void)strcat(path, "/"); - (void)strcat(path, FILENAME); - append = !access(path, F_OK); - if ((fd = open(p = path, - O_RDWR|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) + if ((p = getenv("HOME")) != NULL && *p != '\0' && + (size_t)snprintf(path, sizeof(path), "%s/%s", p, FILENAME) < + sizeof(path)) { + fd = open(p = path, O_RDWR | O_CREAT | O_APPEND, + S_IRUSR | S_IWUSR); + if (fd != -1) goto dupit; } - errx(1, "can't open a nohup.out file"); + errx(EXIT_MISC, "can't open a nohup.out file"); -dupit: (void)lseek(fd, (off_t)0, SEEK_END); +dupit: + (void)lseek(fd, (off_t)0, SEEK_END); if (dup2(fd, STDOUT_FILENO) == -1) - err(1, NULL); - if (append) - (void)fprintf(stderr, "appending output to existing %s\n", p); - else - (void)fprintf(stderr, "sending output to %s\n", p); + err(EXIT_MISC, NULL); + (void)fprintf(stderr, "appending output to %s\n", p); } -void +static void usage() { - (void)fprintf(stderr, "usage: nohup command [arguments]\n"); - exit(1); + (void)fprintf(stderr, "usage: nohup [--] command [arguments]\n"); + exit(EXIT_MISC); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107151659.f6FGxZe30439>