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