xref: /haiku/src/libs/bsd/daemon.c (revision 1b8f7f13a3dc70e0e903cb94248220b40b732204)
1 /*
2  * Copyright 2007, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  */
8 
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <signal.h>
12 #include <unistd.h>
13 
14 
15 static void
16 restore_old_sighup(int result, struct sigaction *action)
17 {
18 	if (result != -1)
19 		sigaction(SIGHUP, action, NULL);
20 }
21 
22 
23 int
24 daemon(int noChangeDir, int noClose)
25 {
26 	struct sigaction oldAction, action;
27 	int oldActionResult;
28 	pid_t newGroup;
29 	pid_t pid;
30 
31 	/* Ignore eventually send SIGHUPS on parent exit */
32 	sigemptyset(&action.sa_mask);
33 	action.sa_handler = SIG_IGN;
34 	action.sa_flags = 0;
35 	oldActionResult = sigaction(SIGHUP, &action, &oldAction);
36 
37 	pid = fork();
38 	if (pid == -1) {
39 		restore_old_sighup(oldActionResult, &oldAction);
40 		return -1;
41 	}
42 	if (pid > 0) {
43 		// we're the parent - let's exit
44 		exit(0);
45 	}
46 
47 	newGroup = setsid();
48 	restore_old_sighup(oldActionResult, &oldAction);
49 
50 	if (newGroup == -1)
51 		return -1;
52 
53 	if (!noChangeDir)
54 		chdir("/");
55 
56 	if (!noClose) {
57 		int fd = open("/dev/null", O_RDWR);
58 		if (fd != -1) {
59 			dup2(fd, STDIN_FILENO);
60 			dup2(fd, STDOUT_FILENO);
61 			dup2(fd, STDERR_FILENO);
62 			if (fd > STDERR_FILENO)
63 				close(fd);
64 		}
65 	}
66 
67 	return 0;
68 }
69