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
restore_old_sighup(int result,struct sigaction * action)16 restore_old_sighup(int result, struct sigaction *action)
17 {
18 if (result != -1)
19 sigaction(SIGHUP, action, NULL);
20 }
21
22
23 int
daemon(int noChangeDir,int noClose)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