1*982405feSThomas Cort /* $NetBSD: nohup.c,v 1.15 2011/09/06 18:24:15 joerg Exp $ */
2*982405feSThomas Cort
3*982405feSThomas Cort /*
4*982405feSThomas Cort * Copyright (c) 1989 The Regents of the University of California.
5*982405feSThomas Cort * All rights reserved.
6*982405feSThomas Cort *
7*982405feSThomas Cort * Redistribution and use in source and binary forms, with or without
8*982405feSThomas Cort * modification, are permitted provided that the following conditions
9*982405feSThomas Cort * are met:
10*982405feSThomas Cort * 1. Redistributions of source code must retain the above copyright
11*982405feSThomas Cort * notice, this list of conditions and the following disclaimer.
12*982405feSThomas Cort * 2. Redistributions in binary form must reproduce the above copyright
13*982405feSThomas Cort * notice, this list of conditions and the following disclaimer in the
14*982405feSThomas Cort * documentation and/or other materials provided with the distribution.
15*982405feSThomas Cort * 3. Neither the name of the University nor the names of its contributors
16*982405feSThomas Cort * may be used to endorse or promote products derived from this software
17*982405feSThomas Cort * without specific prior written permission.
18*982405feSThomas Cort *
19*982405feSThomas Cort * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*982405feSThomas Cort * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*982405feSThomas Cort * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*982405feSThomas Cort * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*982405feSThomas Cort * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*982405feSThomas Cort * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*982405feSThomas Cort * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*982405feSThomas Cort * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*982405feSThomas Cort * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*982405feSThomas Cort * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*982405feSThomas Cort * SUCH DAMAGE.
30*982405feSThomas Cort */
31*982405feSThomas Cort
32*982405feSThomas Cort #include <sys/cdefs.h>
33*982405feSThomas Cort #ifndef lint
34*982405feSThomas Cort __COPYRIGHT("@(#) Copyright (c) 1989\
35*982405feSThomas Cort The Regents of the University of California. All rights reserved.");
36*982405feSThomas Cort #endif /* not lint */
37*982405feSThomas Cort
38*982405feSThomas Cort #ifndef lint
39*982405feSThomas Cort #if 0
40*982405feSThomas Cort static char sccsid[] = "@(#)nohup.c 5.4 (Berkeley) 6/1/90";
41*982405feSThomas Cort #endif
42*982405feSThomas Cort __RCSID("$NetBSD: nohup.c,v 1.15 2011/09/06 18:24:15 joerg Exp $");
43*982405feSThomas Cort #endif /* not lint */
44*982405feSThomas Cort
45*982405feSThomas Cort #include <sys/param.h>
46*982405feSThomas Cort #include <sys/file.h>
47*982405feSThomas Cort #include <sys/stat.h>
48*982405feSThomas Cort #include <fcntl.h>
49*982405feSThomas Cort #include <unistd.h>
50*982405feSThomas Cort #include <signal.h>
51*982405feSThomas Cort #include <stdio.h>
52*982405feSThomas Cort #include <stdlib.h>
53*982405feSThomas Cort #include <string.h>
54*982405feSThomas Cort #include <errno.h>
55*982405feSThomas Cort
56*982405feSThomas Cort static void dofile(void);
57*982405feSThomas Cort __dead static void usage(void);
58*982405feSThomas Cort
59*982405feSThomas Cort /* nohup shall exit with one of the following values:
60*982405feSThomas Cort 126 - The utility was found but could not be invoked.
61*982405feSThomas Cort 127 - An error occurred in the nohup utility, or the utility could
62*982405feSThomas Cort not be found. */
63*982405feSThomas Cort #define EXIT_NOEXEC 126
64*982405feSThomas Cort #define EXIT_NOTFOUND 127
65*982405feSThomas Cort #define EXIT_MISC 127
66*982405feSThomas Cort
67*982405feSThomas Cort int
main(int argc,char ** argv)68*982405feSThomas Cort main(int argc, char **argv)
69*982405feSThomas Cort {
70*982405feSThomas Cort int exit_status;
71*982405feSThomas Cort
72*982405feSThomas Cort while (getopt(argc, argv, "") != -1) {
73*982405feSThomas Cort usage();
74*982405feSThomas Cort }
75*982405feSThomas Cort argc -= optind;
76*982405feSThomas Cort argv += optind;
77*982405feSThomas Cort
78*982405feSThomas Cort if (argc < 1)
79*982405feSThomas Cort usage();
80*982405feSThomas Cort
81*982405feSThomas Cort if (isatty(STDOUT_FILENO))
82*982405feSThomas Cort dofile();
83*982405feSThomas Cort if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
84*982405feSThomas Cort /* may have just closed stderr */
85*982405feSThomas Cort (void)fprintf(stdin, "nohup: %s\n", strerror(errno));
86*982405feSThomas Cort exit(EXIT_MISC);
87*982405feSThomas Cort }
88*982405feSThomas Cort
89*982405feSThomas Cort /* The nohup utility shall take the standard action for all signals
90*982405feSThomas Cort except that SIGHUP shall be ignored. */
91*982405feSThomas Cort (void)signal(SIGHUP, SIG_IGN);
92*982405feSThomas Cort
93*982405feSThomas Cort execvp(argv[0], &argv[0]);
94*982405feSThomas Cort exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC;
95*982405feSThomas Cort (void)fprintf(stderr, "nohup: %s: %s\n", argv[0], strerror(errno));
96*982405feSThomas Cort exit(exit_status);
97*982405feSThomas Cort }
98*982405feSThomas Cort
99*982405feSThomas Cort static void
dofile(void)100*982405feSThomas Cort dofile(void)
101*982405feSThomas Cort {
102*982405feSThomas Cort int fd;
103*982405feSThomas Cort char path[MAXPATHLEN];
104*982405feSThomas Cort const char *p;
105*982405feSThomas Cort
106*982405feSThomas Cort /* If the standard output is a terminal, all output written to
107*982405feSThomas Cort its standard output shall be appended to the end of the file
108*982405feSThomas Cort nohup.out in the current directory. If nohup.out cannot be
109*982405feSThomas Cort created or opened for appending, the output shall be appended
110*982405feSThomas Cort to the end of the file nohup.out in the directory specified
111*982405feSThomas Cort by the HOME environment variable.
112*982405feSThomas Cort
113*982405feSThomas Cort If a file is created, the file's permission bits shall be
114*982405feSThomas Cort set to S_IRUSR | S_IWUSR. */
115*982405feSThomas Cort #define FILENAME "nohup.out"
116*982405feSThomas Cort p = FILENAME;
117*982405feSThomas Cort if ((fd = open(p, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
118*982405feSThomas Cort goto dupit;
119*982405feSThomas Cort if ((p = getenv("HOME")) != NULL) {
120*982405feSThomas Cort (void)strlcpy(path, p, sizeof(path));
121*982405feSThomas Cort (void)strlcat(path, "/", sizeof(path));
122*982405feSThomas Cort (void)strlcat(path, FILENAME, sizeof(path));
123*982405feSThomas Cort if ((fd = open(p = path, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
124*982405feSThomas Cort goto dupit;
125*982405feSThomas Cort }
126*982405feSThomas Cort (void)fprintf(stderr, "nohup: can't open a nohup.out file.\n");
127*982405feSThomas Cort exit(EXIT_MISC);
128*982405feSThomas Cort
129*982405feSThomas Cort dupit: (void)lseek(fd, 0L, SEEK_END);
130*982405feSThomas Cort if (dup2(fd, STDOUT_FILENO) == -1) {
131*982405feSThomas Cort (void)fprintf(stderr, "nohup: %s\n", strerror(errno));
132*982405feSThomas Cort exit(EXIT_MISC);
133*982405feSThomas Cort }
134*982405feSThomas Cort (void)fprintf(stderr, "sending output to %s\n", p);
135*982405feSThomas Cort }
136*982405feSThomas Cort
137*982405feSThomas Cort static void
usage(void)138*982405feSThomas Cort usage(void)
139*982405feSThomas Cort {
140*982405feSThomas Cort (void)fprintf(stderr, "usage: nohup utility [argument ...]\n");
141*982405feSThomas Cort exit(EXIT_MISC);
142*982405feSThomas Cort }
143