xref: /minix3/usr.bin/nohup/nohup.c (revision 982405fef1e6f3228ff3835967a3552b79ed941b)
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