18a16b7a1SPedro F. Giffuni /*- 28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 38a16b7a1SPedro F. Giffuni * 49b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 59b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 69b50d902SRodney W. Grimes * 79b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 89b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 99b50d902SRodney W. Grimes * are met: 109b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 129b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 139b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 149b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 169b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 179b50d902SRodney W. Grimes * without specific prior written permission. 189b50d902SRodney W. Grimes * 199b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 209b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 219b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 229b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 239b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 249b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 259b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 269b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 279b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 289b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 299b50d902SRodney W. Grimes * SUCH DAMAGE. 309b50d902SRodney W. Grimes */ 319b50d902SRodney W. Grimes 32ebe901b4SDavid E. O'Brien #if 0 339b50d902SRodney W. Grimes #ifndef lint 347eb43673SPhilippe Charnier static const char copyright[] = 359b50d902SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 369b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 379b50d902SRodney W. Grimes #endif /* not lint */ 389b50d902SRodney W. Grimes 399b50d902SRodney W. Grimes #ifndef lint 409b50d902SRodney W. Grimes static char sccsid[] = "@(#)nohup.c 8.1 (Berkeley) 6/6/93"; 419b50d902SRodney W. Grimes #endif /* not lint */ 42ebe901b4SDavid E. O'Brien #endif 43ebe901b4SDavid E. O'Brien #include <sys/cdefs.h> 44ebe901b4SDavid E. O'Brien __FBSDID("$FreeBSD$"); 459b50d902SRodney W. Grimes 469b50d902SRodney W. Grimes #include <sys/param.h> 479b50d902SRodney W. Grimes #include <sys/stat.h> 489b50d902SRodney W. Grimes 497eb43673SPhilippe Charnier #include <err.h> 509b50d902SRodney W. Grimes #include <errno.h> 519b50d902SRodney W. Grimes #include <fcntl.h> 529b50d902SRodney W. Grimes #include <signal.h> 539b50d902SRodney W. Grimes #include <stdio.h> 549b50d902SRodney W. Grimes #include <stdlib.h> 55821df508SXin LI #include <string.h> 569b50d902SRodney W. Grimes #include <unistd.h> 579b50d902SRodney W. Grimes 58d3cb5dedSWarner Losh static void dofile(void); 59*1a7ac2bdSAlfonso Gregory static void usage(void) __dead2; 609b50d902SRodney W. Grimes 61e896ec1eSMike Barcroft #define FILENAME "nohup.out" 62e896ec1eSMike Barcroft /* 63e896ec1eSMike Barcroft * POSIX mandates that we exit with: 64e896ec1eSMike Barcroft * 126 - If the utility was found, but failed to execute. 65e896ec1eSMike Barcroft * 127 - If any other error occurred. 66e896ec1eSMike Barcroft */ 67e896ec1eSMike Barcroft #define EXIT_NOEXEC 126 68e896ec1eSMike Barcroft #define EXIT_NOTFOUND 127 69e896ec1eSMike Barcroft #define EXIT_MISC 127 70e896ec1eSMike Barcroft 719b50d902SRodney W. Grimes int 72da8de1e2SAlfred Perlstein main(int argc, char *argv[]) 739b50d902SRodney W. Grimes { 74e896ec1eSMike Barcroft int exit_status; 75e896ec1eSMike Barcroft 76e896ec1eSMike Barcroft while (getopt(argc, argv, "") != -1) 77e896ec1eSMike Barcroft usage(); 78e896ec1eSMike Barcroft argc -= optind; 79e896ec1eSMike Barcroft argv += optind; 80e896ec1eSMike Barcroft if (argc < 1) 819b50d902SRodney W. Grimes usage(); 829b50d902SRodney W. Grimes 839b50d902SRodney W. Grimes if (isatty(STDOUT_FILENO)) 849b50d902SRodney W. Grimes dofile(); 85e896ec1eSMike Barcroft if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 869b50d902SRodney W. Grimes /* may have just closed stderr */ 87e896ec1eSMike Barcroft err(EXIT_MISC, "%s", argv[0]); 889b50d902SRodney W. Grimes 899b50d902SRodney W. Grimes (void)signal(SIGHUP, SIG_IGN); 909b50d902SRodney W. Grimes 91e896ec1eSMike Barcroft execvp(*argv, argv); 92e896ec1eSMike Barcroft exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC; 93e896ec1eSMike Barcroft err(exit_status, "%s", argv[0]); 949b50d902SRodney W. Grimes } 959b50d902SRodney W. Grimes 96e896ec1eSMike Barcroft static void 97da8de1e2SAlfred Perlstein dofile(void) 989b50d902SRodney W. Grimes { 999b50d902SRodney W. Grimes int fd; 100e896ec1eSMike Barcroft char path[MAXPATHLEN]; 101e896ec1eSMike Barcroft const char *p; 1029b50d902SRodney W. Grimes 103e896ec1eSMike Barcroft /* 104e896ec1eSMike Barcroft * POSIX mandates if the standard output is a terminal, the standard 105e896ec1eSMike Barcroft * output is appended to nohup.out in the working directory. Failing 106e896ec1eSMike Barcroft * that, it will be appended to nohup.out in the directory obtained 107e896ec1eSMike Barcroft * from the HOME environment variable. If file creation is required, 108e896ec1eSMike Barcroft * the mode_t is set to S_IRUSR | S_IWUSR. 109e896ec1eSMike Barcroft */ 1109b50d902SRodney W. Grimes p = FILENAME; 111e896ec1eSMike Barcroft fd = open(p, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); 112e896ec1eSMike Barcroft if (fd != -1) 1139b50d902SRodney W. Grimes goto dupit; 114e896ec1eSMike Barcroft if ((p = getenv("HOME")) != NULL && *p != '\0' && 115e896ec1eSMike Barcroft (size_t)snprintf(path, sizeof(path), "%s/%s", p, FILENAME) < 116e896ec1eSMike Barcroft sizeof(path)) { 117e896ec1eSMike Barcroft fd = open(p = path, O_RDWR | O_CREAT | O_APPEND, 118e896ec1eSMike Barcroft S_IRUSR | S_IWUSR); 119e896ec1eSMike Barcroft if (fd != -1) 1209b50d902SRodney W. Grimes goto dupit; 1219b50d902SRodney W. Grimes } 122e896ec1eSMike Barcroft errx(EXIT_MISC, "can't open a nohup.out file"); 1239b50d902SRodney W. Grimes 124e896ec1eSMike Barcroft dupit: 1257eb43673SPhilippe Charnier if (dup2(fd, STDOUT_FILENO) == -1) 126e896ec1eSMike Barcroft err(EXIT_MISC, NULL); 127e896ec1eSMike Barcroft (void)fprintf(stderr, "appending output to %s\n", p); 1289b50d902SRodney W. Grimes } 1299b50d902SRodney W. Grimes 130e896ec1eSMike Barcroft static void 131da8de1e2SAlfred Perlstein usage(void) 1329b50d902SRodney W. Grimes { 1334633a1abSTim J. Robbins (void)fprintf(stderr, "usage: nohup [--] utility [arguments]\n"); 134e896ec1eSMike Barcroft exit(EXIT_MISC); 1359b50d902SRodney W. Grimes } 136