From owner-freebsd-audit Fri Jul 13 7:34:52 2001 Delivered-To: freebsd-audit@freebsd.org Received: from coffee.q9media.com (coffee.q9media.com [216.94.229.19]) by hub.freebsd.org (Postfix) with ESMTP id 3775E37B401 for ; Fri, 13 Jul 2001 07:34:42 -0700 (PDT) (envelope-from mike@coffee.q9media.com) Received: (from mike@localhost) by coffee.q9media.com (8.11.2/8.11.2) id f6DEoXF24866; Fri, 13 Jul 2001 10:50:33 -0400 (EDT) (envelope-from mike) Date: Fri, 13 Jul 2001 10:50:33 -0400 (EDT) Message-Id: <200107131450.f6DEoXF24866@coffee.q9media.com> From: Mike Barcroft To: Bruce Evans Cc: audit@FreeBSD.org Subject: Re: nohup(1) enhancements patch Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Bruce Evans writes: > > I would appreciate comments on the patch at the end of this > > message, also available at: > > http://testbed.q9media.net/freebsd/nohup.20010713.patch > >... > > o Remove some FreeBSD specific access(2) cruft. > > This summarily blows away rev.1.2. Do you mean rev 1.3? If so, yes, access(2) suffers from a race, so you can't guarantee that your appending and not creating a new file. I even thought about doing a series of open(2)s, one without O_CREAT and one with it, but that too is a race because you can't guarentee that the file wasn't created between your first and second open(2). Better to be less discriptive, than lie to the user IMO. [snipped diff] > Non-KNF-formatted comment. > Hand-formatted comment without indent(1) protection. NetBSD and OpenBSD were both using those exact formats, but you are entirely correct. Comments fixed. [snipped diff] > Excessive vertical whitespace. All excessive vertical whitespace removed. > >... > > + execvp(argv[0], &argv[0]); > > + exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC; > > + err(1, "%s", argv[0]); > > + exit(exit_status); > > Last 2 lines should be "err(exit_status, argv[0]);". Good spot. Fixed. [snipped diff] > Non-KNF-formatted comment. > May violate POSIX's copyright. NetBSD and OpenBSD already have these POSIX requirements in their source trees. What's the correct solution? Contact IEEE and see if we can obtain permission, just leave it in, or pull it out? > > - 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' && > > + (strlen(p) + strlen(FILENAME) + 1) < sizeof(path)) { > > + (void)snprintf(path, sizeof(path), "%s/%s", p, FILENAME); > > Why both check that the string fits and use snprintf()? I thought it was a bit easier to read, but it isn't very useful. Reverted back to strcpy/strcat. > > + if ((fd = open(p = path, O_RDWR|O_CREAT|O_APPEND, > > + S_IRUSR|S_IWUSR)) != -1) > > Even more missing spaces arund binary operators than before. Sorry, trying to keep in sync with NetBSD and OpenBSD again. Horizontal space added. New patch at the end of this message, also available at: http://testbed.q9media.net/freebsd/nohup.20010714.patch Best regards, Mike Barcroft ---------------------------------------------------------------------- nohup.20010714.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. o Remove some FreeBSD specific access(2) cruft. 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/13 14:00:51 @@ -1,5 +1,6 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= nohup +WARNS?= 2 .include 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/13 14:00:51 @@ -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 , 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/13 14:00:51 @@ -57,67 +57,92 @@ #include #include -void dofile __P((void)); +static void dofile __P((void)); static void usage __P((void)); +#define FILENAME "nohup.out" +/* + * nohup shall exit with one of the following values: + * 126 - The utility was found, but could not be invoked. + * 127 - An error occurred in the nohup utility, or the utility could + * not be found. + */ +#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]); + /* The nohup utility shall take the standard action for all signals + except that SIGHUP shall be ignored. */ (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" + /* If the standard output is a terminal, all output written to + * its standard output shall be appended to the end of the file + * nohup.out in the current directory. If nohup.out cannot be + * created or opened for appending, the output shall be appended + * to the end of the file nohup.out in the directory specified + * by the HOME environment variable. + * + * If a file is created, the file's permission bits shall be + * 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"))) { + if ((p = getenv("HOME")) != NULL && *p != '\0' && + (strlen(p) + strlen(FILENAME) + 1) < sizeof(path)) { (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) + 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, "sending 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