1*0487dc01Sjoerg /* $NetBSD: nohup.c,v 1.15 2011/09/06 18:24:15 joerg Exp $ */
208f61475Sjtc
361f28255Scgd /*
461f28255Scgd * Copyright (c) 1989 The Regents of the University of California.
561f28255Scgd * All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
1589aaa1bbSagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
3222930ad0Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3498e5374cSlukem __COPYRIGHT("@(#) Copyright (c) 1989\
3598e5374cSlukem The Regents of the University of California. All rights reserved.");
3661f28255Scgd #endif /* not lint */
3761f28255Scgd
3861f28255Scgd #ifndef lint
3908f61475Sjtc #if 0
4008f61475Sjtc static char sccsid[] = "@(#)nohup.c 5.4 (Berkeley) 6/1/90";
4108f61475Sjtc #endif
42*0487dc01Sjoerg __RCSID("$NetBSD: nohup.c,v 1.15 2011/09/06 18:24:15 joerg Exp $");
4361f28255Scgd #endif /* not lint */
4461f28255Scgd
4561f28255Scgd #include <sys/param.h>
4661f28255Scgd #include <sys/file.h>
47aab7593aSjtc #include <sys/stat.h>
48aab7593aSjtc #include <fcntl.h>
4961f28255Scgd #include <unistd.h>
50d0a0f13bSjtc #include <signal.h>
5161f28255Scgd #include <stdio.h>
52aab7593aSjtc #include <stdlib.h>
53aab7593aSjtc #include <string.h>
54aab7593aSjtc #include <errno.h>
5561f28255Scgd
56*0487dc01Sjoerg static void dofile(void);
57*0487dc01Sjoerg __dead static void usage(void);
5861f28255Scgd
59aab7593aSjtc /* nohup shall exit with one of the following values:
60aab7593aSjtc 126 - The utility was found but could not be invoked.
61456dff6cSwiz 127 - An error occurred in the nohup utility, or the utility could
62aab7593aSjtc not be found. */
63aab7593aSjtc #define EXIT_NOEXEC 126
64aab7593aSjtc #define EXIT_NOTFOUND 127
65aab7593aSjtc #define EXIT_MISC 127
66aab7593aSjtc
67aab7593aSjtc int
main(int argc,char ** argv)68*0487dc01Sjoerg main(int argc, char **argv)
6961f28255Scgd {
70aab7593aSjtc int exit_status;
7161f28255Scgd
72262a0893Skleink while (getopt(argc, argv, "") != -1) {
73262a0893Skleink usage();
74262a0893Skleink }
75262a0893Skleink argc -= optind;
76262a0893Skleink argv += optind;
77262a0893Skleink
78262a0893Skleink if (argc < 1)
7961f28255Scgd usage();
8061f28255Scgd
8161f28255Scgd if (isatty(STDOUT_FILENO))
8261f28255Scgd dofile();
8361f28255Scgd if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
8461f28255Scgd /* may have just closed stderr */
8561f28255Scgd (void)fprintf(stdin, "nohup: %s\n", strerror(errno));
86aab7593aSjtc exit(EXIT_MISC);
8761f28255Scgd }
8861f28255Scgd
89aab7593aSjtc /* The nohup utility shall take the standard action for all signals
90aab7593aSjtc except that SIGHUP shall be ignored. */
9161f28255Scgd (void)signal(SIGHUP, SIG_IGN);
9261f28255Scgd
93262a0893Skleink execvp(argv[0], &argv[0]);
944b2ac6c0Sross exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC;
95262a0893Skleink (void)fprintf(stderr, "nohup: %s: %s\n", argv[0], strerror(errno));
96aab7593aSjtc exit(exit_status);
9761f28255Scgd }
9861f28255Scgd
99aab7593aSjtc static void
dofile(void)100*0487dc01Sjoerg dofile(void)
10161f28255Scgd {
10261f28255Scgd int fd;
1031f36782aSlukem char path[MAXPATHLEN];
1041f36782aSlukem const char *p;
10561f28255Scgd
106aab7593aSjtc /* If the standard output is a terminal, all output written to
107aab7593aSjtc its standard output shall be appended to the end of the file
108aab7593aSjtc nohup.out in the current directory. If nohup.out cannot be
109aab7593aSjtc created or opened for appending, the output shall be appended
110aab7593aSjtc to the end of the file nohup.out in the directory specified
111aab7593aSjtc by the HOME environment variable.
112aab7593aSjtc
113aab7593aSjtc If a file is created, the file's permission bits shall be
114aab7593aSjtc set to S_IRUSR | S_IWUSR. */
11561f28255Scgd #define FILENAME "nohup.out"
1167a73bcecSjtc p = FILENAME;
1177a73bcecSjtc if ((fd = open(p, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
11861f28255Scgd goto dupit;
119aab7593aSjtc if ((p = getenv("HOME")) != NULL) {
12051a00352Sitojun (void)strlcpy(path, p, sizeof(path));
12151a00352Sitojun (void)strlcat(path, "/", sizeof(path));
12251a00352Sitojun (void)strlcat(path, FILENAME, sizeof(path));
123aab7593aSjtc if ((fd = open(p = path, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
12461f28255Scgd goto dupit;
12561f28255Scgd }
12661f28255Scgd (void)fprintf(stderr, "nohup: can't open a nohup.out file.\n");
127aab7593aSjtc exit(EXIT_MISC);
12861f28255Scgd
12961f28255Scgd dupit: (void)lseek(fd, 0L, SEEK_END);
13061f28255Scgd if (dup2(fd, STDOUT_FILENO) == -1) {
13161f28255Scgd (void)fprintf(stderr, "nohup: %s\n", strerror(errno));
132aab7593aSjtc exit(EXIT_MISC);
13361f28255Scgd }
13461f28255Scgd (void)fprintf(stderr, "sending output to %s\n", p);
13561f28255Scgd }
13661f28255Scgd
137aab7593aSjtc static void
usage(void)138*0487dc01Sjoerg usage(void)
13961f28255Scgd {
140262a0893Skleink (void)fprintf(stderr, "usage: nohup utility [argument ...]\n");
141aab7593aSjtc exit(EXIT_MISC);
14261f28255Scgd }
143