nohup.c revision 98971
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1989, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3527785Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1989, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4127785Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)nohup.c 8.1 (Berkeley) 6/6/93"; 4327785Scharnier#endif 4427785Scharnierstatic const char rcsid[] = 4550477Speter "$FreeBSD: head/usr.bin/nohup/nohup.c 98971 2002-06-28 09:34:46Z tjr $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 481590Srgrimes#include <sys/param.h> 491590Srgrimes#include <sys/stat.h> 501590Srgrimes 5127785Scharnier#include <err.h> 521590Srgrimes#include <errno.h> 531590Srgrimes#include <fcntl.h> 541590Srgrimes#include <signal.h> 551590Srgrimes#include <stdio.h> 561590Srgrimes#include <stdlib.h> 571590Srgrimes#include <string.h> 581590Srgrimes#include <unistd.h> 591590Srgrimes 6092921Simpstatic void dofile(void); 6192921Simpstatic void usage(void); 621590Srgrimes 6380007Smike#define FILENAME "nohup.out" 6480007Smike/* 6580007Smike * POSIX mandates that we exit with: 6680007Smike * 126 - If the utility was found, but failed to execute. 6780007Smike * 127 - If any other error occurred. 6880007Smike */ 6980007Smike#define EXIT_NOEXEC 126 7080007Smike#define EXIT_NOTFOUND 127 7180007Smike#define EXIT_MISC 127 7280007Smike 731590Srgrimesint 741590Srgrimesmain(argc, argv) 751590Srgrimes int argc; 761590Srgrimes char *argv[]; 771590Srgrimes{ 7880007Smike int exit_status; 7980007Smike 8080007Smike while (getopt(argc, argv, "") != -1) 811590Srgrimes usage(); 8280007Smike argc -= optind; 8380007Smike argv += optind; 8480007Smike if (argc < 1) 8580007Smike usage(); 861590Srgrimes 871590Srgrimes if (isatty(STDOUT_FILENO)) 881590Srgrimes dofile(); 8980007Smike if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 901590Srgrimes /* may have just closed stderr */ 9180007Smike err(EXIT_MISC, "%s", argv[0]); 921590Srgrimes 931590Srgrimes (void)signal(SIGHUP, SIG_IGN); 941590Srgrimes 9580007Smike execvp(*argv, argv); 9680007Smike exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC; 9780007Smike err(exit_status, "%s", argv[0]); 981590Srgrimes} 991590Srgrimes 10080007Smikestatic void 1011590Srgrimesdofile() 1021590Srgrimes{ 1031590Srgrimes int fd; 10480007Smike char path[MAXPATHLEN]; 10580007Smike const char *p; 1061590Srgrimes 10780007Smike /* 10880007Smike * POSIX mandates if the standard output is a terminal, the standard 10980007Smike * output is appended to nohup.out in the working directory. Failing 11080007Smike * that, it will be appended to nohup.out in the directory obtained 11180007Smike * from the HOME environment variable. If file creation is required, 11280007Smike * the mode_t is set to S_IRUSR | S_IWUSR. 11380007Smike */ 1141590Srgrimes p = FILENAME; 11580007Smike fd = open(p, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); 11680007Smike if (fd != -1) 1171590Srgrimes goto dupit; 11880007Smike if ((p = getenv("HOME")) != NULL && *p != '\0' && 11980007Smike (size_t)snprintf(path, sizeof(path), "%s/%s", p, FILENAME) < 12080007Smike sizeof(path)) { 12180007Smike fd = open(p = path, O_RDWR | O_CREAT | O_APPEND, 12280007Smike S_IRUSR | S_IWUSR); 12380007Smike if (fd != -1) 1241590Srgrimes goto dupit; 1251590Srgrimes } 12680007Smike errx(EXIT_MISC, "can't open a nohup.out file"); 1271590Srgrimes 12880007Smikedupit: 12927785Scharnier if (dup2(fd, STDOUT_FILENO) == -1) 13080007Smike err(EXIT_MISC, NULL); 13180007Smike (void)fprintf(stderr, "appending output to %s\n", p); 1321590Srgrimes} 1331590Srgrimes 13480007Smikestatic void 1351590Srgrimesusage() 1361590Srgrimes{ 13798971Stjr (void)fprintf(stderr, "usage: nohup [--] utility [arguments]\n"); 13880007Smike exit(EXIT_MISC); 1391590Srgrimes} 140