passenger 4.0.19 → 4.0.20
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +15 -0
- checksums.yaml.gz.asc +12 -0
- data.tar.gz.asc +7 -7
- data/NEWS +22 -0
- data/bin/passenger-install-apache2-module +2 -2
- data/bin/passenger-install-nginx-module +2 -2
- data/build/agents.rb +6 -0
- data/build/apache2.rb +1 -0
- data/build/basics.rb +2 -2
- data/build/cplusplus_support.rb +6 -1
- data/build/cxx_tests.rb +1 -0
- data/build/nginx.rb +1 -0
- data/build/packaging.rb +1 -1
- data/dev/copy_boost_headers.rb +1 -0
- data/doc/Users guide Apache.idmap.txt +56 -54
- data/doc/Users guide Apache.txt +22 -3
- data/doc/Users guide Nginx.idmap.txt +52 -50
- data/doc/Users guide Nginx.txt +22 -3
- data/ext/apache2/Configuration.hpp +4 -0
- data/ext/apache2/ConfigurationCommands.cpp +6 -0
- data/ext/apache2/ConfigurationFields.hpp +6 -4
- data/ext/apache2/ConfigurationSetters.cpp +11 -0
- data/ext/apache2/CreateDirConfig.cpp +1 -0
- data/ext/apache2/Hooks.cpp +2 -0
- data/ext/apache2/MergeDirConfig.cpp +7 -0
- data/ext/boost/type_traits/detail/common_type_imp.hpp +333 -0
- data/ext/boost/type_traits/detail/has_binary_operator.hpp +229 -0
- data/ext/boost/type_traits/detail/has_postfix_operator.hpp +202 -0
- data/ext/boost/type_traits/detail/has_prefix_operator.hpp +210 -0
- data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +654 -0
- data/ext/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp +2759 -0
- data/ext/boost/type_traits/detail/wrap.hpp +18 -0
- data/ext/common/Constants.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +1 -1
- data/ext/common/agents/HelperAgent/Main.cpp +18 -1
- data/ext/common/agents/HelperAgent/RequestHandler.h +3 -0
- data/ext/common/agents/SpawnPreparer.cpp +25 -0
- data/ext/common/agents/TempDirToucher.c +357 -0
- data/ext/common/agents/Watchdog/Main.cpp +38 -0
- data/ext/nginx/CacheLocationConfig.c +21 -1
- data/ext/nginx/CacheLocationConfig.c.erb +1 -1
- data/ext/nginx/ConfigurationCommands.c +10 -0
- data/ext/nginx/ConfigurationFields.h +18 -16
- data/ext/nginx/ConfigurationFields.h.erb +11 -6
- data/ext/nginx/CreateLocationConfig.c +4 -0
- data/ext/nginx/MergeLocationConfig.c +6 -0
- data/helper-scripts/node-loader.js +6 -2
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/{rails3_extensions → active_support3_extensions}/init.rb +10 -8
- data/lib/phusion_passenger/apache2/config_options.rb +5 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +61 -7
- data/lib/phusion_passenger/nginx/config_options.rb +4 -0
- data/lib/phusion_passenger/platform_info/apache.rb +6 -1
- data/lib/phusion_passenger/platform_info/compiler.rb +29 -2
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/ruby.rb +7 -3
- data/lib/phusion_passenger/public_api.rb +4 -4
- data/lib/phusion_passenger/standalone/command.rb +10 -0
- data/lib/phusion_passenger/standalone/runtime_installer.rb +2 -2
- data/lib/phusion_passenger/standalone/start_command.rb +14 -8
- data/lib/phusion_passenger/utils/unseekable_socket.rb +52 -0
- data/resources/templates/standalone/config.erb +11 -0
- metadata +14 -15
- metadata.gz.asc +7 -7
- data/helper-scripts/touch-dir.sh +0 -48
@@ -0,0 +1,18 @@
|
|
1
|
+
// (C) Copyright David Abrahams 2002.
|
2
|
+
// Use, modification and distribution are subject to the Boost Software License,
|
3
|
+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
4
|
+
// http://www.boost.org/LICENSE_1_0.txt).
|
5
|
+
//
|
6
|
+
// See http://www.boost.org/libs/type_traits for most recent version including documentation.
|
7
|
+
|
8
|
+
#ifndef BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
|
9
|
+
#define BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
|
10
|
+
|
11
|
+
namespace boost {
|
12
|
+
namespace type_traits {
|
13
|
+
|
14
|
+
template <class T> struct wrap {};
|
15
|
+
|
16
|
+
}} // namespace boost::type_traits
|
17
|
+
|
18
|
+
#endif // BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
|
data/ext/common/Constants.h
CHANGED
@@ -512,7 +512,7 @@ cEscapeString(const StaticString &input) {
|
|
512
512
|
string
|
513
513
|
escapeHTML(const StaticString &input) {
|
514
514
|
string result;
|
515
|
-
result.reserve((int)
|
515
|
+
result.reserve((int) ceil(input.size() * 1.25));
|
516
516
|
|
517
517
|
const char *current = (const char *) input.c_str();
|
518
518
|
const char *end = current + input.size();
|
@@ -506,7 +506,24 @@ public:
|
|
506
506
|
requestHandler.reset();
|
507
507
|
|
508
508
|
if (!options.requestSocketLink.empty()) {
|
509
|
-
|
509
|
+
char path[PATH_MAX + 1];
|
510
|
+
ssize_t ret;
|
511
|
+
bool shouldUnlink;
|
512
|
+
|
513
|
+
ret = readlink(options.requestSocketLink.c_str(), path, PATH_MAX);
|
514
|
+
if (ret != -1) {
|
515
|
+
path[ret] = '\0';
|
516
|
+
// Only unlink if a new Flying Passenger instance hasn't overwritten the
|
517
|
+
// symlink.
|
518
|
+
// https://code.google.com/p/phusion-passenger/issues/detail?id=939
|
519
|
+
shouldUnlink = getRequestSocketFilename() == path;
|
520
|
+
} else {
|
521
|
+
shouldUnlink = true;
|
522
|
+
}
|
523
|
+
|
524
|
+
if (shouldUnlink) {
|
525
|
+
syscalls::unlink(options.requestSocketLink.c_str());
|
526
|
+
}
|
510
527
|
}
|
511
528
|
|
512
529
|
P_TRACE(2, "All threads have been shut down.");
|
@@ -1747,6 +1747,9 @@ private:
|
|
1747
1747
|
|
1748
1748
|
client->beginScopeLog(&client->scopeLogs.requestProcessing, "request processing");
|
1749
1749
|
|
1750
|
+
StaticString staticRequestMethod = parser.getHeader("REQUEST_METHOD");
|
1751
|
+
client->logMessage("Request method: " + staticRequestMethod);
|
1752
|
+
|
1750
1753
|
StaticString staticRequestURI = parser.getHeader("REQUEST_URI");
|
1751
1754
|
if (!staticRequestURI.empty()) {
|
1752
1755
|
client->logMessage("URI: " + staticRequestURI);
|
@@ -1,3 +1,28 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2012-2013 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
|
1
26
|
/*
|
2
27
|
* Sets given environment variables, dumps the entire environment to
|
3
28
|
* a given file (for diagnostics purposes), then execs the given command.
|
@@ -0,0 +1,357 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2013 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
|
26
|
+
/* This tool touches everything in a directory every 30 minutes to prevent
|
27
|
+
* /tmp cleaners from removing it.
|
28
|
+
*/
|
29
|
+
|
30
|
+
#include <sys/stat.h>
|
31
|
+
#include <sys/types.h>
|
32
|
+
#include <sys/wait.h>
|
33
|
+
#include <stdio.h>
|
34
|
+
#include <stdlib.h>
|
35
|
+
#include <unistd.h>
|
36
|
+
#include <signal.h>
|
37
|
+
#include <fcntl.h>
|
38
|
+
#include <limits.h>
|
39
|
+
#include <errno.h>
|
40
|
+
#include <string.h>
|
41
|
+
|
42
|
+
#define ERROR_PREFIX "*** TempDirToucher error"
|
43
|
+
|
44
|
+
static char *dir;
|
45
|
+
/**
|
46
|
+
* When Passenger Standalone is started with --daemonize, then it will
|
47
|
+
* pass --cleanup to this tool so that this tool is responsible
|
48
|
+
* for cleaning up the Standalone temp dir.
|
49
|
+
*/
|
50
|
+
static int shouldCleanup = 0;
|
51
|
+
static int shouldDaemonize = 0;
|
52
|
+
static const char *pidFile = NULL;
|
53
|
+
static const char *logFile = NULL;
|
54
|
+
static int terminationPipe[2];
|
55
|
+
|
56
|
+
|
57
|
+
static void
|
58
|
+
parseArguments(int argc, char *argv[]) {
|
59
|
+
dir = argv[1];
|
60
|
+
int i;
|
61
|
+
|
62
|
+
for (i = 2; i < argc; i++) {
|
63
|
+
if (strcmp(argv[i], "--cleanup") == 0) {
|
64
|
+
shouldCleanup = 1;
|
65
|
+
} else if (strcmp(argv[i], "--daemonize") == 0) {
|
66
|
+
shouldDaemonize = 1;
|
67
|
+
} else if (strcmp(argv[i], "--pid-file") == 0) {
|
68
|
+
pidFile = argv[i + 1];
|
69
|
+
i++;
|
70
|
+
} else if (strcmp(argv[i], "--log-file") == 0) {
|
71
|
+
logFile = argv[i + 1];
|
72
|
+
i++;
|
73
|
+
} else {
|
74
|
+
fprintf(stderr, ERROR_PREFIX ": unrecognized argument %s\n",
|
75
|
+
argv[i]);
|
76
|
+
exit(1);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
static void
|
82
|
+
setNonBlocking(int fd) {
|
83
|
+
int flags, ret, e;
|
84
|
+
|
85
|
+
do {
|
86
|
+
flags = fcntl(fd, F_GETFL);
|
87
|
+
} while (flags == -1 && errno == EINTR);
|
88
|
+
if (flags == -1) {
|
89
|
+
e = errno;
|
90
|
+
fprintf(stderr, ERROR_PREFIX
|
91
|
+
": cannot set pipe to non-blocking mode: "
|
92
|
+
"cannot get file descriptor flags. Error: %s (errno %d)\n",
|
93
|
+
strerror(e), e);
|
94
|
+
exit(1);
|
95
|
+
}
|
96
|
+
do {
|
97
|
+
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
98
|
+
} while (ret == -1 && errno == EINTR);
|
99
|
+
if (ret == -1) {
|
100
|
+
e = errno;
|
101
|
+
fprintf(stderr, ERROR_PREFIX
|
102
|
+
": cannot set pipe to non-blocking mode: "
|
103
|
+
"cannot set file descriptor flags. Error: %s (errno %d)\n",
|
104
|
+
strerror(e), e);
|
105
|
+
exit(1);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
static void
|
110
|
+
initialize(int argc, char *argv[]) {
|
111
|
+
int e, fd;
|
112
|
+
|
113
|
+
parseArguments(argc, argv);
|
114
|
+
|
115
|
+
if (logFile != NULL) {
|
116
|
+
fd = open(logFile, O_WRONLY | O_APPEND | O_CREAT);
|
117
|
+
if (fd == -1) {
|
118
|
+
e = errno;
|
119
|
+
fprintf(stderr, ERROR_PREFIX
|
120
|
+
": cannot open log file %s for writing: %s (errno %d)\n",
|
121
|
+
logFile, strerror(e), e);
|
122
|
+
exit(1);
|
123
|
+
}
|
124
|
+
|
125
|
+
if (dup2(fd, 1) == -1) {
|
126
|
+
e = errno;
|
127
|
+
fprintf(stderr, ERROR_PREFIX ": cannot dup2(%d, 1): %s (errno %d)\n",
|
128
|
+
fd, strerror(e), e);
|
129
|
+
}
|
130
|
+
if (dup2(fd, 2) == -1) {
|
131
|
+
e = errno;
|
132
|
+
fprintf(stderr, ERROR_PREFIX ": cannot dup2(%d, 2): %s (errno %d)\n",
|
133
|
+
fd, strerror(e), e);
|
134
|
+
}
|
135
|
+
|
136
|
+
close(fd);
|
137
|
+
}
|
138
|
+
|
139
|
+
if (pipe(terminationPipe) == -1) {
|
140
|
+
e = errno;
|
141
|
+
fprintf(stderr, ERROR_PREFIX ": cannot create a pipe: %s (errno %d)\n",
|
142
|
+
strerror(e), e);
|
143
|
+
exit(1);
|
144
|
+
}
|
145
|
+
|
146
|
+
setNonBlocking(terminationPipe[1]);
|
147
|
+
}
|
148
|
+
|
149
|
+
static void
|
150
|
+
exitHandler(int signo) {
|
151
|
+
write(terminationPipe[1], "x", 1);
|
152
|
+
}
|
153
|
+
|
154
|
+
static void
|
155
|
+
installSignalHandlers() {
|
156
|
+
struct sigaction action;
|
157
|
+
|
158
|
+
action.sa_handler = exitHandler;
|
159
|
+
action.sa_flags = SA_RESTART;
|
160
|
+
sigemptyset(&action.sa_mask);
|
161
|
+
sigaction(SIGINT, &action, NULL);
|
162
|
+
sigaction(SIGTERM, &action, NULL);
|
163
|
+
}
|
164
|
+
|
165
|
+
static void
|
166
|
+
redirectStdinToNull() {
|
167
|
+
int fd = open("/dev/null", O_RDONLY);
|
168
|
+
if (fd != -1) {
|
169
|
+
dup2(fd, 1);
|
170
|
+
close(fd);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
static void
|
175
|
+
maybeDaemonize() {
|
176
|
+
pid_t pid;
|
177
|
+
int e;
|
178
|
+
|
179
|
+
if (shouldDaemonize) {
|
180
|
+
pid = fork();
|
181
|
+
if (pid == 0) {
|
182
|
+
setsid();
|
183
|
+
chdir("/");
|
184
|
+
redirectStdinToNull();
|
185
|
+
} else if (pid == -1) {
|
186
|
+
e = errno;
|
187
|
+
fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
|
188
|
+
strerror(e), e);
|
189
|
+
exit(1);
|
190
|
+
} else {
|
191
|
+
_exit(0);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
static void
|
197
|
+
maybeWritePidfile() {
|
198
|
+
FILE *f;
|
199
|
+
|
200
|
+
if (pidFile != NULL) {
|
201
|
+
f = fopen(pidFile, "w");
|
202
|
+
if (f != NULL) {
|
203
|
+
fprintf(f, "%d\n", (int) getpid());
|
204
|
+
fclose(f);
|
205
|
+
} else {
|
206
|
+
fprintf(stderr, ERROR_PREFIX ": cannot open PID file %s for writing\n",
|
207
|
+
pidFile);
|
208
|
+
exit(1);
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
static int
|
214
|
+
dirExists(const char *dir) {
|
215
|
+
struct stat buf;
|
216
|
+
return stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode);
|
217
|
+
}
|
218
|
+
|
219
|
+
static void
|
220
|
+
touchDir(const char *dir) {
|
221
|
+
pid_t pid;
|
222
|
+
int e, status;
|
223
|
+
|
224
|
+
pid = fork();
|
225
|
+
if (pid == 0) {
|
226
|
+
close(terminationPipe[0]);
|
227
|
+
close(terminationPipe[1]);
|
228
|
+
if (chdir(dir) == -1) {
|
229
|
+
e = errno;
|
230
|
+
fprintf(stderr, ERROR_PREFIX
|
231
|
+
": cannot change working directory to %s: %s (errno %d)\n",
|
232
|
+
dir, strerror(e), e);
|
233
|
+
_exit(1);
|
234
|
+
}
|
235
|
+
execlp("/bin/sh", "/bin/sh", "-c",
|
236
|
+
"find \"$1\" | xargs touch", "/bin/sh", ".",
|
237
|
+
(const char * const) 0);
|
238
|
+
e = errno;
|
239
|
+
fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
|
240
|
+
strerror(e), e);
|
241
|
+
_exit(1);
|
242
|
+
} else if (pid == -1) {
|
243
|
+
e = errno;
|
244
|
+
fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
|
245
|
+
strerror(e), e);
|
246
|
+
exit(1);
|
247
|
+
} else {
|
248
|
+
if (waitpid(pid, &status, 0) == -1) {
|
249
|
+
if (errno != ESRCH && errno != EPERM) {
|
250
|
+
fprintf(stderr, ERROR_PREFIX
|
251
|
+
": unable to wait for shell command 'find %s | xargs touch'\n",
|
252
|
+
dir);
|
253
|
+
exit(1);
|
254
|
+
}
|
255
|
+
} else if (WEXITSTATUS(status) != 0) {
|
256
|
+
fprintf(stderr, ERROR_PREFIX
|
257
|
+
": shell command 'find %s | xargs touch' failed with exit status %d\n",
|
258
|
+
dir, WEXITSTATUS(status));
|
259
|
+
exit(1);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
static int
|
265
|
+
doSleep(int sec) {
|
266
|
+
fd_set readfds;
|
267
|
+
struct timeval timeout;
|
268
|
+
int ret, e;
|
269
|
+
|
270
|
+
FD_ZERO(&readfds);
|
271
|
+
FD_SET(terminationPipe[0], &readfds);
|
272
|
+
timeout.tv_sec = sec;
|
273
|
+
timeout.tv_usec = 0;
|
274
|
+
do {
|
275
|
+
ret = select(terminationPipe[0] + 1, &readfds, NULL, NULL, &timeout);
|
276
|
+
} while (ret == -1 && errno == EINTR);
|
277
|
+
if (ret == -1) {
|
278
|
+
e = errno;
|
279
|
+
fprintf(stderr, ERROR_PREFIX ": cannot select(): %s (errno %d)\n",
|
280
|
+
strerror(e), e);
|
281
|
+
exit(1);
|
282
|
+
return -1; /* Never reached */
|
283
|
+
} else {
|
284
|
+
return ret == 0;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
static void
|
289
|
+
maybeDeletePidFile() {
|
290
|
+
if (pidFile != NULL) {
|
291
|
+
unlink(pidFile);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
static void
|
296
|
+
performCleanup(const char *dir) {
|
297
|
+
pid_t pid;
|
298
|
+
int e, status;
|
299
|
+
|
300
|
+
pid = fork();
|
301
|
+
if (pid == 0) {
|
302
|
+
close(terminationPipe[0]);
|
303
|
+
close(terminationPipe[1]);
|
304
|
+
execlp("/bin/sh", "/bin/sh", "-c",
|
305
|
+
"rm -rf \"$1\"", "/bin/sh", dir,
|
306
|
+
(const char * const) 0);
|
307
|
+
e = errno;
|
308
|
+
fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
|
309
|
+
strerror(e), e);
|
310
|
+
_exit(1);
|
311
|
+
} else if (pid == -1) {
|
312
|
+
e = errno;
|
313
|
+
fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
|
314
|
+
strerror(e), e);
|
315
|
+
exit(1);
|
316
|
+
} else {
|
317
|
+
if (waitpid(pid, &status, 0) == -1) {
|
318
|
+
if (errno != ESRCH && errno != EPERM) {
|
319
|
+
fprintf(stderr, ERROR_PREFIX
|
320
|
+
": unable to wait for shell command 'rm -rf %s'\n",
|
321
|
+
dir);
|
322
|
+
exit(1);
|
323
|
+
}
|
324
|
+
} else if (WEXITSTATUS(status) != 0) {
|
325
|
+
fprintf(stderr, ERROR_PREFIX
|
326
|
+
": shell command 'rm -rf %s' failed with exit status %d\n",
|
327
|
+
dir, WEXITSTATUS(status));
|
328
|
+
exit(1);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
int
|
334
|
+
main(int argc, char *argv[]) {
|
335
|
+
initialize(argc, argv);
|
336
|
+
installSignalHandlers();
|
337
|
+
maybeDaemonize();
|
338
|
+
maybeWritePidfile();
|
339
|
+
|
340
|
+
while (1) {
|
341
|
+
if (dirExists(dir)) {
|
342
|
+
touchDir(dir);
|
343
|
+
if (!doSleep(1800)) {
|
344
|
+
break;
|
345
|
+
}
|
346
|
+
} else {
|
347
|
+
break;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
maybeDeletePidFile();
|
352
|
+
if (shouldCleanup) {
|
353
|
+
performCleanup(dir);
|
354
|
+
}
|
355
|
+
|
356
|
+
return 0;
|
357
|
+
}
|