11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1990, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311573Srgrimesstatic char sccsid[] = "@(#)daemon.c	8.1 (Berkeley) 6/4/93";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3390039Sobrien#include <sys/cdefs.h>
3490039Sobrien__FBSDID("$FreeBSD: releng/11.0/lib/libc/gen/daemon.c 287292 2015-08-29 14:25:01Z kib $");
351573Srgrimes
3671579Sdeischen#include "namespace.h"
37122442Sghelmer#include <errno.h>
381573Srgrimes#include <fcntl.h>
391573Srgrimes#include <paths.h>
40150065Sstefanf#include <stdlib.h>
41122442Sghelmer#include <signal.h>
421573Srgrimes#include <unistd.h>
4371579Sdeischen#include "un-namespace.h"
44287292Skib#include "libc_private.h"
451573Srgrimes
461573Srgrimesint
47287292Skibdaemon(int nochdir, int noclose)
481573Srgrimes{
49122442Sghelmer	struct sigaction osa, sa;
501573Srgrimes	int fd;
51122442Sghelmer	pid_t newgrp;
52122442Sghelmer	int oerrno;
53122442Sghelmer	int osa_ok;
541573Srgrimes
55122442Sghelmer	/* A SIGHUP may be thrown when the parent exits below. */
56122442Sghelmer	sigemptyset(&sa.sa_mask);
57122442Sghelmer	sa.sa_handler = SIG_IGN;
58122442Sghelmer	sa.sa_flags = 0;
59287292Skib	osa_ok = __libc_sigaction(SIGHUP, &sa, &osa);
60122442Sghelmer
611573Srgrimes	switch (fork()) {
621573Srgrimes	case -1:
631573Srgrimes		return (-1);
641573Srgrimes	case 0:
651573Srgrimes		break;
661573Srgrimes	default:
67205165Sphk		/*
68205165Sphk		 * A fine point:  _exit(0), not exit(0), to avoid triggering
69205165Sphk		 * atexit(3) processing
70205165Sphk		 */
711573Srgrimes		_exit(0);
721573Srgrimes	}
731573Srgrimes
74122442Sghelmer	newgrp = setsid();
75122442Sghelmer	oerrno = errno;
76122442Sghelmer	if (osa_ok != -1)
77287292Skib		__libc_sigaction(SIGHUP, &osa, NULL);
78122442Sghelmer
79122442Sghelmer	if (newgrp == -1) {
80122442Sghelmer		errno = oerrno;
811573Srgrimes		return (-1);
82122442Sghelmer	}
831573Srgrimes
841573Srgrimes	if (!nochdir)
851573Srgrimes		(void)chdir("/");
861573Srgrimes
8756698Sjasone	if (!noclose && (fd = _open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
8871579Sdeischen		(void)_dup2(fd, STDIN_FILENO);
8971579Sdeischen		(void)_dup2(fd, STDOUT_FILENO);
9071579Sdeischen		(void)_dup2(fd, STDERR_FILENO);
911573Srgrimes		if (fd > 2)
9256698Sjasone			(void)_close(fd);
931573Srgrimes	}
941573Srgrimes	return (0);
951573Srgrimes}
96