]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/daemon.php
Merge commit 'br3nda/0.8.x-noticesfix' into 0.8.x
[quix0rs-gnu-social.git] / lib / daemon.php
1 <?php
2 /**
3  * Laconica - a distributed open-source microblogging tool
4  * Copyright (C) 2008, 2009, Control Yourself, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) 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 Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 if (!defined('LACONICA')) {
21     exit(1);
22 }
23
24 class Daemon
25 {
26     var $daemonize = true;
27
28     function __construct($daemonize = true)
29     {
30         $this->daemonize = $daemonize;
31     }
32
33     function name()
34     {
35         return null;
36     }
37
38     function background()
39     {
40         $pid = pcntl_fork();
41         if ($pid < 0) { // error
42             common_log(LOG_ERR, "Could not fork.");
43             return false;
44         } else if ($pid > 0) { // parent
45             common_log(LOG_INFO, "Successfully forked.");
46             exit(0);
47         } else { // child
48             return true;
49         }
50     }
51
52     function alreadyRunning()
53     {
54         $pidfilename = $this->pidFilename();
55
56         if (!$pidfilename) {
57             return false;
58         }
59
60         if (!file_exists($pidfilename)) {
61             return false;
62         }
63         $contents = file_get_contents($pidfilename);
64         if (posix_kill(trim($contents), 0)) {
65             return true;
66         } else {
67             return false;
68         }
69     }
70
71     function writePidFile()
72     {
73         $pidfilename = $this->pidFilename();
74
75         if (!$pidfilename) {
76             return false;
77         }
78
79         return file_put_contents($pidfilename, posix_getpid() . "\n");
80     }
81
82     function clearPidFile()
83     {
84         $pidfilename = $this->pidFilename();
85         if (!$pidfilename) {
86             return false;
87         }
88         return unlink($pidfilename);
89     }
90
91     function pidFilename()
92     {
93         $piddir = common_config('daemon', 'piddir');
94         if (!$piddir) {
95             return null;
96         }
97         $name = $this->name();
98         if (!$name) {
99             return null;
100         }
101         return $piddir . '/' . $name . '.pid';
102     }
103
104     function changeUser()
105     {
106         $username = common_config('daemon', 'user');
107
108         if ($username) {
109             $user_info = posix_getpwnam($username);
110             if (!$user_info) {
111                 common_log(LOG_WARNING,
112                            'Ignoring unknown user for daemon: ' . $username);
113             } else {
114                 common_log(LOG_INFO, "Setting user to " . $username);
115                 posix_setuid($user_info['uid']);
116             }
117         }
118
119         $groupname = common_config('daemon', 'group');
120
121         if ($groupname) {
122             $group_info = posix_getgrnam($groupname);
123             if (!$group_info) {
124                 common_log(LOG_WARNING,
125                            'Ignoring unknown group for daemon: ' . $groupname);
126             } else {
127                 common_log(LOG_INFO, "Setting group to " . $groupname);
128                 posix_setgid($group_info['gid']);
129             }
130         }
131     }
132
133     function runOnce()
134     {
135         if ($this->alreadyRunning()) {
136             common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
137             exit(0);
138         }
139
140         if ($this->daemonize) {
141             common_log(LOG_INFO, 'Backgrounding daemon "'.$this->name().'"');
142             $this->background();
143         }
144
145         $this->writePidFile();
146         $this->changeUser();
147         $this->run();
148         $this->clearPidFile();
149     }
150
151     function run()
152     {
153         return true;
154     }
155 }