19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 357eb43673SPhilippe Charnier static const char copyright[] = 369b50d902SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 379b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 389b50d902SRodney W. Grimes #endif /* not lint */ 399b50d902SRodney W. Grimes 409b50d902SRodney W. Grimes #ifndef lint 417eb43673SPhilippe Charnier #if 0 429b50d902SRodney W. Grimes static char sccsid[] = "@(#)nohup.c 8.1 (Berkeley) 6/6/93"; 437eb43673SPhilippe Charnier #endif 447eb43673SPhilippe Charnier static const char rcsid[] = 45c3aac50fSPeter Wemm "$FreeBSD$"; 469b50d902SRodney W. Grimes #endif /* not lint */ 479b50d902SRodney W. Grimes 489b50d902SRodney W. Grimes #include <sys/param.h> 499b50d902SRodney W. Grimes #include <sys/stat.h> 509b50d902SRodney W. Grimes 517eb43673SPhilippe Charnier #include <err.h> 529b50d902SRodney W. Grimes #include <errno.h> 539b50d902SRodney W. Grimes #include <fcntl.h> 549b50d902SRodney W. Grimes #include <signal.h> 559b50d902SRodney W. Grimes #include <stdio.h> 569b50d902SRodney W. Grimes #include <stdlib.h> 579b50d902SRodney W. Grimes #include <string.h> 589b50d902SRodney W. Grimes #include <unistd.h> 599b50d902SRodney W. Grimes 60d3cb5dedSWarner Losh static void dofile(void); 61d3cb5dedSWarner Losh static void usage(void); 629b50d902SRodney W. Grimes 63e896ec1eSMike Barcroft #define FILENAME "nohup.out" 64e896ec1eSMike Barcroft /* 65e896ec1eSMike Barcroft * POSIX mandates that we exit with: 66e896ec1eSMike Barcroft * 126 - If the utility was found, but failed to execute. 67e896ec1eSMike Barcroft * 127 - If any other error occurred. 68e896ec1eSMike Barcroft */ 69e896ec1eSMike Barcroft #define EXIT_NOEXEC 126 70e896ec1eSMike Barcroft #define EXIT_NOTFOUND 127 71e896ec1eSMike Barcroft #define EXIT_MISC 127 72e896ec1eSMike Barcroft 739b50d902SRodney W. Grimes int 749b50d902SRodney W. Grimes main(argc, argv) 759b50d902SRodney W. Grimes int argc; 769b50d902SRodney W. Grimes char *argv[]; 779b50d902SRodney W. Grimes { 78e896ec1eSMike Barcroft int exit_status; 79e896ec1eSMike Barcroft 80e896ec1eSMike Barcroft while (getopt(argc, argv, "") != -1) 81e896ec1eSMike Barcroft usage(); 82e896ec1eSMike Barcroft argc -= optind; 83e896ec1eSMike Barcroft argv += optind; 84e896ec1eSMike Barcroft if (argc < 1) 859b50d902SRodney W. Grimes usage(); 869b50d902SRodney W. Grimes 879b50d902SRodney W. Grimes if (isatty(STDOUT_FILENO)) 889b50d902SRodney W. Grimes dofile(); 89e896ec1eSMike Barcroft if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 909b50d902SRodney W. Grimes /* may have just closed stderr */ 91e896ec1eSMike Barcroft err(EXIT_MISC, "%s", argv[0]); 929b50d902SRodney W. Grimes 939b50d902SRodney W. Grimes (void)signal(SIGHUP, SIG_IGN); 949b50d902SRodney W. Grimes 95e896ec1eSMike Barcroft execvp(*argv, argv); 96e896ec1eSMike Barcroft exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC; 97e896ec1eSMike Barcroft err(exit_status, "%s", argv[0]); 989b50d902SRodney W. Grimes } 999b50d902SRodney W. Grimes 100e896ec1eSMike Barcroft static void 1019b50d902SRodney W. Grimes dofile() 1029b50d902SRodney W. Grimes { 1039b50d902SRodney W. Grimes int fd; 104e896ec1eSMike Barcroft char path[MAXPATHLEN]; 105e896ec1eSMike Barcroft const char *p; 1069b50d902SRodney W. Grimes 107e896ec1eSMike Barcroft /* 108e896ec1eSMike Barcroft * POSIX mandates if the standard output is a terminal, the standard 109e896ec1eSMike Barcroft * output is appended to nohup.out in the working directory. Failing 110e896ec1eSMike Barcroft * that, it will be appended to nohup.out in the directory obtained 111e896ec1eSMike Barcroft * from the HOME environment variable. If file creation is required, 112e896ec1eSMike Barcroft * the mode_t is set to S_IRUSR | S_IWUSR. 113e896ec1eSMike Barcroft */ 1149b50d902SRodney W. Grimes p = FILENAME; 115e896ec1eSMike Barcroft fd = open(p, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); 116e896ec1eSMike Barcroft if (fd != -1) 1179b50d902SRodney W. Grimes goto dupit; 118e896ec1eSMike Barcroft if ((p = getenv("HOME")) != NULL && *p != '\0' && 119e896ec1eSMike Barcroft (size_t)snprintf(path, sizeof(path), "%s/%s", p, FILENAME) < 120e896ec1eSMike Barcroft sizeof(path)) { 121e896ec1eSMike Barcroft fd = open(p = path, O_RDWR | O_CREAT | O_APPEND, 122e896ec1eSMike Barcroft S_IRUSR | S_IWUSR); 123e896ec1eSMike Barcroft if (fd != -1) 1249b50d902SRodney W. Grimes goto dupit; 1259b50d902SRodney W. Grimes } 126e896ec1eSMike Barcroft errx(EXIT_MISC, "can't open a nohup.out file"); 1279b50d902SRodney W. Grimes 128e896ec1eSMike Barcroft dupit: 1297eb43673SPhilippe Charnier if (dup2(fd, STDOUT_FILENO) == -1) 130e896ec1eSMike Barcroft err(EXIT_MISC, NULL); 131e896ec1eSMike Barcroft (void)fprintf(stderr, "appending output to %s\n", p); 1329b50d902SRodney W. Grimes } 1339b50d902SRodney W. Grimes 134e896ec1eSMike Barcroft static void 1359b50d902SRodney W. Grimes usage() 1369b50d902SRodney W. Grimes { 137e896ec1eSMike Barcroft (void)fprintf(stderr, "usage: nohup [--] command [arguments]\n"); 138e896ec1eSMike Barcroft exit(EXIT_MISC); 1399b50d902SRodney W. Grimes } 140