summaryrefslogtreecommitdiff
path: root/src/util/os_priority.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r--src/util/os_priority.c1160
1 files changed, 581 insertions, 579 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index e25623af5..ad510a9b3 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -29,18 +29,19 @@
29#include "disk.h" 29#include "disk.h"
30#include <unistr.h> 30#include <unistr.h>
31 31
32#define LOG(kind, ...) GNUNET_log_from(kind, "util-os-priority", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
33 33
34#define LOG_STRERROR(kind, syscall) \ 34#define LOG_STRERROR(kind, syscall) \
35 GNUNET_log_from_strerror(kind, "util-os-priority", syscall) 35 GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
36 36
37#define LOG_STRERROR_FILE(kind, syscall, filename) \ 37#define LOG_STRERROR_FILE(kind, syscall, filename) \
38 GNUNET_log_from_strerror_file(kind, "util-os-priority", syscall, filename) 38 GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename)
39 39
40#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" 40#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
41 41
42 42
43struct GNUNET_OS_Process { 43struct GNUNET_OS_Process
44{
44 /** 45 /**
45 * PID of the process. 46 * PID of the process.
46 */ 47 */
@@ -77,13 +78,13 @@ static struct GNUNET_SCHEDULER_Task *spch;
77 * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe 78 * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe
78 */ 79 */
79static void 80static void
80shutdown_pch(void *cls) 81shutdown_pch (void *cls)
81{ 82{
82 struct GNUNET_DISK_FileHandle *control_pipe = cls; 83 struct GNUNET_DISK_FileHandle *control_pipe = cls;
83 84
84 GNUNET_SCHEDULER_cancel(pch); 85 GNUNET_SCHEDULER_cancel (pch);
85 pch = NULL; 86 pch = NULL;
86 GNUNET_DISK_file_close(control_pipe); 87 GNUNET_DISK_file_close (control_pipe);
87 control_pipe = NULL; 88 control_pipe = NULL;
88} 89}
89 90
@@ -94,7 +95,7 @@ shutdown_pch(void *cls)
94 * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe 95 * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe
95 */ 96 */
96static void 97static void
97parent_control_handler(void *cls) 98parent_control_handler (void *cls)
98{ 99{
99 struct GNUNET_DISK_FileHandle *control_pipe = cls; 100 struct GNUNET_DISK_FileHandle *control_pipe = cls;
100 char sig; 101 char sig;
@@ -102,29 +103,29 @@ parent_control_handler(void *cls)
102 ssize_t ret; 103 ssize_t ret;
103 104
104 pch = NULL; 105 pch = NULL;
105 ret = GNUNET_DISK_file_read(control_pipe, &sig, sizeof(sig)); 106 ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof(sig));
106 if (sizeof(sig) != ret) 107 if (sizeof(sig) != ret)
107 { 108 {
108 if (-1 == ret) 109 if (-1 == ret)
109 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read"); 110 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
110 LOG(GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n"); 111 LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n");
111 GNUNET_DISK_file_close(control_pipe); 112 GNUNET_DISK_file_close (control_pipe);
112 control_pipe = NULL; 113 control_pipe = NULL;
113 GNUNET_SCHEDULER_cancel(spch); 114 GNUNET_SCHEDULER_cancel (spch);
114 spch = NULL; 115 spch = NULL;
115 return; 116 return;
116 } 117 }
117 pipe_fd = getenv(GNUNET_OS_CONTROL_PIPE); 118 pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE);
118 GNUNET_assert((NULL == pipe_fd) || (strlen(pipe_fd) <= 0)); 119 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
119 LOG(GNUNET_ERROR_TYPE_DEBUG, 120 LOG (GNUNET_ERROR_TYPE_DEBUG,
120 "Got control code %d from parent via pipe %s\n", 121 "Got control code %d from parent via pipe %s\n",
121 sig, 122 sig,
122 pipe_fd); 123 pipe_fd);
123 pch = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 124 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
124 control_pipe, 125 control_pipe,
125 &parent_control_handler, 126 &parent_control_handler,
126 control_pipe); 127 control_pipe);
127 GNUNET_SIGNAL_raise((int)sig); 128 GNUNET_SIGNAL_raise ((int) sig);
128} 129}
129 130
130 131
@@ -137,63 +138,63 @@ parent_control_handler(void *cls)
137 * @param cls closure (unused) 138 * @param cls closure (unused)
138 */ 139 */
139void 140void
140GNUNET_OS_install_parent_control_handler(void *cls) 141GNUNET_OS_install_parent_control_handler (void *cls)
141{ 142{
142 const char *env_buf; 143 const char *env_buf;
143 char *env_buf_end; 144 char *env_buf_end;
144 struct GNUNET_DISK_FileHandle *control_pipe; 145 struct GNUNET_DISK_FileHandle *control_pipe;
145 uint64_t pipe_fd; 146 uint64_t pipe_fd;
146 147
147 (void)cls; 148 (void) cls;
148 if (NULL != pch) 149 if (NULL != pch)
149 { 150 {
150 /* already done, we've been called twice... */ 151 /* already done, we've been called twice... */
151 GNUNET_break(0); 152 GNUNET_break (0);
152 return; 153 return;
153 } 154 }
154 env_buf = getenv(GNUNET_OS_CONTROL_PIPE); 155 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
155 if ((NULL == env_buf) || (strlen(env_buf) <= 0)) 156 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
156 { 157 {
157 LOG(GNUNET_ERROR_TYPE_DEBUG, 158 LOG (GNUNET_ERROR_TYPE_DEBUG,
158 "Not installing a handler because $%s is empty\n", 159 "Not installing a handler because $%s is empty\n",
159 GNUNET_OS_CONTROL_PIPE); 160 GNUNET_OS_CONTROL_PIPE);
160 putenv(GNUNET_OS_CONTROL_PIPE "="); 161 putenv (GNUNET_OS_CONTROL_PIPE "=");
161 return; 162 return;
162 } 163 }
163 errno = 0; 164 errno = 0;
164 pipe_fd = strtoull(env_buf, &env_buf_end, 16); 165 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
165 if ((0 != errno) || (env_buf == env_buf_end)) 166 if ((0 != errno) || (env_buf == env_buf_end))
166 { 167 {
167 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf); 168 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf);
168 putenv(GNUNET_OS_CONTROL_PIPE "="); 169 putenv (GNUNET_OS_CONTROL_PIPE "=");
169 return; 170 return;
170 } 171 }
171 if (pipe_fd >= FD_SETSIZE) 172 if (pipe_fd >= FD_SETSIZE)
172 { 173 {
173 LOG(GNUNET_ERROR_TYPE_ERROR, 174 LOG (GNUNET_ERROR_TYPE_ERROR,
174 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n", 175 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
175 env_buf); 176 env_buf);
176 putenv(GNUNET_OS_CONTROL_PIPE "="); 177 putenv (GNUNET_OS_CONTROL_PIPE "=");
177 return; 178 return;
178 } 179 }
179 180
180 control_pipe = GNUNET_DISK_get_handle_from_int_fd((int)pipe_fd); 181 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd);
181 182
182 if (NULL == control_pipe) 183 if (NULL == control_pipe)
183 { 184 {
184 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "open", env_buf); 185 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf);
185 putenv(GNUNET_OS_CONTROL_PIPE "="); 186 putenv (GNUNET_OS_CONTROL_PIPE "=");
186 return; 187 return;
187 } 188 }
188 LOG(GNUNET_ERROR_TYPE_DEBUG, 189 LOG (GNUNET_ERROR_TYPE_DEBUG,
189 "Adding parent control handler pipe `%s' to the scheduler\n", 190 "Adding parent control handler pipe `%s' to the scheduler\n",
190 env_buf); 191 env_buf);
191 pch = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 192 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
192 control_pipe, 193 control_pipe,
193 &parent_control_handler, 194 &parent_control_handler,
194 control_pipe); 195 control_pipe);
195 spch = GNUNET_SCHEDULER_add_shutdown(&shutdown_pch, control_pipe); 196 spch = GNUNET_SCHEDULER_add_shutdown (&shutdown_pch, control_pipe);
196 putenv(GNUNET_OS_CONTROL_PIPE "="); 197 putenv (GNUNET_OS_CONTROL_PIPE "=");
197} 198}
198 199
199 200
@@ -206,7 +207,7 @@ GNUNET_OS_install_parent_control_handler(void *cls)
206 * @return pointer to the process sturcutre for this process 207 * @return pointer to the process sturcutre for this process
207 */ 208 */
208struct GNUNET_OS_Process * 209struct GNUNET_OS_Process *
209GNUNET_OS_process_current() 210GNUNET_OS_process_current ()
210{ 211{
211 current_process.pid = 0; 212 current_process.pid = 0;
212 return &current_process; 213 return &current_process;
@@ -221,44 +222,44 @@ GNUNET_OS_process_current()
221 * @return 0 on success, -1 on error 222 * @return 0 on success, -1 on error
222 */ 223 */
223int 224int
224GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig) 225GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
225{ 226{
226 int ret; 227 int ret;
227 char csig; 228 char csig;
228 229
229 csig = (char)sig; 230 csig = (char) sig;
230 if (NULL != proc->control_pipe) 231 if (NULL != proc->control_pipe)
231 { 232 {
232 LOG(GNUNET_ERROR_TYPE_DEBUG, 233 LOG (GNUNET_ERROR_TYPE_DEBUG,
233 "Sending signal %d to pid: %u via pipe\n", 234 "Sending signal %d to pid: %u via pipe\n",
234 sig, 235 sig,
235 proc->pid); 236 proc->pid);
236 ret = GNUNET_DISK_file_write(proc->control_pipe, &csig, sizeof(csig)); 237 ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof(csig));
237 if (sizeof(csig) == ret) 238 if (sizeof(csig) == ret)
238 return 0; 239 return 0;
239 } 240 }
240 /* pipe failed or non-existent, try other methods */ 241 /* pipe failed or non-existent, try other methods */
241 switch (sig) 242 switch (sig)
242 { 243 {
243 case SIGHUP: 244 case SIGHUP:
244 case SIGINT: 245 case SIGINT:
245 case SIGKILL: 246 case SIGKILL:
246 case SIGTERM: 247 case SIGTERM:
247#if (SIGTERM != GNUNET_TERM_SIG) 248#if (SIGTERM != GNUNET_TERM_SIG)
248 case GNUNET_TERM_SIG: 249 case GNUNET_TERM_SIG:
249#endif 250#endif
250 LOG(GNUNET_ERROR_TYPE_DEBUG, 251 LOG (GNUNET_ERROR_TYPE_DEBUG,
251 "Sending signal %d to pid: %u via system call\n", 252 "Sending signal %d to pid: %u via system call\n",
252 sig, 253 sig,
253 proc->pid); 254 proc->pid);
254 return kill(proc->pid, sig); 255 return kill (proc->pid, sig);
255 default: 256 default:
256 LOG(GNUNET_ERROR_TYPE_DEBUG, 257 LOG (GNUNET_ERROR_TYPE_DEBUG,
257 "Sending signal %d to pid: %u via system call\n", 258 "Sending signal %d to pid: %u via system call\n",
258 sig, 259 sig,
259 proc->pid); 260 proc->pid);
260 return kill(proc->pid, sig); 261 return kill (proc->pid, sig);
261 } 262 }
262} 263}
263 264
264 265
@@ -270,7 +271,7 @@ GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
270 * @return the current process id 271 * @return the current process id
271 */ 272 */
272pid_t 273pid_t
273GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc) 274GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc)
274{ 275{
275 return proc->pid; 276 return proc->pid;
276} 277}
@@ -283,12 +284,12 @@ GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc)
283 * @param proc pointer to process structure 284 * @param proc pointer to process structure
284 */ 285 */
285void 286void
286GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc) 287GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc)
287{ 288{
288 if (NULL != proc->control_pipe) 289 if (NULL != proc->control_pipe)
289 GNUNET_DISK_file_close(proc->control_pipe); 290 GNUNET_DISK_file_close (proc->control_pipe);
290 291
291 GNUNET_free(proc); 292 GNUNET_free (proc);
292} 293}
293 294
294 295
@@ -301,25 +302,25 @@ GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
301 * @param flags open flags (O_RDONLY, O_WRONLY) 302 * @param flags open flags (O_RDONLY, O_WRONLY)
302 */ 303 */
303static void 304static void
304open_dev_null(int target_fd, int flags) 305open_dev_null (int target_fd, int flags)
305{ 306{
306 int fd; 307 int fd;
307 308
308 fd = open("/dev/null", flags); 309 fd = open ("/dev/null", flags);
309 if (-1 == fd) 310 if (-1 == fd)
310 { 311 {
311 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "open", "/dev/null"); 312 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", "/dev/null");
312 return; 313 return;
313 } 314 }
314 if (fd == target_fd) 315 if (fd == target_fd)
315 return; 316 return;
316 if (-1 == dup2(fd, target_fd)) 317 if (-1 == dup2 (fd, target_fd))
317 { 318 {
318 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "dup2"); 319 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
319 (void)close(fd); 320 (void) close (fd);
320 return; 321 return;
321 } 322 }
322 GNUNET_break(0 == close(fd)); 323 GNUNET_break (0 == close (fd));
323} 324}
324 325
325 326
@@ -341,14 +342,14 @@ open_dev_null(int target_fd, int flags)
341 * @return process ID of the new process, -1 on error 342 * @return process ID of the new process, -1 on error
342 */ 343 */
343static struct GNUNET_OS_Process * 344static struct GNUNET_OS_Process *
344start_process(int pipe_control, 345start_process (int pipe_control,
345 enum GNUNET_OS_InheritStdioFlags std_inheritance, 346 enum GNUNET_OS_InheritStdioFlags std_inheritance,
346 struct GNUNET_DISK_PipeHandle *pipe_stdin, 347 struct GNUNET_DISK_PipeHandle *pipe_stdin,
347 struct GNUNET_DISK_PipeHandle *pipe_stdout, 348 struct GNUNET_DISK_PipeHandle *pipe_stdout,
348 struct GNUNET_DISK_PipeHandle *pipe_stderr, 349 struct GNUNET_DISK_PipeHandle *pipe_stderr,
349 const SOCKTYPE *lsocks, 350 const SOCKTYPE *lsocks,
350 const char *filename, 351 const char *filename,
351 char *const argv[]) 352 char *const argv[])
352{ 353{
353 pid_t ret; 354 pid_t ret;
354 char fds[16]; 355 char fds[16];
@@ -371,223 +372,223 @@ start_process(int pipe_control,
371 int fd_stdin_write; 372 int fd_stdin_write;
372 373
373 if (GNUNET_SYSERR == 374 if (GNUNET_SYSERR ==
374 GNUNET_OS_check_helper_binary(filename, GNUNET_NO, NULL)) 375 GNUNET_OS_check_helper_binary (filename, GNUNET_NO, NULL))
375 return NULL; /* not executable */ 376 return NULL; /* not executable */
376 if (GNUNET_YES == pipe_control) 377 if (GNUNET_YES == pipe_control)
378 {
379 struct GNUNET_DISK_PipeHandle *childpipe;
380 int dup_childpipe_read_fd = -1;
381
382 childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
383 if (NULL == childpipe)
384 return NULL;
385 childpipe_read =
386 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ);
387 childpipe_write =
388 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE);
389 GNUNET_DISK_pipe_close (childpipe);
390 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
391 (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read,
392 &childpipe_read_fd,
393 sizeof(int))) ||
394 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
377 { 395 {
378 struct GNUNET_DISK_PipeHandle *childpipe; 396 if (NULL != childpipe_read)
379 int dup_childpipe_read_fd = -1; 397 GNUNET_DISK_file_close (childpipe_read);
380 398 if (NULL != childpipe_write)
381 childpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); 399 GNUNET_DISK_file_close (childpipe_write);
382 if (NULL == childpipe) 400 if (0 <= dup_childpipe_read_fd)
383 return NULL; 401 close (dup_childpipe_read_fd);
384 childpipe_read = 402 return NULL;
385 GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_READ);
386 childpipe_write =
387 GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_WRITE);
388 GNUNET_DISK_pipe_close(childpipe);
389 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
390 (GNUNET_OK != GNUNET_DISK_internal_file_handle_(childpipe_read,
391 &childpipe_read_fd,
392 sizeof(int))) ||
393 (-1 == (dup_childpipe_read_fd = dup(childpipe_read_fd))))
394 {
395 if (NULL != childpipe_read)
396 GNUNET_DISK_file_close(childpipe_read);
397 if (NULL != childpipe_write)
398 GNUNET_DISK_file_close(childpipe_write);
399 if (0 <= dup_childpipe_read_fd)
400 close(dup_childpipe_read_fd);
401 return NULL;
402 }
403 childpipe_read_fd = dup_childpipe_read_fd;
404 GNUNET_DISK_file_close(childpipe_read);
405 } 403 }
404 childpipe_read_fd = dup_childpipe_read_fd;
405 GNUNET_DISK_file_close (childpipe_read);
406 }
406 else 407 else
407 { 408 {
408 childpipe_write = NULL; 409 childpipe_write = NULL;
409 childpipe_read_fd = -1; 410 childpipe_read_fd = -1;
410 } 411 }
411 if (NULL != pipe_stdin) 412 if (NULL != pipe_stdin)
412 { 413 {
413 GNUNET_assert( 414 GNUNET_assert (
414 GNUNET_OK == 415 GNUNET_OK ==
415 GNUNET_DISK_internal_file_handle_( 416 GNUNET_DISK_internal_file_handle_ (
416 GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), 417 GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
417 &fd_stdin_read, 418 &fd_stdin_read,
418 sizeof(int))); 419 sizeof(int)));
419 GNUNET_assert( 420 GNUNET_assert (
420 GNUNET_OK == 421 GNUNET_OK ==
421 GNUNET_DISK_internal_file_handle_( 422 GNUNET_DISK_internal_file_handle_ (
422 GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_WRITE), 423 GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
423 &fd_stdin_write, 424 &fd_stdin_write,
424 sizeof(int))); 425 sizeof(int)));
425 } 426 }
426 if (NULL != pipe_stdout) 427 if (NULL != pipe_stdout)
427 { 428 {
428 GNUNET_assert( 429 GNUNET_assert (
429 GNUNET_OK == 430 GNUNET_OK ==
430 GNUNET_DISK_internal_file_handle_( 431 GNUNET_DISK_internal_file_handle_ (
431 GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), 432 GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE),
432 &fd_stdout_write, 433 &fd_stdout_write,
433 sizeof(int))); 434 sizeof(int)));
434 GNUNET_assert( 435 GNUNET_assert (
435 GNUNET_OK == 436 GNUNET_OK ==
436 GNUNET_DISK_internal_file_handle_( 437 GNUNET_DISK_internal_file_handle_ (
437 GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_READ), 438 GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
438 &fd_stdout_read, 439 &fd_stdout_read,
439 sizeof(int))); 440 sizeof(int)));
440 } 441 }
441 if (NULL != pipe_stderr) 442 if (NULL != pipe_stderr)
442 { 443 {
443 GNUNET_assert( 444 GNUNET_assert (
444 GNUNET_OK == 445 GNUNET_OK ==
445 GNUNET_DISK_internal_file_handle_( 446 GNUNET_DISK_internal_file_handle_ (
446 GNUNET_DISK_pipe_handle(pipe_stderr, GNUNET_DISK_PIPE_END_READ), 447 GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_READ),
447 &fd_stderr_read, 448 &fd_stderr_read,
448 sizeof(int))); 449 sizeof(int)));
449 GNUNET_assert( 450 GNUNET_assert (
450 GNUNET_OK == 451 GNUNET_OK ==
451 GNUNET_DISK_internal_file_handle_( 452 GNUNET_DISK_internal_file_handle_ (
452 GNUNET_DISK_pipe_handle(pipe_stderr, GNUNET_DISK_PIPE_END_WRITE), 453 GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_WRITE),
453 &fd_stderr_write, 454 &fd_stderr_write,
454 sizeof(int))); 455 sizeof(int)));
455 } 456 }
456 lscp = NULL; 457 lscp = NULL;
457 ls = 0; 458 ls = 0;
458 if (NULL != lsocks) 459 if (NULL != lsocks)
459 { 460 {
460 i = 0; 461 i = 0;
461 while (-1 != (k = lsocks[i++])) 462 while (-1 != (k = lsocks[i++]))
462 GNUNET_array_append(lscp, ls, k); 463 GNUNET_array_append (lscp, ls, k);
463 GNUNET_array_append(lscp, ls, -1); 464 GNUNET_array_append (lscp, ls, -1);
464 } 465 }
465#if DARWIN 466#if DARWIN
466 /* see https://web.archive.org/web/20150924082249/gnunet.org/vfork */ 467 /* see https://web.archive.org/web/20150924082249/gnunet.org/vfork */
467 ret = vfork(); 468 ret = vfork ();
468#else 469#else
469 ret = fork(); 470 ret = fork ();
470#endif 471#endif
471 if (-1 == ret) 472 if (-1 == ret)
472 { 473 {
473 int eno = errno; 474 int eno = errno;
474 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); 475 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
475 GNUNET_array_grow(lscp, ls, 0); 476 GNUNET_array_grow (lscp, ls, 0);
476 if (NULL != childpipe_write) 477 if (NULL != childpipe_write)
477 GNUNET_DISK_file_close(childpipe_write); 478 GNUNET_DISK_file_close (childpipe_write);
478 if (0 <= childpipe_read_fd) 479 if (0 <= childpipe_read_fd)
479 close(childpipe_read_fd); 480 close (childpipe_read_fd);
480 errno = eno; 481 errno = eno;
481 return NULL; 482 return NULL;
482 } 483 }
483 if (0 != ret) 484 if (0 != ret)
485 {
486 unsetenv (GNUNET_OS_CONTROL_PIPE);
487 gnunet_proc = GNUNET_new (struct GNUNET_OS_Process);
488 gnunet_proc->pid = ret;
489 gnunet_proc->control_pipe = childpipe_write;
490 if (GNUNET_YES == pipe_control)
484 { 491 {
485 unsetenv(GNUNET_OS_CONTROL_PIPE); 492 close (childpipe_read_fd);
486 gnunet_proc = GNUNET_new(struct GNUNET_OS_Process);
487 gnunet_proc->pid = ret;
488 gnunet_proc->control_pipe = childpipe_write;
489 if (GNUNET_YES == pipe_control)
490 {
491 close(childpipe_read_fd);
492 }
493 GNUNET_array_grow(lscp, ls, 0);
494 return gnunet_proc;
495 } 493 }
494 GNUNET_array_grow (lscp, ls, 0);
495 return gnunet_proc;
496 }
496 if (0 <= childpipe_read_fd) 497 if (0 <= childpipe_read_fd)
497 { 498 {
498 char fdbuf[100]; 499 char fdbuf[100];
499#ifndef DARWIN 500#ifndef DARWIN
500 /* due to vfork, we must NOT free memory on DARWIN! */ 501 /* due to vfork, we must NOT free memory on DARWIN! */
501 GNUNET_DISK_file_close(childpipe_write); 502 GNUNET_DISK_file_close (childpipe_write);
502#endif 503#endif
503 snprintf(fdbuf, 100, "%x", childpipe_read_fd); 504 snprintf (fdbuf, 100, "%x", childpipe_read_fd);
504 setenv(GNUNET_OS_CONTROL_PIPE, fdbuf, 1); 505 setenv (GNUNET_OS_CONTROL_PIPE, fdbuf, 1);
505 } 506 }
506 else 507 else
507 unsetenv(GNUNET_OS_CONTROL_PIPE); 508 unsetenv (GNUNET_OS_CONTROL_PIPE);
508 if (NULL != pipe_stdin) 509 if (NULL != pipe_stdin)
509 { 510 {
510 GNUNET_break(0 == close(fd_stdin_write)); 511 GNUNET_break (0 == close (fd_stdin_write));
511 if (-1 == dup2(fd_stdin_read, 0)) 512 if (-1 == dup2 (fd_stdin_read, 0))
512 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); 513 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
513 GNUNET_break(0 == close(fd_stdin_read)); 514 GNUNET_break (0 == close (fd_stdin_read));
514 } 515 }
515 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN)) 516 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN))
516 { 517 {
517 GNUNET_break(0 == close(0)); 518 GNUNET_break (0 == close (0));
518 open_dev_null(0, O_RDONLY); 519 open_dev_null (0, O_RDONLY);
519 } 520 }
520 if (NULL != pipe_stdout) 521 if (NULL != pipe_stdout)
521 { 522 {
522 GNUNET_break(0 == close(fd_stdout_read)); 523 GNUNET_break (0 == close (fd_stdout_read));
523 if (-1 == dup2(fd_stdout_write, 1)) 524 if (-1 == dup2 (fd_stdout_write, 1))
524 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); 525 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
525 GNUNET_break(0 == close(fd_stdout_write)); 526 GNUNET_break (0 == close (fd_stdout_write));
526 } 527 }
527 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT)) 528 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT))
528 { 529 {
529 GNUNET_break(0 == close(1)); 530 GNUNET_break (0 == close (1));
530 open_dev_null(1, O_WRONLY); 531 open_dev_null (1, O_WRONLY);
531 } 532 }
532 if (NULL != pipe_stderr) 533 if (NULL != pipe_stderr)
533 { 534 {
534 GNUNET_break(0 == close(fd_stderr_read)); 535 GNUNET_break (0 == close (fd_stderr_read));
535 if (-1 == dup2(fd_stderr_write, 2)) 536 if (-1 == dup2 (fd_stderr_write, 2))
536 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); 537 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
537 GNUNET_break(0 == close(fd_stderr_write)); 538 GNUNET_break (0 == close (fd_stderr_write));
538 } 539 }
539 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR)) 540 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR))
540 { 541 {
541 GNUNET_break(0 == close(2)); 542 GNUNET_break (0 == close (2));
542 open_dev_null(2, O_WRONLY); 543 open_dev_null (2, O_WRONLY);
543 } 544 }
544 if (NULL != lscp) 545 if (NULL != lscp)
546 {
547 /* read systemd documentation... */
548 i = 0;
549 tgt = 3;
550 while (-1 != lscp[i])
545 { 551 {
546 /* read systemd documentation... */ 552 j = i + 1;
547 i = 0; 553 while (-1 != lscp[j])
548 tgt = 3; 554 {
549 while (-1 != lscp[i]) 555 if (lscp[j] == tgt)
550 { 556 {
551 j = i + 1; 557 /* dup away */
552 while (-1 != lscp[j]) 558 k = dup (lscp[j]);
553 { 559 GNUNET_assert (-1 != k);
554 if (lscp[j] == tgt) 560 GNUNET_assert (0 == close (lscp[j]));
555 { 561 lscp[j] = k;
556 /* dup away */ 562 break;
557 k = dup(lscp[j]);
558 GNUNET_assert(-1 != k);
559 GNUNET_assert(0 == close(lscp[j]));
560 lscp[j] = k;
561 break;
562 }
563 j++;
564 }
565 if (lscp[i] != tgt)
566 {
567 /* Bury any existing FD, no matter what; they should all be closed
568 * on exec anyway and the important onces have been dup'ed away */
569 (void)close(tgt);
570 GNUNET_assert(-1 != dup2(lscp[i], tgt));
571 }
572 /* unset close-on-exec flag */
573 flags = fcntl(tgt, F_GETFD);
574 GNUNET_assert(flags >= 0);
575 flags &= ~FD_CLOEXEC;
576 fflush(stderr);
577 (void)fcntl(tgt, F_SETFD, flags);
578 tgt++;
579 i++;
580 } 563 }
581 GNUNET_snprintf(fds, sizeof(fds), "%u", i); 564 j++;
582 setenv("LISTEN_FDS", fds, 1); 565 }
566 if (lscp[i] != tgt)
567 {
568 /* Bury any existing FD, no matter what; they should all be closed
569 * on exec anyway and the important onces have been dup'ed away */
570 (void) close (tgt);
571 GNUNET_assert (-1 != dup2 (lscp[i], tgt));
572 }
573 /* unset close-on-exec flag */
574 flags = fcntl (tgt, F_GETFD);
575 GNUNET_assert (flags >= 0);
576 flags &= ~FD_CLOEXEC;
577 fflush (stderr);
578 (void) fcntl (tgt, F_SETFD, flags);
579 tgt++;
580 i++;
583 } 581 }
582 GNUNET_snprintf (fds, sizeof(fds), "%u", i);
583 setenv ("LISTEN_FDS", fds, 1);
584 }
584#ifndef DARWIN 585#ifndef DARWIN
585 /* due to vfork, we must NOT free memory on DARWIN! */ 586 /* due to vfork, we must NOT free memory on DARWIN! */
586 GNUNET_array_grow(lscp, ls, 0); 587 GNUNET_array_grow (lscp, ls, 0);
587#endif 588#endif
588 execvp(filename, argv); 589 execvp (filename, argv);
589 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 590 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
590 _exit(1); 591 _exit (1);
591} 592}
592 593
593 594
@@ -604,22 +605,22 @@ start_process(int pipe_control,
604 * @return pointer to process structure of the new process, NULL on error 605 * @return pointer to process structure of the new process, NULL on error
605 */ 606 */
606struct GNUNET_OS_Process * 607struct GNUNET_OS_Process *
607GNUNET_OS_start_process_vap(int pipe_control, 608GNUNET_OS_start_process_vap (int pipe_control,
608 enum GNUNET_OS_InheritStdioFlags std_inheritance, 609 enum GNUNET_OS_InheritStdioFlags std_inheritance,
609 struct GNUNET_DISK_PipeHandle *pipe_stdin, 610 struct GNUNET_DISK_PipeHandle *pipe_stdin,
610 struct GNUNET_DISK_PipeHandle *pipe_stdout, 611 struct GNUNET_DISK_PipeHandle *pipe_stdout,
611 struct GNUNET_DISK_PipeHandle *pipe_stderr, 612 struct GNUNET_DISK_PipeHandle *pipe_stderr,
612 const char *filename, 613 const char *filename,
613 char *const argv[]) 614 char *const argv[])
614{ 615{
615 return start_process(pipe_control, 616 return start_process (pipe_control,
616 std_inheritance, 617 std_inheritance,
617 pipe_stdin, 618 pipe_stdin,
618 pipe_stdout, 619 pipe_stdout,
619 pipe_stderr, 620 pipe_stderr,
620 NULL, 621 NULL,
621 filename, 622 filename,
622 argv); 623 argv);
623} 624}
624 625
625 626
@@ -636,13 +637,13 @@ GNUNET_OS_start_process_vap(int pipe_control,
636 * @return pointer to process structure of the new process, NULL on error 637 * @return pointer to process structure of the new process, NULL on error
637 */ 638 */
638struct GNUNET_OS_Process * 639struct GNUNET_OS_Process *
639GNUNET_OS_start_process_va(int pipe_control, 640GNUNET_OS_start_process_va (int pipe_control,
640 enum GNUNET_OS_InheritStdioFlags std_inheritance, 641 enum GNUNET_OS_InheritStdioFlags std_inheritance,
641 struct GNUNET_DISK_PipeHandle *pipe_stdin, 642 struct GNUNET_DISK_PipeHandle *pipe_stdin,
642 struct GNUNET_DISK_PipeHandle *pipe_stdout, 643 struct GNUNET_DISK_PipeHandle *pipe_stdout,
643 struct GNUNET_DISK_PipeHandle *pipe_stderr, 644 struct GNUNET_DISK_PipeHandle *pipe_stderr,
644 const char *filename, 645 const char *filename,
645 va_list va) 646 va_list va)
646{ 647{
647 struct GNUNET_OS_Process *ret; 648 struct GNUNET_OS_Process *ret;
648 va_list ap; 649 va_list ap;
@@ -650,24 +651,24 @@ GNUNET_OS_start_process_va(int pipe_control,
650 int argc; 651 int argc;
651 652
652 argc = 0; 653 argc = 0;
653 va_copy(ap, va); 654 va_copy (ap, va);
654 while (NULL != va_arg(ap, char *)) 655 while (NULL != va_arg (ap, char *))
655 argc++; 656 argc++;
656 va_end(ap); 657 va_end (ap);
657 argv = GNUNET_malloc(sizeof(char *) * (argc + 1)); 658 argv = GNUNET_malloc (sizeof(char *) * (argc + 1));
658 argc = 0; 659 argc = 0;
659 va_copy(ap, va); 660 va_copy (ap, va);
660 while (NULL != (argv[argc] = va_arg(ap, char *))) 661 while (NULL != (argv[argc] = va_arg (ap, char *)))
661 argc++; 662 argc++;
662 va_end(ap); 663 va_end (ap);
663 ret = GNUNET_OS_start_process_vap(pipe_control, 664 ret = GNUNET_OS_start_process_vap (pipe_control,
664 std_inheritance, 665 std_inheritance,
665 pipe_stdin, 666 pipe_stdin,
666 pipe_stdout, 667 pipe_stdout,
667 pipe_stderr, 668 pipe_stderr,
668 filename, 669 filename,
669 argv); 670 argv);
670 GNUNET_free(argv); 671 GNUNET_free (argv);
671 return ret; 672 return ret;
672} 673}
673 674
@@ -684,26 +685,26 @@ GNUNET_OS_start_process_va(int pipe_control,
684 * @return pointer to process structure of the new process, NULL on error 685 * @return pointer to process structure of the new process, NULL on error
685 */ 686 */
686struct GNUNET_OS_Process * 687struct GNUNET_OS_Process *
687GNUNET_OS_start_process(int pipe_control, 688GNUNET_OS_start_process (int pipe_control,
688 enum GNUNET_OS_InheritStdioFlags std_inheritance, 689 enum GNUNET_OS_InheritStdioFlags std_inheritance,
689 struct GNUNET_DISK_PipeHandle *pipe_stdin, 690 struct GNUNET_DISK_PipeHandle *pipe_stdin,
690 struct GNUNET_DISK_PipeHandle *pipe_stdout, 691 struct GNUNET_DISK_PipeHandle *pipe_stdout,
691 struct GNUNET_DISK_PipeHandle *pipe_stderr, 692 struct GNUNET_DISK_PipeHandle *pipe_stderr,
692 const char *filename, 693 const char *filename,
693 ...) 694 ...)
694{ 695{
695 struct GNUNET_OS_Process *ret; 696 struct GNUNET_OS_Process *ret;
696 va_list ap; 697 va_list ap;
697 698
698 va_start(ap, filename); 699 va_start (ap, filename);
699 ret = GNUNET_OS_start_process_va(pipe_control, 700 ret = GNUNET_OS_start_process_va (pipe_control,
700 std_inheritance, 701 std_inheritance,
701 pipe_stdin, 702 pipe_stdin,
702 pipe_stdout, 703 pipe_stdout,
703 pipe_stderr, 704 pipe_stderr,
704 filename, 705 filename,
705 ap); 706 ap);
706 va_end(ap); 707 va_end (ap);
707 return ret; 708 return ret;
708} 709}
709 710
@@ -723,20 +724,20 @@ GNUNET_OS_start_process(int pipe_control,
723 * @return process ID of the new process, -1 on error 724 * @return process ID of the new process, -1 on error
724 */ 725 */
725struct GNUNET_OS_Process * 726struct GNUNET_OS_Process *
726GNUNET_OS_start_process_v(int pipe_control, 727GNUNET_OS_start_process_v (int pipe_control,
727 enum GNUNET_OS_InheritStdioFlags std_inheritance, 728 enum GNUNET_OS_InheritStdioFlags std_inheritance,
728 const SOCKTYPE *lsocks, 729 const SOCKTYPE *lsocks,
729 const char *filename, 730 const char *filename,
730 char *const argv[]) 731 char *const argv[])
731{ 732{
732 return start_process(pipe_control, 733 return start_process (pipe_control,
733 std_inheritance, 734 std_inheritance,
734 NULL, 735 NULL,
735 NULL, 736 NULL,
736 NULL, 737 NULL,
737 lsocks, 738 lsocks,
738 filename, 739 filename,
739 argv); 740 argv);
740} 741}
741 742
742 743
@@ -759,11 +760,11 @@ GNUNET_OS_start_process_v(int pipe_control,
759 * @return pointer to process structure of the new process, NULL on error 760 * @return pointer to process structure of the new process, NULL on error
760 */ 761 */
761struct GNUNET_OS_Process * 762struct GNUNET_OS_Process *
762GNUNET_OS_start_process_s(int pipe_control, 763GNUNET_OS_start_process_s (int pipe_control,
763 unsigned int std_inheritance, 764 unsigned int std_inheritance,
764 const SOCKTYPE *lsocks, 765 const SOCKTYPE *lsocks,
765 const char *filename, 766 const char *filename,
766 ...) 767 ...)
767{ 768{
768 va_list ap; 769 va_list ap;
769 char **argv; 770 char **argv;
@@ -780,103 +781,103 @@ GNUNET_OS_start_process_s(int pipe_control,
780 size_t len; 781 size_t len;
781 782
782 argv_size = 1; 783 argv_size = 1;
783 va_start(ap, filename); 784 va_start (ap, filename);
784 arg = filename; 785 arg = filename;
785 last = NULL; 786 last = NULL;
786 do 787 do
788 {
789 rpos = arg;
790 quote_on = 0;
791 while ('\0' != *rpos)
787 { 792 {
788 rpos = arg; 793 if ('"' == *rpos)
789 quote_on = 0; 794 {
790 while ('\0' != *rpos) 795 if (1 == quote_on)
791 { 796 quote_on = 0;
792 if ('"' == *rpos) 797 else
793 { 798 quote_on = 1;
794 if (1 == quote_on) 799 }
795 quote_on = 0; 800 if ((' ' == *rpos) && (0 == quote_on))
796 else 801 {
797 quote_on = 1; 802 if (NULL != last)
798 } 803 argv_size++;
799 if ((' ' == *rpos) && (0 == quote_on)) 804 last = NULL;
800 { 805 rpos++;
801 if (NULL != last) 806 while (' ' == *rpos)
802 argv_size++; 807 rpos++;
803 last = NULL; 808 }
804 rpos++; 809 if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=?
805 while (' ' == *rpos) 810 last = rpos;
806 rpos++; 811 if ('\0' != *rpos)
807 } 812 rpos++;
808 if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=?
809 last = rpos;
810 if ('\0' != *rpos)
811 rpos++;
812 }
813 if (NULL != last)
814 argv_size++;
815 } 813 }
816 while (NULL != (arg = (va_arg(ap, const char *)))); 814 if (NULL != last)
817 va_end(ap); 815 argv_size++;
816 }
817 while (NULL != (arg = (va_arg (ap, const char *))));
818 va_end (ap);
818 819
819 argv = GNUNET_malloc(argv_size * sizeof(char *)); 820 argv = GNUNET_malloc (argv_size * sizeof(char *));
820 argv_size = 0; 821 argv_size = 0;
821 va_start(ap, filename); 822 va_start (ap, filename);
822 arg = filename; 823 arg = filename;
823 last = NULL; 824 last = NULL;
824 do 825 do
826 {
827 cp = GNUNET_strdup (arg);
828 quote_on = 0;
829 pos = cp;
830 while ('\0' != *pos)
825 { 831 {
826 cp = GNUNET_strdup(arg); 832 if ('"' == *pos)
827 quote_on = 0; 833 {
828 pos = cp; 834 if (1 == quote_on)
829 while ('\0' != *pos) 835 quote_on = 0;
830 { 836 else
831 if ('"' == *pos) 837 quote_on = 1;
832 { 838 }
833 if (1 == quote_on) 839 if ((' ' == *pos) && (0 == quote_on))
834 quote_on = 0; 840 {
835 else 841 *pos = '\0';
836 quote_on = 1; 842 if (NULL != last)
837 } 843 argv[argv_size++] = GNUNET_strdup (last);
838 if ((' ' == *pos) && (0 == quote_on)) 844 last = NULL;
839 { 845 pos++;
840 *pos = '\0'; 846 while (' ' == *pos)
841 if (NULL != last) 847 pos++;
842 argv[argv_size++] = GNUNET_strdup(last); 848 }
843 last = NULL; 849 if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
844 pos++; 850 last = pos;
845 while (' ' == *pos) 851 if ('\0' != *pos)
846 pos++; 852 pos++;
847 }
848 if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
849 last = pos;
850 if ('\0' != *pos)
851 pos++;
852 }
853 if (NULL != last)
854 argv[argv_size++] = GNUNET_strdup(last);
855 last = NULL;
856 GNUNET_free(cp);
857 } 853 }
858 while (NULL != (arg = (va_arg(ap, const char *)))); 854 if (NULL != last)
859 va_end(ap); 855 argv[argv_size++] = GNUNET_strdup (last);
856 last = NULL;
857 GNUNET_free (cp);
858 }
859 while (NULL != (arg = (va_arg (ap, const char *))));
860 va_end (ap);
860 argv[argv_size] = NULL; 861 argv[argv_size] = NULL;
861 862
862 for (i = 0; i < argv_size; i++) 863 for (i = 0; i < argv_size; i++)
864 {
865 len = strlen (argv[i]);
866 if ((argv[i][0] == '"') && (argv[i][len - 1] == '"'))
863 { 867 {
864 len = strlen(argv[i]); 868 memmove (&argv[i][0], &argv[i][1], len - 2);
865 if ((argv[i][0] == '"') && (argv[i][len - 1] == '"')) 869 argv[i][len - 2] = '\0';
866 {
867 memmove(&argv[i][0], &argv[i][1], len - 2);
868 argv[i][len - 2] = '\0';
869 }
870 } 870 }
871 }
871 binary_path = argv[0]; 872 binary_path = argv[0];
872 proc = GNUNET_OS_start_process_v(pipe_control, 873 proc = GNUNET_OS_start_process_v (pipe_control,
873 std_inheritance, 874 std_inheritance,
874 lsocks, 875 lsocks,
875 binary_path, 876 binary_path,
876 argv); 877 argv);
877 while (argv_size > 0) 878 while (argv_size > 0)
878 GNUNET_free(argv[--argv_size]); 879 GNUNET_free (argv[--argv_size]);
879 GNUNET_free(argv); 880 GNUNET_free (argv);
880 return proc; 881 return proc;
881} 882}
882 883
@@ -892,59 +893,59 @@ GNUNET_OS_start_process_s(int pipe_control,
892 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 893 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
893 */ 894 */
894static int 895static int
895process_status(struct GNUNET_OS_Process *proc, 896process_status (struct GNUNET_OS_Process *proc,
896 enum GNUNET_OS_ProcessStatusType *type, 897 enum GNUNET_OS_ProcessStatusType *type,
897 unsigned long *code, 898 unsigned long *code,
898 int options) 899 int options)
899{ 900{
900 int status; 901 int status;
901 int ret; 902 int ret;
902 903
903 GNUNET_assert(0 != proc); 904 GNUNET_assert (0 != proc);
904 ret = waitpid(proc->pid, &status, options); 905 ret = waitpid (proc->pid, &status, options);
905 if (ret < 0) 906 if (ret < 0)
906 { 907 {
907 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); 908 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
908 return GNUNET_SYSERR; 909 return GNUNET_SYSERR;
909 } 910 }
910 if (0 == ret) 911 if (0 == ret)
911 { 912 {
912 *type = GNUNET_OS_PROCESS_RUNNING; 913 *type = GNUNET_OS_PROCESS_RUNNING;
913 *code = 0; 914 *code = 0;
914 return GNUNET_NO; 915 return GNUNET_NO;
915 } 916 }
916 if (proc->pid != ret) 917 if (proc->pid != ret)
917 { 918 {
918 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); 919 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
919 return GNUNET_SYSERR; 920 return GNUNET_SYSERR;
920 } 921 }
921 if (WIFEXITED(status)) 922 if (WIFEXITED (status))
922 { 923 {
923 *type = GNUNET_OS_PROCESS_EXITED; 924 *type = GNUNET_OS_PROCESS_EXITED;
924 *code = WEXITSTATUS(status); 925 *code = WEXITSTATUS (status);
925 } 926 }
926 else if (WIFSIGNALED(status)) 927 else if (WIFSIGNALED (status))
927 { 928 {
928 *type = GNUNET_OS_PROCESS_SIGNALED; 929 *type = GNUNET_OS_PROCESS_SIGNALED;
929 *code = WTERMSIG(status); 930 *code = WTERMSIG (status);
930 } 931 }
931 else if (WIFSTOPPED(status)) 932 else if (WIFSTOPPED (status))
932 { 933 {
933 *type = GNUNET_OS_PROCESS_SIGNALED; 934 *type = GNUNET_OS_PROCESS_SIGNALED;
934 *code = WSTOPSIG(status); 935 *code = WSTOPSIG (status);
935 } 936 }
936#ifdef WIFCONTINUED 937#ifdef WIFCONTINUED
937 else if (WIFCONTINUED(status)) 938 else if (WIFCONTINUED (status))
938 { 939 {
939 *type = GNUNET_OS_PROCESS_RUNNING; 940 *type = GNUNET_OS_PROCESS_RUNNING;
940 *code = 0; 941 *code = 0;
941 } 942 }
942#endif 943#endif
943 else 944 else
944 { 945 {
945 *type = GNUNET_OS_PROCESS_UNKNOWN; 946 *type = GNUNET_OS_PROCESS_UNKNOWN;
946 *code = 0; 947 *code = 0;
947 } 948 }
948 949
949 return GNUNET_OK; 950 return GNUNET_OK;
950} 951}
@@ -960,11 +961,11 @@ process_status(struct GNUNET_OS_Process *proc,
960 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 961 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
961 */ 962 */
962int 963int
963GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, 964GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
964 enum GNUNET_OS_ProcessStatusType *type, 965 enum GNUNET_OS_ProcessStatusType *type,
965 unsigned long *code) 966 unsigned long *code)
966{ 967{
967 return process_status(proc, type, code, WNOHANG); 968 return process_status (proc, type, code, WNOHANG);
968} 969}
969 970
970 971
@@ -978,11 +979,11 @@ GNUNET_OS_process_status(struct GNUNET_OS_Process *proc,
978 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 979 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
979 */ 980 */
980int 981int
981GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, 982GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
982 enum GNUNET_OS_ProcessStatusType *type, 983 enum GNUNET_OS_ProcessStatusType *type,
983 unsigned long *code) 984 unsigned long *code)
984{ 985{
985 return process_status(proc, type, code, 0); 986 return process_status (proc, type, code, 0);
986} 987}
987 988
988 989
@@ -997,18 +998,18 @@ GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc,
997 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 998 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
998 */ 999 */
999int 1000int
1000GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) 1001GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1001{ 1002{
1002 pid_t pid = proc->pid; 1003 pid_t pid = proc->pid;
1003 pid_t ret; 1004 pid_t ret;
1004 1005
1005 while ((pid != (ret = waitpid(pid, NULL, 0))) && (EINTR == errno)) 1006 while ((pid != (ret = waitpid (pid, NULL, 0))) && (EINTR == errno))
1006 ; 1007 ;
1007 if (pid != ret) 1008 if (pid != ret)
1008 { 1009 {
1009 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); 1010 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1010 return GNUNET_SYSERR; 1011 return GNUNET_SYSERR;
1011 } 1012 }
1012 return GNUNET_OK; 1013 return GNUNET_OK;
1013} 1014}
1014 1015
@@ -1016,7 +1017,8 @@ GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
1016/** 1017/**
1017 * Handle to a command. 1018 * Handle to a command.
1018 */ 1019 */
1019struct GNUNET_OS_CommandHandle { 1020struct GNUNET_OS_CommandHandle
1021{
1020 /** 1022 /**
1021 * Process handle. 1023 * Process handle.
1022 */ 1024 */
@@ -1072,18 +1074,18 @@ struct GNUNET_OS_CommandHandle {
1072 * @param cmd handle to the process 1074 * @param cmd handle to the process
1073 */ 1075 */
1074void 1076void
1075GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd) 1077GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
1076{ 1078{
1077 if (NULL != cmd->proc) 1079 if (NULL != cmd->proc)
1078 { 1080 {
1079 GNUNET_assert(NULL != cmd->rtask); 1081 GNUNET_assert (NULL != cmd->rtask);
1080 GNUNET_SCHEDULER_cancel(cmd->rtask); 1082 GNUNET_SCHEDULER_cancel (cmd->rtask);
1081 } 1083 }
1082 (void)GNUNET_OS_process_kill(cmd->eip, SIGKILL); 1084 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
1083 GNUNET_break(GNUNET_OK == GNUNET_OS_process_wait(cmd->eip)); 1085 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip));
1084 GNUNET_OS_process_destroy(cmd->eip); 1086 GNUNET_OS_process_destroy (cmd->eip);
1085 GNUNET_DISK_pipe_close(cmd->opipe); 1087 GNUNET_DISK_pipe_close (cmd->opipe);
1086 GNUNET_free(cmd); 1088 GNUNET_free (cmd);
1087} 1089}
1088 1090
1089 1091
@@ -1093,7 +1095,7 @@ GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
1093 * @param cls the `struct GNUNET_OS_CommandHandle *` 1095 * @param cls the `struct GNUNET_OS_CommandHandle *`
1094 */ 1096 */
1095static void 1097static void
1096cmd_read(void *cls) 1098cmd_read (void *cls)
1097{ 1099{
1098 struct GNUNET_OS_CommandHandle *cmd = cls; 1100 struct GNUNET_OS_CommandHandle *cmd = cls;
1099 const struct GNUNET_SCHEDULER_TaskContext *tc; 1101 const struct GNUNET_SCHEDULER_TaskContext *tc;
@@ -1102,46 +1104,46 @@ cmd_read(void *cls)
1102 ssize_t ret; 1104 ssize_t ret;
1103 1105
1104 cmd->rtask = NULL; 1106 cmd->rtask = NULL;
1105 tc = GNUNET_SCHEDULER_get_task_context(); 1107 tc = GNUNET_SCHEDULER_get_task_context ();
1106 if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset(tc->read_ready, cmd->r)) 1108 if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r))
1107 { 1109 {
1108 /* timeout */ 1110 /* timeout */
1109 proc = cmd->proc; 1111 proc = cmd->proc;
1110 cmd->proc = NULL; 1112 cmd->proc = NULL;
1111 proc(cmd->proc_cls, NULL); 1113 proc (cmd->proc_cls, NULL);
1112 return; 1114 return;
1113 } 1115 }
1114 ret = GNUNET_DISK_file_read(cmd->r, 1116 ret = GNUNET_DISK_file_read (cmd->r,
1115 &cmd->buf[cmd->off], 1117 &cmd->buf[cmd->off],
1116 sizeof(cmd->buf) - cmd->off); 1118 sizeof(cmd->buf) - cmd->off);
1117 if (ret <= 0) 1119 if (ret <= 0)
1120 {
1121 if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf)))
1118 { 1122 {
1119 if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf))) 1123 cmd->buf[cmd->off] = '\0';
1120 { 1124 cmd->proc (cmd->proc_cls, cmd->buf);
1121 cmd->buf[cmd->off] = '\0';
1122 cmd->proc(cmd->proc_cls, cmd->buf);
1123 }
1124 proc = cmd->proc;
1125 cmd->proc = NULL;
1126 proc(cmd->proc_cls, NULL);
1127 return;
1128 } 1125 }
1129 end = memchr(&cmd->buf[cmd->off], '\n', ret); 1126 proc = cmd->proc;
1127 cmd->proc = NULL;
1128 proc (cmd->proc_cls, NULL);
1129 return;
1130 }
1131 end = memchr (&cmd->buf[cmd->off], '\n', ret);
1130 cmd->off += ret; 1132 cmd->off += ret;
1131 while (NULL != end) 1133 while (NULL != end)
1132 { 1134 {
1133 *end = '\0'; 1135 *end = '\0';
1134 cmd->proc(cmd->proc_cls, cmd->buf); 1136 cmd->proc (cmd->proc_cls, cmd->buf);
1135 memmove(cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf)); 1137 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
1136 cmd->off -= (end + 1 - cmd->buf); 1138 cmd->off -= (end + 1 - cmd->buf);
1137 end = memchr(cmd->buf, '\n', cmd->off); 1139 end = memchr (cmd->buf, '\n', cmd->off);
1138 } 1140 }
1139 cmd->rtask = 1141 cmd->rtask =
1140 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_absolute_get_remaining( 1142 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (
1141 cmd->timeout), 1143 cmd->timeout),
1142 cmd->r, 1144 cmd->r,
1143 &cmd_read, 1145 &cmd_read,
1144 cmd); 1146 cmd);
1145} 1147}
1146 1148
1147 1149
@@ -1157,39 +1159,39 @@ cmd_read(void *cls)
1157 * @return NULL on error 1159 * @return NULL on error
1158 */ 1160 */
1159struct GNUNET_OS_CommandHandle * 1161struct GNUNET_OS_CommandHandle *
1160GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, 1162GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
1161 void *proc_cls, 1163 void *proc_cls,
1162 struct GNUNET_TIME_Relative timeout, 1164 struct GNUNET_TIME_Relative timeout,
1163 const char *binary, 1165 const char *binary,
1164 ...) 1166 ...)
1165{ 1167{
1166 struct GNUNET_OS_CommandHandle *cmd; 1168 struct GNUNET_OS_CommandHandle *cmd;
1167 struct GNUNET_OS_Process *eip; 1169 struct GNUNET_OS_Process *eip;
1168 struct GNUNET_DISK_PipeHandle *opipe; 1170 struct GNUNET_DISK_PipeHandle *opipe;
1169 va_list ap; 1171 va_list ap;
1170 1172
1171 opipe = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); 1173 opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
1172 if (NULL == opipe) 1174 if (NULL == opipe)
1173 return NULL; 1175 return NULL;
1174 va_start(ap, binary); 1176 va_start (ap, binary);
1175 /* redirect stdout, don't inherit stderr/stdin */ 1177 /* redirect stdout, don't inherit stderr/stdin */
1176 eip = 1178 eip =
1177 GNUNET_OS_start_process_va(GNUNET_NO, 0, NULL, opipe, NULL, binary, ap); 1179 GNUNET_OS_start_process_va (GNUNET_NO, 0, NULL, opipe, NULL, binary, ap);
1178 va_end(ap); 1180 va_end (ap);
1179 if (NULL == eip) 1181 if (NULL == eip)
1180 { 1182 {
1181 GNUNET_DISK_pipe_close(opipe); 1183 GNUNET_DISK_pipe_close (opipe);
1182 return NULL; 1184 return NULL;
1183 } 1185 }
1184 GNUNET_DISK_pipe_close_end(opipe, GNUNET_DISK_PIPE_END_WRITE); 1186 GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE);
1185 cmd = GNUNET_new(struct GNUNET_OS_CommandHandle); 1187 cmd = GNUNET_new (struct GNUNET_OS_CommandHandle);
1186 cmd->timeout = GNUNET_TIME_relative_to_absolute(timeout); 1188 cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1187 cmd->eip = eip; 1189 cmd->eip = eip;
1188 cmd->opipe = opipe; 1190 cmd->opipe = opipe;
1189 cmd->proc = proc; 1191 cmd->proc = proc;
1190 cmd->proc_cls = proc_cls; 1192 cmd->proc_cls = proc_cls;
1191 cmd->r = GNUNET_DISK_pipe_handle(opipe, GNUNET_DISK_PIPE_END_READ); 1193 cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ);
1192 cmd->rtask = GNUNET_SCHEDULER_add_read_file(timeout, cmd->r, &cmd_read, cmd); 1194 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd);
1193 return cmd; 1195 return cmd;
1194} 1196}
1195 1197