aboutsummaryrefslogtreecommitdiff
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.c933
1 files changed, 472 insertions, 461 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index f2e3f3c38..bccde8d46 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -53,44 +53,42 @@ static struct GNUNET_OS_Process current_process;
53 */ 53 */
54static void 54static void
55parent_control_handler (void *cls, 55parent_control_handler (void *cls,
56 const struct 56 const struct GNUNET_SCHEDULER_TaskContext *tc)
57 GNUNET_SCHEDULER_TaskContext * tc)
58{ 57{
59 struct GNUNET_DISK_FileHandle *control_pipe = (struct GNUNET_DISK_FileHandle *) cls; 58 struct GNUNET_DISK_FileHandle *control_pipe =
59 (struct GNUNET_DISK_FileHandle *) cls;
60 int sig; 60 int sig;
61 61
62#if DEBUG_OS 62#if DEBUG_OS
63 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 63 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
64 "`%s' invoked because of %d\n", 64 "`%s' invoked because of %d\n", __FUNCTION__, tc->reason);
65 __FUNCTION__,
66 tc->reason);
67#endif 65#endif
68 if (tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 66 if (tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN |
67 GNUNET_SCHEDULER_REASON_TIMEOUT |
68 GNUNET_SCHEDULER_REASON_PREREQ_DONE))
69 {
70 GNUNET_DISK_npipe_close (control_pipe);
71 }
72 else
73 {
74 if (GNUNET_DISK_file_read (control_pipe,
75 &sig, sizeof (sig)) != sizeof (sig))
69 { 76 {
77 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
70 GNUNET_DISK_npipe_close (control_pipe); 78 GNUNET_DISK_npipe_close (control_pipe);
71 } 79 }
72 else 80 else
73 { 81 {
74 if (GNUNET_DISK_file_read (control_pipe,
75 &sig,
76 sizeof (sig)) != sizeof (sig))
77 {
78 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
79 "GNUNET_DISK_file_read");
80 GNUNET_DISK_npipe_close (control_pipe);
81 }
82 else
83 {
84#if DEBUG_OS 82#if DEBUG_OS
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 83 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Got control code %d from parent\n", sig); 84 "Got control code %d from parent\n", sig);
87#endif 85#endif
88 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 86 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
89 control_pipe, 87 control_pipe,
90 &parent_control_handler, control_pipe); 88 &parent_control_handler, control_pipe);
91 raise (sig); 89 raise (sig);
92 }
93 } 90 }
91 }
94} 92}
95 93
96 94
@@ -100,39 +98,36 @@ parent_control_handler (void *cls,
100void 98void
101GNUNET_OS_install_parent_control_handler (void *cls, 99GNUNET_OS_install_parent_control_handler (void *cls,
102 const struct 100 const struct
103 GNUNET_SCHEDULER_TaskContext * tc) 101 GNUNET_SCHEDULER_TaskContext *tc)
104{ 102{
105 const char *env_buf; 103 const char *env_buf;
106 struct GNUNET_DISK_FileHandle *control_pipe; 104 struct GNUNET_DISK_FileHandle *control_pipe;
107 105
108 env_buf = getenv (GNUNET_OS_CONTROL_PIPE); 106 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
109 if ( (env_buf == NULL) || (strlen (env_buf) <= 0) ) 107 if ((env_buf == NULL) || (strlen (env_buf) <= 0))
110 { 108 {
111 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 109 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
112 _("Not installing a handler because $%s=%s\n"), 110 _("Not installing a handler because $%s=%s\n"),
113 GNUNET_OS_CONTROL_PIPE, 111 GNUNET_OS_CONTROL_PIPE, env_buf);
114 env_buf); 112 return;
115 return; 113 }
116 }
117 control_pipe = GNUNET_DISK_npipe_open (env_buf, 114 control_pipe = GNUNET_DISK_npipe_open (env_buf,
118 GNUNET_DISK_OPEN_READ, 115 GNUNET_DISK_OPEN_READ,
119 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); 116 GNUNET_DISK_PERM_USER_READ |
117 GNUNET_DISK_PERM_USER_WRITE);
120 if (control_pipe == NULL) 118 if (control_pipe == NULL)
121 { 119 {
122 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 120 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "open", env_buf);
123 "open", 121 return;
124 env_buf); 122 }
125 return;
126 }
127#if DEBUG_OS 123#if DEBUG_OS
128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
129 "Adding parent control handler pipe `%s' to the scheduler\n", 125 "Adding parent control handler pipe `%s' to the scheduler\n",
130 env_buf); 126 env_buf);
131#endif 127#endif
132 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 128 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
133 control_pipe, 129 control_pipe,
134 &parent_control_handler, 130 &parent_control_handler, control_pipe);
135 control_pipe);
136} 131}
137 132
138 133
@@ -164,27 +159,27 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
164 int res = 0; 159 int res = 0;
165 int ret = 0; 160 int ret = 0;
166 161
167 ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof(sig)); 162 ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig));
168 if (ret != sizeof(sig)) 163 if (ret != sizeof (sig))
169 { 164 {
170 if (errno == ECOMM) 165 if (errno == ECOMM)
171 { 166 {
172 /* Child process is not controllable via pipe */ 167 /* Child process is not controllable via pipe */
173#if DEBUG_OS 168#if DEBUG_OS
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
175 "Child process is not controllable, will kill it directly\n"); 170 "Child process is not controllable, will kill it directly\n");
176#endif 171#endif
177 } 172 }
178 else if (errno == EPIPE) 173 else if (errno == EPIPE)
179 { 174 {
180#if DEBUG_OS 175#if DEBUG_OS
181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
182 "Failed to write into control pipe, because pipe is invalid (the child is most likely dead)\n"); 177 "Failed to write into control pipe, because pipe is invalid (the child is most likely dead)\n");
183#endif 178#endif
184 } 179 }
185 else 180 else
186 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 181 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
187 "Failed to write into control pipe , errno is %d\n", errno); 182 "Failed to write into control pipe , errno is %d\n", errno);
188#if WINDOWS && !defined(__CYGWIN__) 183#if WINDOWS && !defined(__CYGWIN__)
189 TerminateProcess (proc->handle, 0); 184 TerminateProcess (proc->handle, 0);
190#else 185#else
@@ -195,7 +190,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
195 { 190 {
196#if DEBUG_OS 191#if DEBUG_OS
197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
198 "Wrote control code into control pipe, now waiting\n"); 193 "Wrote control code into control pipe, now waiting\n");
199#endif 194#endif
200 195
201#if WINDOWS 196#if WINDOWS
@@ -225,27 +220,28 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
225 while (1) 220 while (1)
226 { 221 {
227 ret = GNUNET_NETWORK_socket_select (rfds, NULL, efds, 222 ret = GNUNET_NETWORK_socket_select (rfds, NULL, efds,
228 GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_unit (), 223 GNUNET_TIME_relative_multiply
229 5000)); 224 (GNUNET_TIME_relative_get_unit (),
225 5000));
230 226
231 if (ret < 1 || GNUNET_NETWORK_fdset_handle_isset (efds, 227 if (ret < 1 || GNUNET_NETWORK_fdset_handle_isset (efds,
232 proc->control_pipe)) 228 proc->control_pipe))
233 { 229 {
234 /* Just to be sure */ 230 /* Just to be sure */
235 PLIBC_KILL (proc->pid, sig); 231 PLIBC_KILL (proc->pid, sig);
236 res = 0; 232 res = 0;
237 break; 233 break;
238 } 234 }
239 else 235 else
240 { 236 {
241 if (GNUNET_DISK_file_read (proc->control_pipe, &ret, 237 if (GNUNET_DISK_file_read (proc->control_pipe, &ret,
242 sizeof(ret)) != GNUNET_OK) 238 sizeof (ret)) != GNUNET_OK)
243 res = PLIBC_KILL (proc->pid, sig); 239 res = PLIBC_KILL (proc->pid, sig);
244 240
245 /* Child signaled shutdown is in progress */ 241 /* Child signaled shutdown is in progress */
246 continue; 242 continue;
247 } 243 }
248 } 244 }
249#endif 245#endif
250 } 246 }
251 247
@@ -263,7 +259,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
263 * @return the current process id 259 * @return the current process id
264 */ 260 */
265pid_t 261pid_t
266GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc) 262GNUNET_OS_process_get_pid (struct GNUNET_OS_Process * proc)
267{ 263{
268 return proc->pid; 264 return proc->pid;
269} 265}
@@ -303,6 +299,7 @@ static DWORD_WINAPI
303ChildWaitThread (void *arg) 299ChildWaitThread (void *arg)
304{ 300{
305 struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *) arg; 301 struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *) arg;
302
306 WaitForSingleObject (proc->handle, INFINITE); 303 WaitForSingleObject (proc->handle, INFINITE);
307 304
308 if (w32_sigchld_handler) 305 if (w32_sigchld_handler)
@@ -331,91 +328,90 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
331 328
332 /* convert to MINGW/Unix values */ 329 /* convert to MINGW/Unix values */
333 switch (prio) 330 switch (prio)
334 { 331 {
335 case GNUNET_SCHEDULER_PRIORITY_UI: 332 case GNUNET_SCHEDULER_PRIORITY_UI:
336 case GNUNET_SCHEDULER_PRIORITY_URGENT: 333 case GNUNET_SCHEDULER_PRIORITY_URGENT:
337#ifdef MINGW 334#ifdef MINGW
338 rprio = HIGH_PRIORITY_CLASS; 335 rprio = HIGH_PRIORITY_CLASS;
339#else 336#else
340 rprio = 0; 337 rprio = 0;
341#endif 338#endif
342 break; 339 break;
343 340
344 case GNUNET_SCHEDULER_PRIORITY_HIGH: 341 case GNUNET_SCHEDULER_PRIORITY_HIGH:
345#ifdef MINGW 342#ifdef MINGW
346 rprio = ABOVE_NORMAL_PRIORITY_CLASS; 343 rprio = ABOVE_NORMAL_PRIORITY_CLASS;
347#else 344#else
348 rprio = 5; 345 rprio = 5;
349#endif 346#endif
350 break; 347 break;
351 348
352 case GNUNET_SCHEDULER_PRIORITY_DEFAULT: 349 case GNUNET_SCHEDULER_PRIORITY_DEFAULT:
353#ifdef MINGW 350#ifdef MINGW
354 rprio = NORMAL_PRIORITY_CLASS; 351 rprio = NORMAL_PRIORITY_CLASS;
355#else 352#else
356 rprio = 7; 353 rprio = 7;
357#endif 354#endif
358 break; 355 break;
359 356
360 case GNUNET_SCHEDULER_PRIORITY_BACKGROUND: 357 case GNUNET_SCHEDULER_PRIORITY_BACKGROUND:
361#ifdef MINGW 358#ifdef MINGW
362 rprio = BELOW_NORMAL_PRIORITY_CLASS; 359 rprio = BELOW_NORMAL_PRIORITY_CLASS;
363#else 360#else
364 rprio = 10; 361 rprio = 10;
365#endif 362#endif
366 break; 363 break;
367 364
368 case GNUNET_SCHEDULER_PRIORITY_IDLE: 365 case GNUNET_SCHEDULER_PRIORITY_IDLE:
369#ifdef MINGW 366#ifdef MINGW
370 rprio = IDLE_PRIORITY_CLASS; 367 rprio = IDLE_PRIORITY_CLASS;
371#else 368#else
372 rprio = 19; 369 rprio = 19;
373#endif 370#endif
374 break; 371 break;
375 default: 372 default:
376 GNUNET_assert (0); 373 GNUNET_assert (0);
377 return GNUNET_SYSERR; 374 return GNUNET_SYSERR;
378 } 375 }
379 376
380 /* Set process priority */ 377 /* Set process priority */
381#ifdef MINGW 378#ifdef MINGW
382 { 379 {
383 HANDLE h = proc->handle; 380 HANDLE h = proc->handle;
381
384 GNUNET_assert (h != NULL); 382 GNUNET_assert (h != NULL);
385 SetPriorityClass (h, rprio); 383 SetPriorityClass (h, rprio);
386 } 384 }
387#elif LINUX 385#elif LINUX
388 pid_t pid; 386 pid_t pid;
389 387
390 pid = proc->pid; 388 pid = proc->pid;
391 if ( (0 == pid) || 389 if ((0 == pid) || (pid == getpid ()))
392 (pid == getpid () ) ) 390 {
391 int have = nice (0);
392 int delta = rprio - have;
393
394 errno = 0;
395 if ((delta != 0) && (rprio == nice (delta)) && (errno != 0))
393 { 396 {
394 int have = nice (0); 397 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
395 int delta = rprio - have; 398 GNUNET_ERROR_TYPE_BULK, "nice");
396 errno = 0; 399 return GNUNET_SYSERR;
397 if ( (delta != 0) &&
398 (rprio == nice (delta)) &&
399 (errno != 0) )
400 {
401 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
402 GNUNET_ERROR_TYPE_BULK, "nice");
403 return GNUNET_SYSERR;
404 }
405 } 400 }
401 }
406 else 402 else
403 {
404 if (0 != setpriority (PRIO_PROCESS, pid, rprio))
407 { 405 {
408 if (0 != setpriority (PRIO_PROCESS, pid, rprio)) 406 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
409 { 407 GNUNET_ERROR_TYPE_BULK, "setpriority");
410 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING | 408 return GNUNET_SYSERR;
411 GNUNET_ERROR_TYPE_BULK, "setpriority");
412 return GNUNET_SYSERR;
413 }
414 } 409 }
410 }
415#else 411#else
416#if DEBUG_OS 412#if DEBUG_OS
417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
418 "Priority management not availabe for this platform\n"); 414 "Priority management not availabe for this platform\n");
419#endif 415#endif
420#endif 416#endif
421 return GNUNET_OK; 417 return GNUNET_OK;
@@ -434,10 +430,11 @@ CreateCustomEnvTable (char **vars)
434 size_t var_len; 430 size_t var_len;
435 char *var; 431 char *var;
436 char *val; 432 char *val;
433
437 win32_env_table = GetEnvironmentStringsA (); 434 win32_env_table = GetEnvironmentStringsA ();
438 if (win32_env_table == NULL) 435 if (win32_env_table == NULL)
439 return NULL; 436 return NULL;
440 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++); 437 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) ;
441 n_var = c; 438 n_var = c;
442 index = GNUNET_malloc (sizeof (char *) * n_var); 439 index = GNUNET_malloc (sizeof (char *) * n_var);
443 for (c = 0; c < n_var; c++) 440 for (c = 0; c < n_var; c++)
@@ -446,6 +443,7 @@ CreateCustomEnvTable (char **vars)
446 { 443 {
447 size_t len = strlen (ptr); 444 size_t len = strlen (ptr);
448 int found = 0; 445 int found = 0;
446
449 for (var_ptr = vars; *var_ptr; var_ptr++) 447 for (var_ptr = vars; *var_ptr; var_ptr++)
450 { 448 {
451 var = *var_ptr++; 449 var = *var_ptr++;
@@ -461,7 +459,7 @@ CreateCustomEnvTable (char **vars)
461 } 459 }
462 if (!found) 460 if (!found)
463 tablesize += len + 1; 461 tablesize += len + 1;
464 ptr += len + 1; 462 ptr += len + 1;
465 } 463 }
466 for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) 464 for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++)
467 { 465 {
@@ -475,6 +473,7 @@ CreateCustomEnvTable (char **vars)
475 { 473 {
476 size_t len = strlen (ptr); 474 size_t len = strlen (ptr);
477 int found = 0; 475 int found = 0;
476
478 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) 477 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++)
479 { 478 {
480 var = *var_ptr++; 479 var = *var_ptr++;
@@ -531,12 +530,12 @@ CreateCustomEnvTable (char **vars)
531 * @return pointer to process structure of the new process, NULL on error 530 * @return pointer to process structure of the new process, NULL on error
532 */ 531 */
533struct GNUNET_OS_Process * 532struct GNUNET_OS_Process *
534GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, 533GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
535 struct GNUNET_DISK_PipeHandle *pipe_stdout, 534 struct GNUNET_DISK_PipeHandle *pipe_stdout,
536 const char *filename, 535 const char *filename, va_list va)
537 va_list va)
538{ 536{
539 va_list ap; 537 va_list ap;
538
540#if ENABLE_WINDOWS_WORKAROUNDS 539#if ENABLE_WINDOWS_WORKAROUNDS
541 char *childpipename = NULL; 540 char *childpipename = NULL;
542 struct GNUNET_DISK_FileHandle *control_pipe = NULL; 541 struct GNUNET_DISK_FileHandle *control_pipe = NULL;
@@ -554,8 +553,9 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
554 553
555#if ENABLE_WINDOWS_WORKAROUNDS 554#if ENABLE_WINDOWS_WORKAROUNDS
556 control_pipe = GNUNET_DISK_npipe_create (&childpipename, 555 control_pipe = GNUNET_DISK_npipe_create (&childpipename,
557 GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | 556 GNUNET_DISK_OPEN_WRITE,
558 GNUNET_DISK_PERM_USER_WRITE); 557 GNUNET_DISK_PERM_USER_READ |
558 GNUNET_DISK_PERM_USER_WRITE);
559 if (control_pipe == NULL) 559 if (control_pipe == NULL)
560 return NULL; 560 return NULL;
561#endif 561#endif
@@ -563,24 +563,35 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
563 argc = 0; 563 argc = 0;
564 va_copy (ap, va); 564 va_copy (ap, va);
565 while (NULL != va_arg (ap, char *)) 565 while (NULL != va_arg (ap, char *))
566 argc++; 566 argc++;
567
567 va_end (ap); 568 va_end (ap);
568 argv = GNUNET_malloc (sizeof (char *) * (argc + 1)); 569 argv = GNUNET_malloc (sizeof (char *) * (argc + 1));
569 argc = 0; 570 argc = 0;
570 va_copy (ap, va); 571 va_copy (ap, va);
571 while (NULL != (argv[argc] = va_arg (ap, char *))) 572 while (NULL != (argv[argc] = va_arg (ap, char *)))
572 argc++; 573 argc++;
574
573 va_end (ap); 575 va_end (ap);
574 if (pipe_stdout != NULL) 576 if (pipe_stdout != NULL)
575 { 577 {
576 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), &fd_stdout_write, sizeof (int)); 578 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
577 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_READ), &fd_stdout_read, sizeof (int)); 579 (pipe_stdout,
578 } 580 GNUNET_DISK_PIPE_END_WRITE),
581 &fd_stdout_write, sizeof (int));
582 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
583 (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
584 &fd_stdout_read, sizeof (int));
585 }
579 if (pipe_stdin != NULL) 586 if (pipe_stdin != NULL)
580 { 587 {
581 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), &fd_stdin_read, sizeof (int)); 588 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
582 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_WRITE), &fd_stdin_write, sizeof (int)); 589 (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
583 } 590 &fd_stdin_read, sizeof (int));
591 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
592 (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
593 &fd_stdin_write, sizeof (int));
594 }
584 595
585#if HAVE_WORKING_VFORK 596#if HAVE_WORKING_VFORK
586 ret = vfork (); 597 ret = vfork ();
@@ -588,44 +599,44 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
588 ret = fork (); 599 ret = fork ();
589#endif 600#endif
590 if (ret != 0) 601 if (ret != 0)
602 {
603 if (ret == -1)
591 { 604 {
592 if (ret == -1) 605 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
593 {
594 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
595#if ENABLE_WINDOWS_WORKAROUNDS 606#if ENABLE_WINDOWS_WORKAROUNDS
596 GNUNET_DISK_npipe_close (control_pipe); 607 GNUNET_DISK_npipe_close (control_pipe);
597#endif 608#endif
598 } 609 }
599 else 610 else
600 { 611 {
601 612
602#if HAVE_WORKING_VFORK 613#if HAVE_WORKING_VFORK
603 /* let's hope vfork actually works; for some extreme cases (including 614 /* let's hope vfork actually works; for some extreme cases (including
604 a testcase) we need 'execvp' to have run before we return, since 615 * a testcase) we need 'execvp' to have run before we return, since
605 we may send a signal to the process next and we don't want it 616 * we may send a signal to the process next and we don't want it
606 to be caught by OUR signal handler (but either by the default 617 * to be caught by OUR signal handler (but either by the default
607 handler or the actual handler as installed by the process itself). */ 618 * handler or the actual handler as installed by the process itself). */
608#else 619#else
609 /* let's give the child process a chance to run execvp, 1s should 620 /* let's give the child process a chance to run execvp, 1s should
610 be plenty in practice */ 621 * be plenty in practice */
611 if (pipe_stdout != NULL) 622 if (pipe_stdout != NULL)
612 GNUNET_DISK_pipe_close_end(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE); 623 GNUNET_DISK_pipe_close_end (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
613 if (pipe_stdin != NULL) 624 if (pipe_stdin != NULL)
614 GNUNET_DISK_pipe_close_end(pipe_stdin, GNUNET_DISK_PIPE_END_READ); 625 GNUNET_DISK_pipe_close_end (pipe_stdin, GNUNET_DISK_PIPE_END_READ);
615 sleep (1); 626 sleep (1);
616#endif 627#endif
617 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); 628 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
618 gnunet_proc->pid = ret; 629 gnunet_proc->pid = ret;
619#if ENABLE_WINDOWS_WORKAROUNDS 630#if ENABLE_WINDOWS_WORKAROUNDS
620 gnunet_proc->control_pipe = control_pipe; 631 gnunet_proc->control_pipe = control_pipe;
621#endif 632#endif
622 } 633 }
623 GNUNET_free (argv); 634 GNUNET_free (argv);
624#if ENABLE_WINDOWS_WORKAROUNDS 635#if ENABLE_WINDOWS_WORKAROUNDS
625 GNUNET_free (childpipename); 636 GNUNET_free (childpipename);
626#endif 637#endif
627 return gnunet_proc; 638 return gnunet_proc;
628 } 639 }
629 640
630#if ENABLE_WINDOWS_WORKAROUNDS 641#if ENABLE_WINDOWS_WORKAROUNDS
631 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); 642 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1);
@@ -633,21 +644,21 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
633#endif 644#endif
634 645
635 if (pipe_stdout != NULL) 646 if (pipe_stdout != NULL)
636 { 647 {
637 GNUNET_break (0 == close (fd_stdout_read)); 648 GNUNET_break (0 == close (fd_stdout_read));
638 if (-1 == dup2(fd_stdout_write, 1)) 649 if (-1 == dup2 (fd_stdout_write, 1))
639 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); 650 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
640 GNUNET_break (0 == close (fd_stdout_write)); 651 GNUNET_break (0 == close (fd_stdout_write));
641 } 652 }
642 653
643 if (pipe_stdin != NULL) 654 if (pipe_stdin != NULL)
644 { 655 {
645 656
646 GNUNET_break (0 == close (fd_stdin_write)); 657 GNUNET_break (0 == close (fd_stdin_write));
647 if (-1 == dup2(fd_stdin_read, 0)) 658 if (-1 == dup2 (fd_stdin_read, 0))
648 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); 659 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
649 GNUNET_break (0 == close (fd_stdin_read)); 660 GNUNET_break (0 == close (fd_stdin_read));
650 } 661 }
651 execvp (filename, argv); 662 execvp (filename, argv);
652 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 663 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
653 _exit (1); 664 _exit (1);
@@ -682,7 +693,9 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
682 693
683 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); 694 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0);
684 695
685 alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + strlen (libdir); 696 alloc_len =
697 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 +
698 strlen (libdir);
686 699
687 pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); 700 pathbuf = GNUNET_malloc (alloc_len * sizeof (char));
688 701
@@ -704,36 +717,39 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
704 /* Check that this is the full path. If it isn't, search. */ 717 /* Check that this is the full path. If it isn't, search. */
705 if (non_const_filename[1] == ':') 718 if (non_const_filename[1] == ':')
706 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); 719 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
707 else if (!SearchPathA (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), path, NULL)) 720 else if (!SearchPathA
708 { 721 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char),
709 SetErrnoFromWinError (GetLastError ()); 722 path, NULL))
710 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath", non_const_filename); 723 {
711 GNUNET_free (non_const_filename); 724 SetErrnoFromWinError (GetLastError ());
712 GNUNET_free (pathbuf); 725 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath",
713 return NULL; 726 non_const_filename);
714 } 727 GNUNET_free (non_const_filename);
728 GNUNET_free (pathbuf);
729 return NULL;
730 }
715 GNUNET_free (pathbuf); 731 GNUNET_free (pathbuf);
716 GNUNET_free (non_const_filename); 732 GNUNET_free (non_const_filename);
717 733
718 cmdlen = 0; 734 cmdlen = 0;
719 va_copy (ap, va); 735 va_copy (ap, va);
720 while (NULL != (arg = va_arg (ap, char *))) 736 while (NULL != (arg = va_arg (ap, char *)))
721 { 737 {
722 if (cmdlen == 0) 738 if (cmdlen == 0)
723 cmdlen = cmdlen + strlen (path) + 3; 739 cmdlen = cmdlen + strlen (path) + 3;
724 else 740 else
725 cmdlen = cmdlen + strlen (arg) + 3; 741 cmdlen = cmdlen + strlen (arg) + 3;
726 } 742 }
727 va_end (ap); 743 va_end (ap);
728 744
729 cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1)); 745 cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1));
730 va_copy (ap, va); 746 va_copy (ap, va);
731 while (NULL != (arg = va_arg (ap, char *))) 747 while (NULL != (arg = va_arg (ap, char *)))
732 { 748 {
733 if (idx == cmd) 749 if (idx == cmd)
734 idx += sprintf (idx, "\"%s\" ", path); 750 idx += sprintf (idx, "\"%s\" ", path);
735 else 751 else
736 idx += sprintf (idx, "\"%s\" ", arg); 752 idx += sprintf (idx, "\"%s\" ", arg);
737 } 753 }
738 va_end (ap); 754 va_end (ap);
739 755
@@ -744,20 +760,26 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
744 start.dwFlags |= STARTF_USESTDHANDLES; 760 start.dwFlags |= STARTF_USESTDHANDLES;
745 761
746 if (pipe_stdin != NULL) 762 if (pipe_stdin != NULL)
747 { 763 {
748 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), &stdin_handle, sizeof (HANDLE)); 764 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
749 start.hStdInput = stdin_handle; 765 (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
750 } 766 &stdin_handle, sizeof (HANDLE));
767 start.hStdInput = stdin_handle;
768 }
751 769
752 if (pipe_stdout != NULL) 770 if (pipe_stdout != NULL)
753 { 771 {
754 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), &stdout_handle, sizeof (HANDLE)); 772 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
755 start.hStdOutput = stdout_handle; 773 (pipe_stdout,
756 } 774 GNUNET_DISK_PIPE_END_WRITE),
775 &stdout_handle, sizeof (HANDLE));
776 start.hStdOutput = stdout_handle;
777 }
757 778
758 control_pipe = GNUNET_DISK_npipe_create (&childpipename, 779 control_pipe = GNUNET_DISK_npipe_create (&childpipename,
759 GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | 780 GNUNET_DISK_OPEN_WRITE,
760 GNUNET_DISK_PERM_USER_WRITE); 781 GNUNET_DISK_PERM_USER_READ |
782 GNUNET_DISK_PERM_USER_WRITE);
761 if (control_pipe == NULL) 783 if (control_pipe == NULL)
762 { 784 {
763 GNUNET_free (cmd); 785 GNUNET_free (cmd);
@@ -766,9 +788,8 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
766 } 788 }
767 789
768#if DEBUG_OS 790#if DEBUG_OS
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Opened the parent end of the pipe `%s'\n", 792 "Opened the parent end of the pipe `%s'\n", childpipename);
771 childpipename);
772#endif 793#endif
773 794
774 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); 795 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
@@ -781,13 +802,13 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
781 if (!CreateProcessA 802 if (!CreateProcessA
782 (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, 803 (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
783 env_block, NULL, &start, &proc)) 804 env_block, NULL, &start, &proc))
784 { 805 {
785 SetErrnoFromWinError (GetLastError ()); 806 SetErrnoFromWinError (GetLastError ());
786 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path); 807 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
787 GNUNET_free (env_block); 808 GNUNET_free (env_block);
788 GNUNET_free (cmd); 809 GNUNET_free (cmd);
789 return NULL; 810 return NULL;
790 } 811 }
791 812
792 GNUNET_free (env_block); 813 GNUNET_free (env_block);
793 814
@@ -820,18 +841,15 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
820 * 841 *
821 */ 842 */
822struct GNUNET_OS_Process * 843struct GNUNET_OS_Process *
823GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, 844GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin,
824 struct GNUNET_DISK_PipeHandle *pipe_stdout, 845 struct GNUNET_DISK_PipeHandle *pipe_stdout,
825 const char *filename, ...) 846 const char *filename, ...)
826{ 847{
827 struct GNUNET_OS_Process *ret; 848 struct GNUNET_OS_Process *ret;
828 va_list ap; 849 va_list ap;
829 850
830 va_start (ap, filename); 851 va_start (ap, filename);
831 ret = GNUNET_OS_start_process_va (pipe_stdin, 852 ret = GNUNET_OS_start_process_va (pipe_stdin, pipe_stdout, filename, ap);
832 pipe_stdout,
833 filename,
834 ap);
835 va_end (ap); 853 va_end (ap);
836 return ret; 854 return ret;
837} 855}
@@ -848,7 +866,7 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin,
848 */ 866 */
849struct GNUNET_OS_Process * 867struct GNUNET_OS_Process *
850GNUNET_OS_start_process_v (const int *lsocks, 868GNUNET_OS_start_process_v (const int *lsocks,
851 const char *filename, char *const argv[]) 869 const char *filename, char *const argv[])
852{ 870{
853#if ENABLE_WINDOWS_WORKAROUNDS 871#if ENABLE_WINDOWS_WORKAROUNDS
854 struct GNUNET_DISK_FileHandle *control_pipe = NULL; 872 struct GNUNET_DISK_FileHandle *control_pipe = NULL;
@@ -866,12 +884,13 @@ GNUNET_OS_start_process_v (const int *lsocks,
866 int tgt; 884 int tgt;
867 int flags; 885 int flags;
868 int *lscp; 886 int *lscp;
869 unsigned int ls; 887 unsigned int ls;
870 888
871#if ENABLE_WINDOWS_WORKAROUNDS 889#if ENABLE_WINDOWS_WORKAROUNDS
872 control_pipe = GNUNET_DISK_npipe_create (&childpipename, 890 control_pipe = GNUNET_DISK_npipe_create (&childpipename,
873 GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | 891 GNUNET_DISK_OPEN_WRITE,
874 GNUNET_DISK_PERM_USER_WRITE); 892 GNUNET_DISK_PERM_USER_READ |
893 GNUNET_DISK_PERM_USER_WRITE);
875 if (control_pipe == NULL) 894 if (control_pipe == NULL)
876 return NULL; 895 return NULL;
877#endif 896#endif
@@ -879,100 +898,100 @@ GNUNET_OS_start_process_v (const int *lsocks,
879 lscp = NULL; 898 lscp = NULL;
880 ls = 0; 899 ls = 0;
881 if (lsocks != NULL) 900 if (lsocks != NULL)
882 { 901 {
883 i = 0; 902 i = 0;
884 while (-1 != (k = lsocks[i++])) 903 while (-1 != (k = lsocks[i++]))
885 GNUNET_array_append (lscp, ls, k); 904 GNUNET_array_append (lscp, ls, k);
886 GNUNET_array_append (lscp, ls, -1); 905 GNUNET_array_append (lscp, ls, -1);
887 } 906 }
888#if HAVE_WORKING_VFORK 907#if HAVE_WORKING_VFORK
889 ret = vfork (); 908 ret = vfork ();
890#else 909#else
891 ret = fork (); 910 ret = fork ();
892#endif 911#endif
893 if (ret != 0) 912 if (ret != 0)
913 {
914 if (ret == -1)
894 { 915 {
895 if (ret == -1) 916 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
896 {
897 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
898#if ENABLE_WINDOWS_WORKAROUNDS 917#if ENABLE_WINDOWS_WORKAROUNDS
899 GNUNET_DISK_npipe_close (control_pipe); 918 GNUNET_DISK_npipe_close (control_pipe);
900#endif 919#endif
901 } 920 }
902 else 921 else
903 { 922 {
904#if HAVE_WORKING_VFORK 923#if HAVE_WORKING_VFORK
905 /* let's hope vfork actually works; for some extreme cases (including 924 /* let's hope vfork actually works; for some extreme cases (including
906 a testcase) we need 'execvp' to have run before we return, since 925 * a testcase) we need 'execvp' to have run before we return, since
907 we may send a signal to the process next and we don't want it 926 * we may send a signal to the process next and we don't want it
908 to be caught by OUR signal handler (but either by the default 927 * to be caught by OUR signal handler (but either by the default
909 handler or the actual handler as installed by the process itself). */ 928 * handler or the actual handler as installed by the process itself). */
910#else 929#else
911 /* let's give the child process a chance to run execvp, 1s should 930 /* let's give the child process a chance to run execvp, 1s should
912 be plenty in practice */ 931 * be plenty in practice */
913 sleep (1); 932 sleep (1);
914#endif 933#endif
915 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); 934 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
916 gnunet_proc->pid = ret; 935 gnunet_proc->pid = ret;
917#if ENABLE_WINDOWS_WORKAROUNDS 936#if ENABLE_WINDOWS_WORKAROUNDS
918 gnunet_proc->control_pipe = control_pipe; 937 gnunet_proc->control_pipe = control_pipe;
919 938
920#endif 939#endif
921 } 940 }
922 GNUNET_array_grow (lscp, ls, 0); 941 GNUNET_array_grow (lscp, ls, 0);
923#if ENABLE_WINDOWS_WORKAROUNDS 942#if ENABLE_WINDOWS_WORKAROUNDS
924 GNUNET_free (childpipename); 943 GNUNET_free (childpipename);
925#endif 944#endif
926 return gnunet_proc; 945 return gnunet_proc;
927 } 946 }
928 947
929#if ENABLE_WINDOWS_WORKAROUNDS 948#if ENABLE_WINDOWS_WORKAROUNDS
930 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); 949 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1);
931 GNUNET_free (childpipename); 950 GNUNET_free (childpipename);
932#endif 951#endif
933 952
934 if (lscp != NULL) 953 if (lscp != NULL)
954 {
955 /* read systemd documentation... */
956 GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid ());
957 setenv ("LISTEN_PID", lpid, 1);
958 i = 0;
959 tgt = 3;
960 while (-1 != lscp[i])
935 { 961 {
936 /* read systemd documentation... */ 962 j = i + 1;
937 GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid()); 963 while (-1 != lscp[j])
938 setenv ("LISTEN_PID", lpid, 1); 964 {
939 i = 0; 965 if (lscp[j] == tgt)
940 tgt = 3; 966 {
941 while (-1 != lscp[i]) 967 /* dup away */
942 { 968 k = dup (lscp[j]);
943 j = i + 1; 969 GNUNET_assert (-1 != k);
944 while (-1 != lscp[j]) 970 GNUNET_assert (0 == close (lscp[j]));
945 { 971 lscp[j] = k;
946 if (lscp[j] == tgt) 972 break;
947 { 973 }
948 /* dup away */ 974 j++;
949 k = dup (lscp[j]); 975 }
950 GNUNET_assert (-1 != k); 976 if (lscp[i] != tgt)
951 GNUNET_assert (0 == close (lscp[j])); 977 {
952 lscp[j] = k; 978 /* Bury any existing FD, no matter what; they should all be closed
953 break; 979 * on exec anyway and the important onces have been dup'ed away */
954 } 980 (void) close (tgt);
955 j++; 981 GNUNET_assert (-1 != dup2 (lscp[i], tgt));
956 } 982 }
957 if (lscp[i] != tgt) 983 /* unset close-on-exec flag */
958 { 984 flags = fcntl (tgt, F_GETFD);
959 /* Bury any existing FD, no matter what; they should all be closed 985 GNUNET_assert (flags >= 0);
960 on exec anyway and the important onces have been dup'ed away */ 986 flags &= ~FD_CLOEXEC;
961 (void) close (tgt); 987 fflush (stderr);
962 GNUNET_assert (-1 != dup2 (lscp[i], tgt)); 988 (void) fcntl (tgt, F_SETFD, flags);
963 } 989 tgt++;
964 /* unset close-on-exec flag */ 990 i++;
965 flags = fcntl (tgt, F_GETFD);
966 GNUNET_assert (flags >= 0);
967 flags &= ~FD_CLOEXEC;
968 fflush (stderr);
969 (void) fcntl (tgt, F_SETFD, flags);
970 tgt++;
971 i++;
972 }
973 GNUNET_snprintf (fds, sizeof (fds), "%u", i);
974 setenv ("LISTEN_FDS", fds, 1);
975 } 991 }
992 GNUNET_snprintf (fds, sizeof (fds), "%u", i);
993 setenv ("LISTEN_FDS", fds, 1);
994 }
976 GNUNET_array_grow (lscp, ls, 0); 995 GNUNET_array_grow (lscp, ls, 0);
977 execvp (filename, argv); 996 execvp (filename, argv);
978 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 997 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
@@ -1009,7 +1028,9 @@ GNUNET_OS_start_process_v (const int *lsocks,
1009 1028
1010 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); 1029 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0);
1011 1030
1012 alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + strlen (libdir); 1031 alloc_len =
1032 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 +
1033 strlen (libdir);
1013 1034
1014 pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); 1035 pathbuf = GNUNET_malloc (alloc_len * sizeof (char));
1015 1036
@@ -1023,7 +1044,7 @@ GNUNET_OS_start_process_v (const int *lsocks,
1023 if (alloc_len != pathbuf_len - 1) 1044 if (alloc_len != pathbuf_len - 1)
1024 { 1045 {
1025 GNUNET_free (pathbuf); 1046 GNUNET_free (pathbuf);
1026 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ 1047 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */
1027 return NULL; 1048 return NULL;
1028 } 1049 }
1029 1050
@@ -1036,24 +1057,27 @@ GNUNET_OS_start_process_v (const int *lsocks,
1036 /* Check that this is the full path. If it isn't, search. */ 1057 /* Check that this is the full path. If it isn't, search. */
1037 if (non_const_filename[1] == ':') 1058 if (non_const_filename[1] == ':')
1038 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); 1059 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
1039 else if (!SearchPathA (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), path, NULL)) 1060 else if (!SearchPathA
1040 { 1061 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char),
1041 SetErrnoFromWinError (GetLastError ()); 1062 path, NULL))
1042 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath", non_const_filename); 1063 {
1043 GNUNET_free (non_const_filename); 1064 SetErrnoFromWinError (GetLastError ());
1044 GNUNET_free (pathbuf); 1065 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath",
1045 return NULL; 1066 non_const_filename);
1046 } 1067 GNUNET_free (non_const_filename);
1068 GNUNET_free (pathbuf);
1069 return NULL;
1070 }
1047 GNUNET_free (pathbuf); 1071 GNUNET_free (pathbuf);
1048 GNUNET_free (non_const_filename); 1072 GNUNET_free (non_const_filename);
1049 1073
1050 /* Count the number of arguments */ 1074 /* Count the number of arguments */
1051 arg = (char **) argv; 1075 arg = (char **) argv;
1052 while (*arg) 1076 while (*arg)
1053 { 1077 {
1054 arg++; 1078 arg++;
1055 argcount++; 1079 argcount++;
1056 } 1080 }
1057 1081
1058 /* Allocate a copy argv */ 1082 /* Allocate a copy argv */
1059 non_const_argv = GNUNET_malloc (sizeof (char *) * (argcount + 1)); 1083 non_const_argv = GNUNET_malloc (sizeof (char *) * (argcount + 1));
@@ -1062,33 +1086,33 @@ GNUNET_OS_start_process_v (const int *lsocks,
1062 argcount = 0; 1086 argcount = 0;
1063 arg = (char **) argv; 1087 arg = (char **) argv;
1064 while (*arg) 1088 while (*arg)
1065 { 1089 {
1066 if (arg == argv) 1090 if (arg == argv)
1067 non_const_argv[argcount] = GNUNET_strdup (path); 1091 non_const_argv[argcount] = GNUNET_strdup (path);
1068 else 1092 else
1069 non_const_argv[argcount] = GNUNET_strdup (*arg); 1093 non_const_argv[argcount] = GNUNET_strdup (*arg);
1070 arg++; 1094 arg++;
1071 argcount++; 1095 argcount++;
1072 } 1096 }
1073 non_const_argv[argcount] = NULL; 1097 non_const_argv[argcount] = NULL;
1074 1098
1075 /* Count cmd len */ 1099 /* Count cmd len */
1076 cmdlen = 1; 1100 cmdlen = 1;
1077 arg = non_const_argv; 1101 arg = non_const_argv;
1078 while (*arg) 1102 while (*arg)
1079 { 1103 {
1080 cmdlen = cmdlen + strlen (*arg) + 3; 1104 cmdlen = cmdlen + strlen (*arg) + 3;
1081 arg++; 1105 arg++;
1082 } 1106 }
1083 1107
1084 /* Allocate and create cmd */ 1108 /* Allocate and create cmd */
1085 cmd = idx = GNUNET_malloc (sizeof (char) * cmdlen); 1109 cmd = idx = GNUNET_malloc (sizeof (char) * cmdlen);
1086 arg = non_const_argv; 1110 arg = non_const_argv;
1087 while (*arg) 1111 while (*arg)
1088 { 1112 {
1089 idx += sprintf (idx, "\"%s\" ", *arg); 1113 idx += sprintf (idx, "\"%s\" ", *arg);
1090 arg++; 1114 arg++;
1091 } 1115 }
1092 1116
1093 while (argcount > 0) 1117 while (argcount > 0)
1094 GNUNET_free (non_const_argv[--argcount]); 1118 GNUNET_free (non_const_argv[--argcount]);
@@ -1098,8 +1122,9 @@ GNUNET_OS_start_process_v (const int *lsocks,
1098 start.cb = sizeof (start); 1122 start.cb = sizeof (start);
1099 1123
1100 control_pipe = GNUNET_DISK_npipe_create (&childpipename, 1124 control_pipe = GNUNET_DISK_npipe_create (&childpipename,
1101 GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | 1125 GNUNET_DISK_OPEN_WRITE,
1102 GNUNET_DISK_PERM_USER_WRITE); 1126 GNUNET_DISK_PERM_USER_READ |
1127 GNUNET_DISK_PERM_USER_WRITE);
1103 if (control_pipe == NULL) 1128 if (control_pipe == NULL)
1104 { 1129 {
1105 GNUNET_free (cmd); 1130 GNUNET_free (cmd);
@@ -1108,7 +1133,8 @@ GNUNET_OS_start_process_v (const int *lsocks,
1108 } 1133 }
1109 1134
1110#if DEBUG_OS 1135#if DEBUG_OS
1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", childpipename); 1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1137 "Opened the parent end of the pipe `%s'\n", childpipename);
1112#endif 1138#endif
1113 1139
1114 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); 1140 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
@@ -1121,13 +1147,13 @@ GNUNET_OS_start_process_v (const int *lsocks,
1121 if (!CreateProcess 1147 if (!CreateProcess
1122 (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, 1148 (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED,
1123 env_block, NULL, &start, &proc)) 1149 env_block, NULL, &start, &proc))
1124 { 1150 {
1125 SetErrnoFromWinError (GetLastError ()); 1151 SetErrnoFromWinError (GetLastError ());
1126 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); 1152 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
1127 GNUNET_free (env_block); 1153 GNUNET_free (env_block);
1128 GNUNET_free (cmd); 1154 GNUNET_free (cmd);
1129 return NULL; 1155 return NULL;
1130 } 1156 }
1131 1157
1132 GNUNET_free (env_block); 1158 GNUNET_free (env_block);
1133 1159
@@ -1155,8 +1181,8 @@ GNUNET_OS_start_process_v (const int *lsocks,
1155 * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise 1181 * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise
1156 */ 1182 */
1157int 1183int
1158GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, 1184GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1159 enum GNUNET_OS_ProcessStatusType *type, 1185 enum GNUNET_OS_ProcessStatusType *type,
1160 unsigned long *code) 1186 unsigned long *code)
1161{ 1187{
1162#ifndef MINGW 1188#ifndef MINGW
@@ -1166,48 +1192,48 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1166 GNUNET_assert (0 != proc); 1192 GNUNET_assert (0 != proc);
1167 ret = waitpid (proc->pid, &status, WNOHANG); 1193 ret = waitpid (proc->pid, &status, WNOHANG);
1168 if (ret < 0) 1194 if (ret < 0)
1169 { 1195 {
1170 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 1196 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1171 return GNUNET_SYSERR; 1197 return GNUNET_SYSERR;
1172 } 1198 }
1173 if (0 == ret) 1199 if (0 == ret)
1174 { 1200 {
1175 *type = GNUNET_OS_PROCESS_RUNNING; 1201 *type = GNUNET_OS_PROCESS_RUNNING;
1176 *code = 0; 1202 *code = 0;
1177 return GNUNET_NO; 1203 return GNUNET_NO;
1178 } 1204 }
1179 if (proc->pid != ret) 1205 if (proc->pid != ret)
1180 { 1206 {
1181 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 1207 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1182 return GNUNET_SYSERR; 1208 return GNUNET_SYSERR;
1183 } 1209 }
1184 if (WIFEXITED (status)) 1210 if (WIFEXITED (status))
1185 { 1211 {
1186 *type = GNUNET_OS_PROCESS_EXITED; 1212 *type = GNUNET_OS_PROCESS_EXITED;
1187 *code = WEXITSTATUS (status); 1213 *code = WEXITSTATUS (status);
1188 } 1214 }
1189 else if (WIFSIGNALED (status)) 1215 else if (WIFSIGNALED (status))
1190 { 1216 {
1191 *type = GNUNET_OS_PROCESS_SIGNALED; 1217 *type = GNUNET_OS_PROCESS_SIGNALED;
1192 *code = WTERMSIG (status); 1218 *code = WTERMSIG (status);
1193 } 1219 }
1194 else if (WIFSTOPPED (status)) 1220 else if (WIFSTOPPED (status))
1195 { 1221 {
1196 *type = GNUNET_OS_PROCESS_SIGNALED; 1222 *type = GNUNET_OS_PROCESS_SIGNALED;
1197 *code = WSTOPSIG (status); 1223 *code = WSTOPSIG (status);
1198 } 1224 }
1199#ifdef WIFCONTINUED 1225#ifdef WIFCONTINUED
1200 else if (WIFCONTINUED (status)) 1226 else if (WIFCONTINUED (status))
1201 { 1227 {
1202 *type = GNUNET_OS_PROCESS_RUNNING; 1228 *type = GNUNET_OS_PROCESS_RUNNING;
1203 *code = 0; 1229 *code = 0;
1204 } 1230 }
1205#endif 1231#endif
1206 else 1232 else
1207 { 1233 {
1208 *type = GNUNET_OS_PROCESS_UNKNOWN; 1234 *type = GNUNET_OS_PROCESS_UNKNOWN;
1209 *code = 0; 1235 *code = 0;
1210 } 1236 }
1211#else 1237#else
1212 HANDLE h; 1238 HANDLE h;
1213 DWORD c, error_code, ret; 1239 DWORD c, error_code, ret;
@@ -1215,10 +1241,11 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1215 h = proc->handle; 1241 h = proc->handle;
1216 ret = proc->pid; 1242 ret = proc->pid;
1217 if (h == NULL || ret == 0) 1243 if (h == NULL || ret == 0)
1218 { 1244 {
1219 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n", ret, h); 1245 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1220 return GNUNET_SYSERR; 1246 "Invalid process information {%d, %08X}\n", ret, h);
1221 } 1247 return GNUNET_SYSERR;
1248 }
1222 if (h == NULL) 1249 if (h == NULL)
1223 h = GetCurrentProcess (); 1250 h = GetCurrentProcess ();
1224 1251
@@ -1227,16 +1254,16 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1227 error_code = GetLastError (); 1254 error_code = GetLastError ();
1228 if (ret == 0 || error_code != NO_ERROR) 1255 if (ret == 0 || error_code != NO_ERROR)
1229 { 1256 {
1230 SetErrnoFromWinError (error_code); 1257 SetErrnoFromWinError (error_code);
1231 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess"); 1258 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess");
1232 return GNUNET_SYSERR; 1259 return GNUNET_SYSERR;
1233 } 1260 }
1234 if (STILL_ACTIVE == c) 1261 if (STILL_ACTIVE == c)
1235 { 1262 {
1236 *type = GNUNET_OS_PROCESS_RUNNING; 1263 *type = GNUNET_OS_PROCESS_RUNNING;
1237 *code = 0; 1264 *code = 0;
1238 return GNUNET_NO; 1265 return GNUNET_NO;
1239 } 1266 }
1240 *type = GNUNET_OS_PROCESS_EXITED; 1267 *type = GNUNET_OS_PROCESS_EXITED;
1241 *code = c; 1268 *code = c;
1242#endif 1269#endif
@@ -1256,6 +1283,7 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1256 1283
1257#ifndef MINGW 1284#ifndef MINGW
1258 pid_t pid = proc->pid; 1285 pid_t pid = proc->pid;
1286
1259 if (pid != waitpid (pid, NULL, 0)) 1287 if (pid != waitpid (pid, NULL, 0))
1260 return GNUNET_SYSERR; 1288 return GNUNET_SYSERR;
1261 return GNUNET_OK; 1289 return GNUNET_OK;
@@ -1265,21 +1293,19 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1265 1293
1266 h = proc->handle; 1294 h = proc->handle;
1267 if (NULL == h) 1295 if (NULL == h)
1268 { 1296 {
1269 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1297 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1270 "Invalid process information {%d, %08X}\n", 1298 "Invalid process information {%d, %08X}\n", proc->pid, h);
1271 proc->pid, 1299 return GNUNET_SYSERR;
1272 h); 1300 }
1273 return GNUNET_SYSERR;
1274 }
1275 if (h == NULL) 1301 if (h == NULL)
1276 h = GetCurrentProcess (); 1302 h = GetCurrentProcess ();
1277 1303
1278 if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) 1304 if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
1279 { 1305 {
1280 SetErrnoFromWinError (GetLastError ()); 1306 SetErrnoFromWinError (GetLastError ());
1281 ret = GNUNET_SYSERR; 1307 ret = GNUNET_SYSERR;
1282 } 1308 }
1283 else 1309 else
1284 ret = GNUNET_OK; 1310 ret = GNUNET_OK;
1285 1311
@@ -1303,7 +1329,7 @@ struct GNUNET_OS_CommandHandle
1303 * Handle to the output pipe. 1329 * Handle to the output pipe.
1304 */ 1330 */
1305 struct GNUNET_DISK_PipeHandle *opipe; 1331 struct GNUNET_DISK_PipeHandle *opipe;
1306 1332
1307 /** 1333 /**
1308 * Read-end of output pipe. 1334 * Read-end of output pipe.
1309 */ 1335 */
@@ -1318,12 +1344,12 @@ struct GNUNET_OS_CommandHandle
1318 * Closure for 'proc'. 1344 * Closure for 'proc'.
1319 */ 1345 */
1320 void *proc_cls; 1346 void *proc_cls;
1321 1347
1322 /** 1348 /**
1323 * Buffer for the output. 1349 * Buffer for the output.
1324 */ 1350 */
1325 char buf[1024]; 1351 char buf[1024];
1326 1352
1327 /** 1353 /**
1328 * Task reading from pipe. 1354 * Task reading from pipe.
1329 */ 1355 */
@@ -1353,13 +1379,12 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
1353{ 1379{
1354 1380
1355 if (cmd->proc != NULL) 1381 if (cmd->proc != NULL)
1356 { 1382 {
1357 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cmd->rtask); 1383 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cmd->rtask);
1358 GNUNET_SCHEDULER_cancel (cmd->rtask); 1384 GNUNET_SCHEDULER_cancel (cmd->rtask);
1359 } 1385 }
1360 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL); 1386 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
1361 GNUNET_break (GNUNET_OK == 1387 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip));
1362 GNUNET_OS_process_wait (cmd->eip));
1363 GNUNET_OS_process_close (cmd->eip); 1388 GNUNET_OS_process_close (cmd->eip);
1364 GNUNET_DISK_pipe_close (cmd->opipe); 1389 GNUNET_DISK_pipe_close (cmd->opipe);
1365 GNUNET_free (cmd); 1390 GNUNET_free (cmd);
@@ -1373,8 +1398,7 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
1373 * @param tc scheduler context 1398 * @param tc scheduler context
1374 */ 1399 */
1375static void 1400static void
1376cmd_read (void *cls, 1401cmd_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1377 const struct GNUNET_SCHEDULER_TaskContext *tc)
1378{ 1402{
1379 struct GNUNET_OS_CommandHandle *cmd = cls; 1403 struct GNUNET_OS_CommandHandle *cmd = cls;
1380 GNUNET_OS_LineProcessor proc; 1404 GNUNET_OS_LineProcessor proc;
@@ -1382,47 +1406,42 @@ cmd_read (void *cls,
1382 ssize_t ret; 1406 ssize_t ret;
1383 1407
1384 cmd->rtask = GNUNET_SCHEDULER_NO_TASK; 1408 cmd->rtask = GNUNET_SCHEDULER_NO_TASK;
1385 if (GNUNET_YES != 1409 if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r))
1386 GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, 1410 {
1387 cmd->r)) 1411 /* timeout, shutdown, etc. */
1388 { 1412 proc = cmd->proc;
1389 /* timeout, shutdown, etc. */ 1413 cmd->proc = NULL;
1390 proc = cmd->proc; 1414 proc (cmd->proc_cls, NULL);
1391 cmd->proc = NULL; 1415 return;
1392 proc (cmd->proc_cls, NULL); 1416 }
1393 return;
1394 }
1395 ret = GNUNET_DISK_file_read (cmd->r, 1417 ret = GNUNET_DISK_file_read (cmd->r,
1396 &cmd->buf[cmd->off], 1418 &cmd->buf[cmd->off],
1397 sizeof (cmd->buf)-cmd->off); 1419 sizeof (cmd->buf) - cmd->off);
1398 if (ret <= 0) 1420 if (ret <= 0)
1421 {
1422 if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf)))
1399 { 1423 {
1400 if ( (cmd->off > 0) && (cmd->off < sizeof (cmd->buf)) ) 1424 cmd->buf[cmd->off] = '\0';
1401 { 1425 cmd->proc (cmd->proc_cls, cmd->buf);
1402 cmd->buf[cmd->off] = '\0'; 1426 }
1403 cmd->proc (cmd->proc_cls, cmd->buf); 1427 proc = cmd->proc;
1404 } 1428 cmd->proc = NULL;
1405 proc = cmd->proc; 1429 proc (cmd->proc_cls, NULL);
1406 cmd->proc = NULL; 1430 return;
1407 proc (cmd->proc_cls, NULL); 1431 }
1408 return;
1409 }
1410 end = memchr (&cmd->buf[cmd->off], '\n', ret); 1432 end = memchr (&cmd->buf[cmd->off], '\n', ret);
1411 cmd->off += ret; 1433 cmd->off += ret;
1412 while (end != NULL) 1434 while (end != NULL)
1413 { 1435 {
1414 *end = '\0'; 1436 *end = '\0';
1415 cmd->proc (cmd->proc_cls, cmd->buf); 1437 cmd->proc (cmd->proc_cls, cmd->buf);
1416 memmove (cmd->buf, 1438 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
1417 end + 1, 1439 cmd->off -= (end + 1 - cmd->buf);
1418 cmd->off - (end + 1 - cmd->buf)); 1440 end = memchr (cmd->buf, '\n', cmd->off);
1419 cmd->off -= (end + 1 - cmd->buf); 1441 }
1420 end = memchr (cmd->buf, '\n', cmd->off); 1442 cmd->rtask =
1421 } 1443 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
1422 cmd->rtask = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (cmd->timeout), 1444 (cmd->timeout), cmd->r, &cmd_read, cmd);
1423 cmd->r,
1424 &cmd_read,
1425 cmd);
1426} 1445}
1427 1446
1428 1447
@@ -1439,30 +1458,26 @@ cmd_read (void *cls,
1439 */ 1458 */
1440struct GNUNET_OS_CommandHandle * 1459struct GNUNET_OS_CommandHandle *
1441GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, 1460GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
1442 void *proc_cls, 1461 void *proc_cls,
1443 struct GNUNET_TIME_Relative timeout, 1462 struct GNUNET_TIME_Relative timeout,
1444 const char *binary, 1463 const char *binary, ...)
1445 ...)
1446{ 1464{
1447 struct GNUNET_OS_CommandHandle *cmd; 1465 struct GNUNET_OS_CommandHandle *cmd;
1448 struct GNUNET_OS_Process *eip; 1466 struct GNUNET_OS_Process *eip;
1449 struct GNUNET_DISK_PipeHandle *opipe; 1467 struct GNUNET_DISK_PipeHandle *opipe;
1450 va_list ap; 1468 va_list ap;
1451 1469
1452 opipe = GNUNET_DISK_pipe (GNUNET_YES, 1470 opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
1453 GNUNET_NO,
1454 GNUNET_YES);
1455 if (NULL == opipe) 1471 if (NULL == opipe)
1456 return NULL; 1472 return NULL;
1457 va_start (ap, binary); 1473 va_start (ap, binary);
1458 eip = GNUNET_OS_start_process_va (NULL, opipe, 1474 eip = GNUNET_OS_start_process_va (NULL, opipe, binary, ap);
1459 binary, ap);
1460 va_end (ap); 1475 va_end (ap);
1461 if (NULL == eip) 1476 if (NULL == eip)
1462 { 1477 {
1463 GNUNET_DISK_pipe_close (opipe); 1478 GNUNET_DISK_pipe_close (opipe);
1464 return NULL; 1479 return NULL;
1465 } 1480 }
1466 GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE); 1481 GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE);
1467 cmd = GNUNET_malloc (sizeof (struct GNUNET_OS_CommandHandle)); 1482 cmd = GNUNET_malloc (sizeof (struct GNUNET_OS_CommandHandle));
1468 cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1483 cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout);
@@ -1470,12 +1485,8 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
1470 cmd->opipe = opipe; 1485 cmd->opipe = opipe;
1471 cmd->proc = proc; 1486 cmd->proc = proc;
1472 cmd->proc_cls = proc_cls; 1487 cmd->proc_cls = proc_cls;
1473 cmd->r = GNUNET_DISK_pipe_handle (opipe, 1488 cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ);
1474 GNUNET_DISK_PIPE_END_READ); 1489 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd);
1475 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout,
1476 cmd->r,
1477 &cmd_read,
1478 cmd);
1479 return cmd; 1490 return cmd;
1480} 1491}
1481 1492