1/* $Id: daemonize.c,v 1.12 2011/05/27 09:35:02 nanard Exp $ */
2/* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
7
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <unistd.h>
11#include <fcntl.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <syslog.h>
15#include <string.h>
16#include <signal.h>
17
18#include "daemonize.h"
19#include "config.h"
20
21#ifndef USE_DAEMON
22
23int
24daemonize(void)
25{
26	int pid, i;
27
28	switch(fork())
29	{
30	/* fork error */
31	case -1:
32		perror("fork()");
33		exit(1);
34
35	/* child process */
36	case 0:
37		/* obtain a new process group */
38		if( (pid = setsid()) < 0)
39		{
40			perror("setsid()");
41			exit(1);
42		}
43
44		/* close all descriptors */
45		for (i=getdtablesize();i>=0;--i) close(i);
46
47		i = open("/dev/null", O_RDWR); /* open stdin */
48		dup(i); /* stdout */
49		dup(i); /* stderr */
50
51		umask(027);
52		chdir("/"); /* chdir to /tmp ? */
53
54		return pid;
55
56	/* parent process */
57	default:
58		exit(0);
59	}
60}
61#endif
62
63int
64writepidfile(const char * fname, int pid)
65{
66	char pidstring[16];
67	int pidstringlen;
68	int pidfile;
69
70	if(!fname || (strlen(fname) == 0))
71		return -1;
72
73	if( (pidfile = open(fname, O_WRONLY|O_CREAT, 0644)) < 0)
74	{
75		syslog(LOG_ERR, "Unable to open pidfile for writing %s: %m", fname);
76		return -1;
77	}
78
79	pidstringlen = snprintf(pidstring, sizeof(pidstring), "%d\n", pid);
80	if(pidstringlen <= 0)
81	{
82		syslog(LOG_ERR,
83			"Unable to write to pidfile %s: snprintf(): FAILED", fname);
84		close(pidfile);
85		return -1;
86	}
87	else
88	{
89		if(write(pidfile, pidstring, pidstringlen) < 0)
90			syslog(LOG_ERR, "Unable to write to pidfile %s: %m", fname);
91	}
92
93	close(pidfile);
94
95	return 0;
96}
97
98int
99checkforrunning(const char * fname)
100{
101	char buffer[64];
102	int pidfile;
103	pid_t pid;
104
105	if(!fname || (strlen(fname) == 0))
106		return -1;
107
108	if( (pidfile = open(fname, O_RDONLY)) < 0)
109		return 0;
110
111	memset(buffer, 0, 64);
112
113	if(read(pidfile, buffer, 63))
114	{
115		if( (pid = atol(buffer)) > 0)
116		{
117			if(!kill(pid, 0))
118			{
119				close(pidfile);
120				return -2;
121			}
122		}
123	}
124
125	close(pidfile);
126
127	return 0;
128}
129
130