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

Reviewed by:	bde
Approved by:	des
Obtained from:	NetBSD, OpenBSD
MFC after:	9 days
This commit is contained in:
Mike Barcroft 2001-07-19 21:25:10 +00:00
parent e16873dad6
commit e896ec1ef5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=80007
2 changed files with 74 additions and 42 deletions

View File

@ -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 @@ The
.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 @@ in the current directory.
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 @@ utility uses the directory named by
.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 @@ The
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.

View File

@ -57,67 +57,83 @@ static const char rcsid[] =
#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, argv);
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:
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);
}