forked from pi-hole/FTL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
daemon.c
159 lines (139 loc) · 3.37 KB
/
daemon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* Daemon routines
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
struct timeval t0[NUMTIMERS];
void go_daemon(void)
{
pid_t process_id = 0;
pid_t sid = 0;
// Create child process
process_id = fork();
// Indication of fork() failure
if (process_id < 0)
{
logg("fork failed!\n");
// Return failure in exit status
exit(EXIT_FAILURE);
}
// PARENT PROCESS. Need to kill it.
if (process_id > 0)
{
printf("FTL started!\n");
// return success in exit status
exit(EXIT_SUCCESS);
}
//unmask the file mode
umask(0);
//set new session
// creates a session and sets the process group ID
sid = setsid();
if(sid < 0)
{
// Return failure
logg("setsid failed!\n");
exit(EXIT_FAILURE);
}
// Create grandchild process
// Fork a second child and exit immediately to prevent zombies. This
// causes the second child process to be orphaned, making the init
// process responsible for its cleanup. And, since the first child is
// a session leader without a controlling terminal, it's possible for
// it to acquire one by opening a terminal in the future (System V-
// based systems). This second fork guarantees that the child is no
// longer a session leader, preventing the daemon from ever acquiring
// a controlling terminal.
process_id = fork();
// Indication of fork() failure
if (process_id < 0)
{
logg("fork failed!\n");
// Return failure in exit status
exit(EXIT_FAILURE);
}
// PARENT PROCESS. Need to kill it.
if (process_id > 0)
{
// return success in exit status
exit(EXIT_SUCCESS);
}
savepid();
// Closing stdin, stdout and stderr is handled by dnsmasq
}
void timer_start(int i)
{
if(i >= NUMTIMERS)
{
logg("Code error: Timer %i not defined in timer_start().", i);
exit(EXIT_FAILURE);
}
gettimeofday(&t0[i], 0);
}
double timer_elapsed_msec(int i)
{
if(i >= NUMTIMERS)
{
logg("Code error: Timer %i not defined in timer_elapsed_msec().", i);
exit(EXIT_FAILURE);
}
struct timeval t1;
gettimeofday(&t1, 0);
return (t1.tv_sec - t0[i].tv_sec) * 1000.0f + (t1.tv_usec - t0[i].tv_usec) / 1000.0f;
}
void sleepms(int milliseconds)
{
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = (milliseconds % 1000) * 1000;
select(0, NULL, NULL, NULL, &tv);
}
void savepid(void)
{
FILE *f;
pid_t pid = getpid();
if((f = fopen(FTLfiles.pid, "w+")) == NULL)
{
logg("WARNING: Unable to write PID to file.");
logg(" Continuing anyway...");
}
else
{
fprintf(f, "%i", (int)pid);
fclose(f);
}
logg("PID of FTL process: %i", (int)pid);
}
void removepid(void)
{
FILE *f;
if((f = fopen(FTLfiles.pid, "w+")) == NULL)
{
logg("WARNING: Unable to empty PID file");
return;
}
fclose(f);
}
char *getUserName(void)
{
char * name;
// the getpwuid() function shall search the user database for an entry with a matching uid
// the geteuid() function shall return the effective user ID of the calling process - this is used as the search criteria for the getpwuid() function
uid_t euid = geteuid();
struct passwd *pw = getpwuid(euid);
if(pw)
{
name = strdup(pw->pw_name);
}
else
{
if(asprintf(&name, "%u", euid) < 0)
return NULL;
}
return name;
}