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
|
bool DaemonInit()
{
/* Our process ID and Session ID */
pid_t pid, sid;
/* Change the file mode mask */
umask(0);
/* Fork off the parent process */
pid = fork();
if (pid < 0)
{
std::cerr << "First fock failed!" << std::endl;;
return false;
}
/* If we got a good PID, then
* we can exit the parent process. */
if (pid > 0)
{
sleep(1);
exit(EXIT_SUCCESS);
}
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0)
{
std::cerr << "Setsid failed!" << std::endl;;
return false;
}
/* Fork off the second time */
pid = fork();
if (pid < 0)
{
std::cerr << "Second fork failed!" << std::endl;;
return false;
}
/* If we got a good PID, then
* we can exit the parent process. */
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
/* Ignore signals */
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN);
/* Change the current working directory */
if ((chdir("/")) < 0) {
return false;
}
//需保证 pid_fd 生命周期与进程生命周期一致
int pid_fd = open("/var/run/daemon_example.pid", O_RDWR|O_CREAT, 0640);
if ( pid_fd < 0)
{
//std::cerr << "Can not open " << pidfile_ << std::endl;
return false;
}
if (lockf(fd_, F_TLOCK, 0) < 0)
{
//std::cerr << "Another instance is running!" << std::endl;;
return false;
}
/*write and lock pid file*/
std::stringstream stream;
stream << getpid() << '\n';
std::string pidstr = stream.str();
ssize_t len = write(fd_, pidstr.c_str(), pidstr.length());
if(len < 0)
{
//std::cerr << "Write to /var/run/daemon_example.pid failed!"
// << std::endl;;
return false;
}
/* Close out the standard file descriptors */
if(close(STDIN_FILENO) == -1)
{
//std::cerr << "Can not close STDIN_FILENO!" << std::endl;
return false;
}
if(close(STDOUT_FILENO) == -1)
{
//std::cerr << "Can not close STDOUT_FILENO!" << std::endl;
return false;
}
if(close(STDERR_FILENO) == -1)
{
//std::cerr << "Can not close STDERR_FILENO!" << std::endl;
return false;
}
/*redirect standard output*/
//需保证 output_fd 生命周期与进程生命周期一致
int output_fd = open(DEV_NULL, O_RDWR, 0);
if(output_fd == -1)
{
return false;
}
if(dup2(output_fd, STDIN_FILENO) == -1)
{
return false;
}
if(dup2(output_fd, STDOUT_FILENO) == -1)
{
return false;
}
if(dup2(output_fd, STDERR_FILENO) == -1)
{
return false;
}
return true;
}
|