1 /*
2    daemon.c - implementation of daemon() for systems that lack it
3 
4    Copyright (C) 2002, 2003 Arthur de Jong
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 
22 #include "daemon.h"
23 
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 
29 
daemon(int nochdir,int noclose)30 int daemon(int nochdir,int noclose)
31 {
32   /* change directory */
33   if (!nochdir)
34     if (chdir("/")!=0)
35       return -1;
36   /* fork() and exit() to detach from the parent process */
37   switch (fork())
38   {
39   case 0: /* we are the child */
40     break;
41   case -1: /* we are the parent, but have an error */
42     return -1;
43   default: /* we are the parent and we're done*/
44     _exit(0);
45   }
46   /* become process leader */
47   if (setsid()<0)
48   {
49     return -1;
50   }
51   /* fork again so we cannot allocate a pty */
52   switch (fork())
53   {
54   case 0: /* we are the child */
55     break;
56   case -1: /* we are the parent, but have an error */
57     return -1;
58   default: /* we are the parent and we're done*/
59     _exit(0);
60   }
61   /* close stdin, stdout and stderr and reconnect to /dev/null */
62   if (!noclose)
63   {
64     close(0); /* stdin */
65     close(1); /* stdout */
66     close(2); /* stderr */
67     open("/dev/null",O_RDWR); /* stdin, fd=0 */
68     dup(0); /* stdout, fd=1 */
69     dup(0); /* stderr, fd=2 */
70   }
71   return 0;
72 }
73