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.c1110
1 files changed, 549 insertions, 561 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index 4f21e7edb..a7ce0c5e5 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -59,43 +59,41 @@ static struct GNUNET_OS_Process current_process;
59 */ 59 */
60static void 60static void
61parent_control_handler (void *cls, 61parent_control_handler (void *cls,
62 const struct GNUNET_SCHEDULER_TaskContext *tc) 62 const struct GNUNET_SCHEDULER_TaskContext *tc)
63{ 63{
64 struct GNUNET_DISK_FileHandle *control_pipe = 64 struct GNUNET_DISK_FileHandle *control_pipe =
65 (struct GNUNET_DISK_FileHandle *) cls; 65 (struct GNUNET_DISK_FileHandle *) cls;
66 int sig; 66 int sig;
67 67
68#if DEBUG_OS 68#if DEBUG_OS
69 LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' invoked because of %d\n", 69 LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' invoked because of %d\n", __FUNCTION__,
70 __FUNCTION__, tc->reason); 70 tc->reason);
71#endif 71#endif
72 if (tc->reason & 72 if (tc->reason &
73 (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | 73 (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT |
74 GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 74 GNUNET_SCHEDULER_REASON_PREREQ_DONE))
75 {
76 GNUNET_DISK_npipe_close (control_pipe);
77 }
78 else
79 {
80 if (GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)) !=
81 sizeof (sig))
75 { 82 {
83 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
76 GNUNET_DISK_npipe_close (control_pipe); 84 GNUNET_DISK_npipe_close (control_pipe);
77 } 85 }
78 else 86 else
79 { 87 {
80 if (GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)) !=
81 sizeof (sig))
82 {
83 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
84 GNUNET_DISK_npipe_close (control_pipe);
85 }
86 else
87 {
88#if DEBUG_OS 88#if DEBUG_OS
89 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d from parent\n", 89 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d from parent\n", sig);
90 sig);
91#endif 90#endif
92 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 91 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
93 control_pipe, 92 control_pipe, &parent_control_handler,
94 &parent_control_handler, 93 control_pipe);
95 control_pipe); 94 raise (sig);
96 raise (sig);
97 }
98 } 95 }
96 }
99} 97}
100 98
101 99
@@ -104,35 +102,34 @@ parent_control_handler (void *cls,
104 */ 102 */
105void 103void
106GNUNET_OS_install_parent_control_handler (void *cls, 104GNUNET_OS_install_parent_control_handler (void *cls,
107 const struct 105 const struct
108 GNUNET_SCHEDULER_TaskContext *tc) 106 GNUNET_SCHEDULER_TaskContext *tc)
109{ 107{
110 const char *env_buf; 108 const char *env_buf;
111 struct GNUNET_DISK_FileHandle *control_pipe; 109 struct GNUNET_DISK_FileHandle *control_pipe;
112 110
113 env_buf = getenv (GNUNET_OS_CONTROL_PIPE); 111 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
114 if ((env_buf == NULL) || (strlen (env_buf) <= 0)) 112 if ((env_buf == NULL) || (strlen (env_buf) <= 0))
115 { 113 {
116 LOG (GNUNET_ERROR_TYPE_INFO, 114 LOG (GNUNET_ERROR_TYPE_INFO, _("Not installing a handler because $%s=%s\n"),
117 _("Not installing a handler because $%s=%s\n"), 115 GNUNET_OS_CONTROL_PIPE, env_buf);
118 GNUNET_OS_CONTROL_PIPE, env_buf); 116 return;
119 return; 117 }
120 }
121 control_pipe = 118 control_pipe =
122 GNUNET_DISK_npipe_open (env_buf, GNUNET_DISK_OPEN_READ, 119 GNUNET_DISK_npipe_open (env_buf, GNUNET_DISK_OPEN_READ,
123 GNUNET_DISK_PERM_USER_READ | 120 GNUNET_DISK_PERM_USER_READ |
124 GNUNET_DISK_PERM_USER_WRITE); 121 GNUNET_DISK_PERM_USER_WRITE);
125 if (control_pipe == NULL) 122 if (control_pipe == NULL)
126 { 123 {
127 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf); 124 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf);
128 return; 125 return;
129 } 126 }
130#if DEBUG_OS 127#if DEBUG_OS
131 LOG (GNUNET_ERROR_TYPE_DEBUG, 128 LOG (GNUNET_ERROR_TYPE_DEBUG,
132 "Adding parent control handler pipe `%s' to the scheduler\n", env_buf); 129 "Adding parent control handler pipe `%s' to the scheduler\n", env_buf);
133#endif 130#endif
134 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, control_pipe, 131 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, control_pipe,
135 &parent_control_handler, control_pipe); 132 &parent_control_handler, control_pipe);
136} 133}
137 134
138 135
@@ -166,90 +163,90 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
166 163
167 ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig)); 164 ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig));
168 if (ret != sizeof (sig)) 165 if (ret != sizeof (sig))
166 {
167 if (errno == ECOMM)
169 { 168 {
170 if (errno == ECOMM) 169 /* Child process is not controllable via pipe */
171 {
172 /* Child process is not controllable via pipe */
173#if DEBUG_OS 170#if DEBUG_OS
174 LOG (GNUNET_ERROR_TYPE_DEBUG, 171 LOG (GNUNET_ERROR_TYPE_DEBUG,
175 "Child process is not controllable, will kill it directly\n"); 172 "Child process is not controllable, will kill it directly\n");
176#endif 173#endif
177 } 174 }
178 else if (errno == EPIPE) 175 else if (errno == EPIPE)
179 { 176 {
180#if DEBUG_OS 177#if DEBUG_OS
181 LOG (GNUNET_ERROR_TYPE_DEBUG, 178 LOG (GNUNET_ERROR_TYPE_DEBUG,
182 "Failed to write into control pipe, because pipe is invalid (the child is most likely dead)\n"); 179 "Failed to write into control pipe, because pipe is invalid (the child is most likely dead)\n");
183#endif 180#endif
184 } 181 }
185 else 182 else
186 LOG (GNUNET_ERROR_TYPE_WARNING, 183 LOG (GNUNET_ERROR_TYPE_WARNING,
187 "Failed to write into control pipe , errno is %d\n", errno); 184 "Failed to write into control pipe , errno is %d\n", errno);
188#if WINDOWS && !defined(__CYGWIN__) 185#if WINDOWS && !defined(__CYGWIN__)
189 TerminateProcess (proc->handle, 0); 186 TerminateProcess (proc->handle, 0);
190#else 187#else
191 PLIBC_KILL (proc->pid, sig); 188 PLIBC_KILL (proc->pid, sig);
192#endif 189#endif
193 } 190 }
194 else 191 else
195 { 192 {
196#if DEBUG_OS 193#if DEBUG_OS
197 LOG (GNUNET_ERROR_TYPE_DEBUG, 194 LOG (GNUNET_ERROR_TYPE_DEBUG,
198 "Wrote control code into control pipe, now waiting\n"); 195 "Wrote control code into control pipe, now waiting\n");
199#endif 196#endif
200 197
201#if WINDOWS 198#if WINDOWS
202 /* Give it 3 seconds to die, then kill it in a nice Windows-specific way */ 199 /* Give it 3 seconds to die, then kill it in a nice Windows-specific way */
203 if (WaitForSingleObject (proc->handle, 3000) != WAIT_OBJECT_0) 200 if (WaitForSingleObject (proc->handle, 3000) != WAIT_OBJECT_0)
204 TerminateProcess (proc->handle, 0); 201 TerminateProcess (proc->handle, 0);
205 res = 0; 202 res = 0;
206#else 203#else
207 struct GNUNET_NETWORK_FDSet *rfds; 204 struct GNUNET_NETWORK_FDSet *rfds;
208 struct GNUNET_NETWORK_FDSet *efds; 205 struct GNUNET_NETWORK_FDSet *efds;
209 206
210 rfds = GNUNET_NETWORK_fdset_create (); 207 rfds = GNUNET_NETWORK_fdset_create ();
211 efds = GNUNET_NETWORK_fdset_create (); 208 efds = GNUNET_NETWORK_fdset_create ();
212 209
213 GNUNET_NETWORK_fdset_handle_set (rfds, proc->control_pipe); 210 GNUNET_NETWORK_fdset_handle_set (rfds, proc->control_pipe);
214 GNUNET_NETWORK_fdset_handle_set (efds, proc->control_pipe); 211 GNUNET_NETWORK_fdset_handle_set (efds, proc->control_pipe);
215 212
216 /* Ndurner thought this up, and i have no idea what it does. 213 /* Ndurner thought this up, and i have no idea what it does.
217 * There's have never been any code to answer the shutdown call 214 * There's have never been any code to answer the shutdown call
218 * (write a single int into the pipe, so that this function can read it). 215 * (write a single int into the pipe, so that this function can read it).
219 * On *nix select() will probably tell that pipe is ready 216 * On *nix select() will probably tell that pipe is ready
220 * for reading, once the other process shuts down, 217 * for reading, once the other process shuts down,
221 * but the read () call will fail, triggering a kill () 218 * but the read () call will fail, triggering a kill ()
222 * on the pid that is already dead. This will probably result in non-0 219 * on the pid that is already dead. This will probably result in non-0
223 * return from kill(), and therefore from this function. 220 * return from kill(), and therefore from this function.
224 */ 221 */
225 while (1) 222 while (1)
226 { 223 {
227 ret = 224 ret =
228 GNUNET_NETWORK_socket_select (rfds, NULL, efds, 225 GNUNET_NETWORK_socket_select (rfds, NULL, efds,
229 GNUNET_TIME_relative_multiply 226 GNUNET_TIME_relative_multiply
230 (GNUNET_TIME_relative_get_unit (), 227 (GNUNET_TIME_relative_get_unit (),
231 5000)); 228 5000));
232 229
233 if (ret < 1 || 230 if (ret < 1 ||
234 GNUNET_NETWORK_fdset_handle_isset (efds, proc->control_pipe)) 231 GNUNET_NETWORK_fdset_handle_isset (efds, proc->control_pipe))
235 { 232 {
236 /* Just to be sure */ 233 /* Just to be sure */
237 PLIBC_KILL (proc->pid, sig); 234 PLIBC_KILL (proc->pid, sig);
238 res = 0; 235 res = 0;
239 break; 236 break;
240 } 237 }
241 else 238 else
242 { 239 {
243 if (GNUNET_DISK_file_read 240 if (GNUNET_DISK_file_read (proc->control_pipe, &ret, sizeof (ret)) !=
244 (proc->control_pipe, &ret, sizeof (ret)) != GNUNET_OK) 241 GNUNET_OK)
245 res = PLIBC_KILL (proc->pid, sig); 242 res = PLIBC_KILL (proc->pid, sig);
246 243
247 /* Child signaled shutdown is in progress */ 244 /* Child signaled shutdown is in progress */
248 continue; 245 continue;
249 } 246 }
250 }
251#endif
252 } 247 }
248#endif
249 }
253 250
254 return res; 251 return res;
255#else 252#else
@@ -324,7 +321,7 @@ ChildWaitThread (void *arg)
324 */ 321 */
325int 322int
326GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc, 323GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
327 enum GNUNET_SCHEDULER_Priority prio) 324 enum GNUNET_SCHEDULER_Priority prio)
328{ 325{
329 int rprio; 326 int rprio;
330 327
@@ -334,51 +331,51 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
334 331
335 /* convert to MINGW/Unix values */ 332 /* convert to MINGW/Unix values */
336 switch (prio) 333 switch (prio)
337 { 334 {
338 case GNUNET_SCHEDULER_PRIORITY_UI: 335 case GNUNET_SCHEDULER_PRIORITY_UI:
339 case GNUNET_SCHEDULER_PRIORITY_URGENT: 336 case GNUNET_SCHEDULER_PRIORITY_URGENT:
340#ifdef MINGW 337#ifdef MINGW
341 rprio = HIGH_PRIORITY_CLASS; 338 rprio = HIGH_PRIORITY_CLASS;
342#else 339#else
343 rprio = 0; 340 rprio = 0;
344#endif 341#endif
345 break; 342 break;
346 343
347 case GNUNET_SCHEDULER_PRIORITY_HIGH: 344 case GNUNET_SCHEDULER_PRIORITY_HIGH:
348#ifdef MINGW 345#ifdef MINGW
349 rprio = ABOVE_NORMAL_PRIORITY_CLASS; 346 rprio = ABOVE_NORMAL_PRIORITY_CLASS;
350#else 347#else
351 rprio = 5; 348 rprio = 5;
352#endif 349#endif
353 break; 350 break;
354 351
355 case GNUNET_SCHEDULER_PRIORITY_DEFAULT: 352 case GNUNET_SCHEDULER_PRIORITY_DEFAULT:
356#ifdef MINGW 353#ifdef MINGW
357 rprio = NORMAL_PRIORITY_CLASS; 354 rprio = NORMAL_PRIORITY_CLASS;
358#else 355#else
359 rprio = 7; 356 rprio = 7;
360#endif 357#endif
361 break; 358 break;
362 359
363 case GNUNET_SCHEDULER_PRIORITY_BACKGROUND: 360 case GNUNET_SCHEDULER_PRIORITY_BACKGROUND:
364#ifdef MINGW 361#ifdef MINGW
365 rprio = BELOW_NORMAL_PRIORITY_CLASS; 362 rprio = BELOW_NORMAL_PRIORITY_CLASS;
366#else 363#else
367 rprio = 10; 364 rprio = 10;
368#endif 365#endif
369 break; 366 break;
370 367
371 case GNUNET_SCHEDULER_PRIORITY_IDLE: 368 case GNUNET_SCHEDULER_PRIORITY_IDLE:
372#ifdef MINGW 369#ifdef MINGW
373 rprio = IDLE_PRIORITY_CLASS; 370 rprio = IDLE_PRIORITY_CLASS;
374#else 371#else
375 rprio = 19; 372 rprio = 19;
376#endif 373#endif
377 break; 374 break;
378 default: 375 default:
379 GNUNET_assert (0); 376 GNUNET_assert (0);
380 return GNUNET_SYSERR; 377 return GNUNET_SYSERR;
381 } 378 }
382 379
383 /* Set process priority */ 380 /* Set process priority */
384#ifdef MINGW 381#ifdef MINGW
@@ -393,27 +390,26 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
393 390
394 pid = proc->pid; 391 pid = proc->pid;
395 if ((0 == pid) || (pid == getpid ())) 392 if ((0 == pid) || (pid == getpid ()))
393 {
394 int have = nice (0);
395 int delta = rprio - have;
396
397 errno = 0;
398 if ((delta != 0) && (rprio == nice (delta)) && (errno != 0))
396 { 399 {
397 int have = nice (0); 400 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "nice");
398 int delta = rprio - have; 401 return GNUNET_SYSERR;
399
400 errno = 0;
401 if ((delta != 0) && (rprio == nice (delta)) && (errno != 0))
402 {
403 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
404 "nice");
405 return GNUNET_SYSERR;
406 }
407 } 402 }
403 }
408 else 404 else
405 {
406 if (0 != setpriority (PRIO_PROCESS, pid, rprio))
409 { 407 {
410 if (0 != setpriority (PRIO_PROCESS, pid, rprio)) 408 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
411 { 409 "setpriority");
412 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, 410 return GNUNET_SYSERR;
413 "setpriority");
414 return GNUNET_SYSERR;
415 }
416 } 411 }
412 }
417#else 413#else
418#if DEBUG_OS 414#if DEBUG_OS
419 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 415 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
@@ -440,84 +436,84 @@ CreateCustomEnvTable (char **vars)
440 win32_env_table = GetEnvironmentStringsA (); 436 win32_env_table = GetEnvironmentStringsA ();
441 if (win32_env_table == NULL) 437 if (win32_env_table == NULL)
442 return NULL; 438 return NULL;
443 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++); 439 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) ;
444 n_var = c; 440 n_var = c;
445 index = GNUNET_malloc (sizeof (char *) * n_var); 441 index = GNUNET_malloc (sizeof (char *) * n_var);
446 for (c = 0; c < n_var; c++) 442 for (c = 0; c < n_var; c++)
447 index[c] = 0; 443 index[c] = 0;
448 for (items_count = 0, ptr = win32_env_table; ptr[0] != 0; items_count++) 444 for (items_count = 0, ptr = win32_env_table; ptr[0] != 0; items_count++)
445 {
446 size_t len = strlen (ptr);
447 int found = 0;
448
449 for (var_ptr = vars; *var_ptr; var_ptr++)
449 { 450 {
450 size_t len = strlen (ptr); 451 var = *var_ptr++;
451 int found = 0; 452 val = *var_ptr;
452 453 var_len = strlen (var);
453 for (var_ptr = vars; *var_ptr; var_ptr++) 454 if (strncmp (var, ptr, var_len) == 0)
454 { 455 {
455 var = *var_ptr++; 456 found = 1;
456 val = *var_ptr; 457 index[c] = 1;
457 var_len = strlen (var); 458 tablesize += var_len + strlen (val) + 1;
458 if (strncmp (var, ptr, var_len) == 0) 459 break;
459 { 460 }
460 found = 1;
461 index[c] = 1;
462 tablesize += var_len + strlen (val) + 1;
463 break;
464 }
465 }
466 if (!found)
467 tablesize += len + 1;
468 ptr += len + 1;
469 } 461 }
462 if (!found)
463 tablesize += len + 1;
464 ptr += len + 1;
465 }
470 for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) 466 for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++)
467 {
468 var = *var_ptr++;
469 val = *var_ptr;
470 if (index[c] != 1)
471 n_found += strlen (var) + strlen (val) + 1;
472 }
473 result = GNUNET_malloc (tablesize + n_found + 1);
474 for (result_ptr = result, ptr = win32_env_table; ptr[0] != 0;)
475 {
476 size_t len = strlen (ptr);
477 int found = 0;
478
479 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++)
471 { 480 {
472 var = *var_ptr++; 481 var = *var_ptr++;
473 val = *var_ptr; 482 val = *var_ptr;
474 if (index[c] != 1) 483 var_len = strlen (var);
475 n_found += strlen (var) + strlen (val) + 1; 484 if (strncmp (var, ptr, var_len) == 0)
485 {
486 found = 1;
487 break;
488 }
476 } 489 }
477 result = GNUNET_malloc (tablesize + n_found + 1); 490 if (!found)
478 for (result_ptr = result, ptr = win32_env_table; ptr[0] != 0;)
479 { 491 {
480 size_t len = strlen (ptr); 492 strcpy (result_ptr, ptr);
481 int found = 0; 493 result_ptr += len + 1;
482 494 }
483 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) 495 else
484 { 496 {
485 var = *var_ptr++; 497 strcpy (result_ptr, var);
486 val = *var_ptr; 498 result_ptr += var_len;
487 var_len = strlen (var); 499 strcpy (result_ptr, val);
488 if (strncmp (var, ptr, var_len) == 0) 500 result_ptr += strlen (val) + 1;
489 {
490 found = 1;
491 break;
492 }
493 }
494 if (!found)
495 {
496 strcpy (result_ptr, ptr);
497 result_ptr += len + 1;
498 }
499 else
500 {
501 strcpy (result_ptr, var);
502 result_ptr += var_len;
503 strcpy (result_ptr, val);
504 result_ptr += strlen (val) + 1;
505 }
506 ptr += len + 1;
507 } 501 }
502 ptr += len + 1;
503 }
508 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) 504 for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++)
505 {
506 var = *var_ptr++;
507 val = *var_ptr;
508 var_len = strlen (var);
509 if (index[c] != 1)
509 { 510 {
510 var = *var_ptr++; 511 strcpy (result_ptr, var);
511 val = *var_ptr; 512 result_ptr += var_len;
512 var_len = strlen (var); 513 strcpy (result_ptr, val);
513 if (index[c] != 1) 514 result_ptr += strlen (val) + 1;
514 {
515 strcpy (result_ptr, var);
516 result_ptr += var_len;
517 strcpy (result_ptr, val);
518 result_ptr += strlen (val) + 1;
519 }
520 } 515 }
516 }
521 FreeEnvironmentStrings (win32_env_table); 517 FreeEnvironmentStrings (win32_env_table);
522 GNUNET_free (index); 518 GNUNET_free (index);
523 *result_ptr = 0; 519 *result_ptr = 0;
@@ -537,8 +533,8 @@ CreateCustomEnvTable (char **vars)
537 */ 533 */
538struct GNUNET_OS_Process * 534struct GNUNET_OS_Process *
539GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, 535GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
540 struct GNUNET_DISK_PipeHandle *pipe_stdout, 536 struct GNUNET_DISK_PipeHandle *pipe_stdout,
541 const char *filename, va_list va) 537 const char *filename, va_list va)
542{ 538{
543 va_list ap; 539 va_list ap;
544 540
@@ -559,9 +555,9 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
559 555
560#if ENABLE_WINDOWS_WORKAROUNDS 556#if ENABLE_WINDOWS_WORKAROUNDS
561 control_pipe = 557 control_pipe =
562 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE, 558 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE,
563 GNUNET_DISK_PERM_USER_READ | 559 GNUNET_DISK_PERM_USER_READ |
564 GNUNET_DISK_PERM_USER_WRITE); 560 GNUNET_DISK_PERM_USER_WRITE);
565 if (control_pipe == NULL) 561 if (control_pipe == NULL)
566 return NULL; 562 return NULL;
567#endif 563#endif
@@ -569,38 +565,35 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
569 argc = 0; 565 argc = 0;
570 va_copy (ap, va); 566 va_copy (ap, va);
571 while (NULL != va_arg (ap, char *)) 567 while (NULL != va_arg (ap, char *))
572 argc++; 568 argc++;
573 569
574 va_end (ap); 570 va_end (ap);
575 argv = GNUNET_malloc (sizeof (char *) * (argc + 1)); 571 argv = GNUNET_malloc (sizeof (char *) * (argc + 1));
576 argc = 0; 572 argc = 0;
577 va_copy (ap, va); 573 va_copy (ap, va);
578 while (NULL != (argv[argc] = va_arg (ap, char *))) 574 while (NULL != (argv[argc] = va_arg (ap, char *)))
579 argc++; 575 argc++;
580 576
581 va_end (ap); 577 va_end (ap);
582 if (pipe_stdout != NULL) 578 if (pipe_stdout != NULL)
583 { 579 {
584 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 580 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
585 (pipe_stdout, 581 (pipe_stdout,
586 GNUNET_DISK_PIPE_END_WRITE), 582 GNUNET_DISK_PIPE_END_WRITE),
587 &fd_stdout_write, sizeof (int)); 583 &fd_stdout_write, sizeof (int));
588 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 584 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
589 (pipe_stdout, 585 (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
590 GNUNET_DISK_PIPE_END_READ), 586 &fd_stdout_read, sizeof (int));
591 &fd_stdout_read, sizeof (int)); 587 }
592 }
593 if (pipe_stdin != NULL) 588 if (pipe_stdin != NULL)
594 { 589 {
595 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 590 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
596 (pipe_stdin, 591 (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
597 GNUNET_DISK_PIPE_END_READ), 592 &fd_stdin_read, sizeof (int));
598 &fd_stdin_read, sizeof (int)); 593 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
599 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 594 (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
600 (pipe_stdin, 595 &fd_stdin_write, sizeof (int));
601 GNUNET_DISK_PIPE_END_WRITE), 596 }
602 &fd_stdin_write, sizeof (int));
603 }
604 597
605#if HAVE_WORKING_VFORK 598#if HAVE_WORKING_VFORK
606 ret = vfork (); 599 ret = vfork ();
@@ -608,46 +601,44 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
608 ret = fork (); 601 ret = fork ();
609#endif 602#endif
610 if (ret != 0) 603 if (ret != 0)
604 {
605 if (ret == -1)
611 { 606 {
612 if (ret == -1) 607 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
613 {
614 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
615#if ENABLE_WINDOWS_WORKAROUNDS 608#if ENABLE_WINDOWS_WORKAROUNDS
616 GNUNET_DISK_npipe_close (control_pipe); 609 GNUNET_DISK_npipe_close (control_pipe);
617#endif 610#endif
618 } 611 }
619 else 612 else
620 { 613 {
621 614
622#if HAVE_WORKING_VFORK 615#if HAVE_WORKING_VFORK
623 /* let's hope vfork actually works; for some extreme cases (including 616 /* let's hope vfork actually works; for some extreme cases (including
624 * a testcase) we need 'execvp' to have run before we return, since 617 * a testcase) we need 'execvp' to have run before we return, since
625 * we may send a signal to the process next and we don't want it 618 * we may send a signal to the process next and we don't want it
626 * to be caught by OUR signal handler (but either by the default 619 * to be caught by OUR signal handler (but either by the default
627 * handler or the actual handler as installed by the process itself). */ 620 * handler or the actual handler as installed by the process itself). */
628#else 621#else
629 /* let's give the child process a chance to run execvp, 1s should 622 /* let's give the child process a chance to run execvp, 1s should
630 * be plenty in practice */ 623 * be plenty in practice */
631 if (pipe_stdout != NULL) 624 if (pipe_stdout != NULL)
632 GNUNET_DISK_pipe_close_end (pipe_stdout, 625 GNUNET_DISK_pipe_close_end (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
633 GNUNET_DISK_PIPE_END_WRITE); 626 if (pipe_stdin != NULL)
634 if (pipe_stdin != NULL) 627 GNUNET_DISK_pipe_close_end (pipe_stdin, GNUNET_DISK_PIPE_END_READ);
635 GNUNET_DISK_pipe_close_end (pipe_stdin, 628 sleep (1);
636 GNUNET_DISK_PIPE_END_READ);
637 sleep (1);
638#endif 629#endif
639 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); 630 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
640 gnunet_proc->pid = ret; 631 gnunet_proc->pid = ret;
641#if ENABLE_WINDOWS_WORKAROUNDS 632#if ENABLE_WINDOWS_WORKAROUNDS
642 gnunet_proc->control_pipe = control_pipe; 633 gnunet_proc->control_pipe = control_pipe;
643#endif 634#endif
644 } 635 }
645 GNUNET_free (argv); 636 GNUNET_free (argv);
646#if ENABLE_WINDOWS_WORKAROUNDS 637#if ENABLE_WINDOWS_WORKAROUNDS
647 GNUNET_free (childpipename); 638 GNUNET_free (childpipename);
648#endif 639#endif
649 return gnunet_proc; 640 return gnunet_proc;
650 } 641 }
651 642
652#if ENABLE_WINDOWS_WORKAROUNDS 643#if ENABLE_WINDOWS_WORKAROUNDS
653 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); 644 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1);
@@ -655,21 +646,21 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
655#endif 646#endif
656 647
657 if (pipe_stdout != NULL) 648 if (pipe_stdout != NULL)
658 { 649 {
659 GNUNET_break (0 == close (fd_stdout_read)); 650 GNUNET_break (0 == close (fd_stdout_read));
660 if (-1 == dup2 (fd_stdout_write, 1)) 651 if (-1 == dup2 (fd_stdout_write, 1))
661 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); 652 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
662 GNUNET_break (0 == close (fd_stdout_write)); 653 GNUNET_break (0 == close (fd_stdout_write));
663 } 654 }
664 655
665 if (pipe_stdin != NULL) 656 if (pipe_stdin != NULL)
666 { 657 {
667 658
668 GNUNET_break (0 == close (fd_stdin_write)); 659 GNUNET_break (0 == close (fd_stdin_write));
669 if (-1 == dup2 (fd_stdin_read, 0)) 660 if (-1 == dup2 (fd_stdin_read, 0))
670 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); 661 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
671 GNUNET_break (0 == close (fd_stdin_read)); 662 GNUNET_break (0 == close (fd_stdin_read));
672 } 663 }
673 execvp (filename, argv); 664 execvp (filename, argv);
674 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 665 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
675 _exit (1); 666 _exit (1);
@@ -705,8 +696,8 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
705 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); 696 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0);
706 697
707 alloc_len = 698 alloc_len =
708 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + 699 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 +
709 strlen (libdir); 700 strlen (libdir);
710 701
711 pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); 702 pathbuf = GNUNET_malloc (alloc_len * sizeof (char));
712 703
@@ -729,39 +720,39 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
729 if (non_const_filename[1] == ':') 720 if (non_const_filename[1] == ':')
730 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); 721 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
731 else if (!SearchPathA 722 else if (!SearchPathA
732 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), 723 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char),
733 path, NULL)) 724 path, NULL))
734 { 725 {
735 SetErrnoFromWinError (GetLastError ()); 726 SetErrnoFromWinError (GetLastError ());
736 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath", 727 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath",
737 non_const_filename); 728 non_const_filename);
738 GNUNET_free (non_const_filename); 729 GNUNET_free (non_const_filename);
739 GNUNET_free (pathbuf); 730 GNUNET_free (pathbuf);
740 return NULL; 731 return NULL;
741 } 732 }
742 GNUNET_free (pathbuf); 733 GNUNET_free (pathbuf);
743 GNUNET_free (non_const_filename); 734 GNUNET_free (non_const_filename);
744 735
745 cmdlen = 0; 736 cmdlen = 0;
746 va_copy (ap, va); 737 va_copy (ap, va);
747 while (NULL != (arg = va_arg (ap, char *))) 738 while (NULL != (arg = va_arg (ap, char *)))
748 { 739 {
749 if (cmdlen == 0) 740 if (cmdlen == 0)
750 cmdlen = cmdlen + strlen (path) + 3; 741 cmdlen = cmdlen + strlen (path) + 3;
751 else 742 else
752 cmdlen = cmdlen + strlen (arg) + 3; 743 cmdlen = cmdlen + strlen (arg) + 3;
753 } 744 }
754 va_end (ap); 745 va_end (ap);
755 746
756 cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1)); 747 cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1));
757 va_copy (ap, va); 748 va_copy (ap, va);
758 while (NULL != (arg = va_arg (ap, char *))) 749 while (NULL != (arg = va_arg (ap, char *)))
759 { 750 {
760 if (idx == cmd) 751 if (idx == cmd)
761 idx += sprintf (idx, "\"%s\" ", path); 752 idx += sprintf (idx, "\"%s\" ", path);
762 else 753 else
763 idx += sprintf (idx, "\"%s\" ", arg); 754 idx += sprintf (idx, "\"%s\" ", arg);
764 } 755 }
765 va_end (ap); 756 va_end (ap);
766 757
767 memset (&start, 0, sizeof (start)); 758 memset (&start, 0, sizeof (start));
@@ -771,37 +762,36 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
771 start.dwFlags |= STARTF_USESTDHANDLES; 762 start.dwFlags |= STARTF_USESTDHANDLES;
772 763
773 if (pipe_stdin != NULL) 764 if (pipe_stdin != NULL)
774 { 765 {
775 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 766 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
776 (pipe_stdin, 767 (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
777 GNUNET_DISK_PIPE_END_READ), 768 &stdin_handle, sizeof (HANDLE));
778 &stdin_handle, sizeof (HANDLE)); 769 start.hStdInput = stdin_handle;
779 start.hStdInput = stdin_handle; 770 }
780 }
781 771
782 if (pipe_stdout != NULL) 772 if (pipe_stdout != NULL)
783 { 773 {
784 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 774 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
785 (pipe_stdout, 775 (pipe_stdout,
786 GNUNET_DISK_PIPE_END_WRITE), 776 GNUNET_DISK_PIPE_END_WRITE),
787 &stdout_handle, sizeof (HANDLE)); 777 &stdout_handle, sizeof (HANDLE));
788 start.hStdOutput = stdout_handle; 778 start.hStdOutput = stdout_handle;
789 } 779 }
790 780
791 control_pipe = 781 control_pipe =
792 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE, 782 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE,
793 GNUNET_DISK_PERM_USER_READ | 783 GNUNET_DISK_PERM_USER_READ |
794 GNUNET_DISK_PERM_USER_WRITE); 784 GNUNET_DISK_PERM_USER_WRITE);
795 if (control_pipe == NULL) 785 if (control_pipe == NULL)
796 { 786 {
797 GNUNET_free (cmd); 787 GNUNET_free (cmd);
798 GNUNET_free (path); 788 GNUNET_free (path);
799 return NULL; 789 return NULL;
800 } 790 }
801 791
802#if DEBUG_OS 792#if DEBUG_OS
803 LOG (GNUNET_ERROR_TYPE_DEBUG, 793 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n",
804 "Opened the parent end of the pipe `%s'\n", childpipename); 794 childpipename);
805#endif 795#endif
806 796
807 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); 797 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
@@ -814,13 +804,13 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
814 if (!CreateProcessA 804 if (!CreateProcessA
815 (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, 805 (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
816 env_block, NULL, &start, &proc)) 806 env_block, NULL, &start, &proc))
817 { 807 {
818 SetErrnoFromWinError (GetLastError ()); 808 SetErrnoFromWinError (GetLastError ());
819 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path); 809 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
820 GNUNET_free (env_block); 810 GNUNET_free (env_block);
821 GNUNET_free (cmd); 811 GNUNET_free (cmd);
822 return NULL; 812 return NULL;
823 } 813 }
824 814
825 GNUNET_free (env_block); 815 GNUNET_free (env_block);
826 816
@@ -854,8 +844,8 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
854 */ 844 */
855struct GNUNET_OS_Process * 845struct GNUNET_OS_Process *
856GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, 846GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin,
857 struct GNUNET_DISK_PipeHandle *pipe_stdout, 847 struct GNUNET_DISK_PipeHandle *pipe_stdout,
858 const char *filename, ...) 848 const char *filename, ...)
859{ 849{
860 struct GNUNET_OS_Process *ret; 850 struct GNUNET_OS_Process *ret;
861 va_list ap; 851 va_list ap;
@@ -878,7 +868,7 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin,
878 */ 868 */
879struct GNUNET_OS_Process * 869struct GNUNET_OS_Process *
880GNUNET_OS_start_process_v (const int *lsocks, const char *filename, 870GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
881 char *const argv[]) 871 char *const argv[])
882{ 872{
883#if ENABLE_WINDOWS_WORKAROUNDS 873#if ENABLE_WINDOWS_WORKAROUNDS
884 struct GNUNET_DISK_FileHandle *control_pipe = NULL; 874 struct GNUNET_DISK_FileHandle *control_pipe = NULL;
@@ -900,9 +890,9 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
900 890
901#if ENABLE_WINDOWS_WORKAROUNDS 891#if ENABLE_WINDOWS_WORKAROUNDS
902 control_pipe = 892 control_pipe =
903 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE, 893 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE,
904 GNUNET_DISK_PERM_USER_READ | 894 GNUNET_DISK_PERM_USER_READ |
905 GNUNET_DISK_PERM_USER_WRITE); 895 GNUNET_DISK_PERM_USER_WRITE);
906 if (control_pipe == NULL) 896 if (control_pipe == NULL)
907 return NULL; 897 return NULL;
908#endif 898#endif
@@ -910,52 +900,52 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
910 lscp = NULL; 900 lscp = NULL;
911 ls = 0; 901 ls = 0;
912 if (lsocks != NULL) 902 if (lsocks != NULL)
913 { 903 {
914 i = 0; 904 i = 0;
915 while (-1 != (k = lsocks[i++])) 905 while (-1 != (k = lsocks[i++]))
916 GNUNET_array_append (lscp, ls, k); 906 GNUNET_array_append (lscp, ls, k);
917 GNUNET_array_append (lscp, ls, -1); 907 GNUNET_array_append (lscp, ls, -1);
918 } 908 }
919#if HAVE_WORKING_VFORK 909#if HAVE_WORKING_VFORK
920 ret = vfork (); 910 ret = vfork ();
921#else 911#else
922 ret = fork (); 912 ret = fork ();
923#endif 913#endif
924 if (ret != 0) 914 if (ret != 0)
915 {
916 if (ret == -1)
925 { 917 {
926 if (ret == -1) 918 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
927 {
928 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
929#if ENABLE_WINDOWS_WORKAROUNDS 919#if ENABLE_WINDOWS_WORKAROUNDS
930 GNUNET_DISK_npipe_close (control_pipe); 920 GNUNET_DISK_npipe_close (control_pipe);
931#endif 921#endif
932 } 922 }
933 else 923 else
934 { 924 {
935#if HAVE_WORKING_VFORK 925#if HAVE_WORKING_VFORK
936 /* let's hope vfork actually works; for some extreme cases (including 926 /* let's hope vfork actually works; for some extreme cases (including
937 * a testcase) we need 'execvp' to have run before we return, since 927 * a testcase) we need 'execvp' to have run before we return, since
938 * we may send a signal to the process next and we don't want it 928 * we may send a signal to the process next and we don't want it
939 * to be caught by OUR signal handler (but either by the default 929 * to be caught by OUR signal handler (but either by the default
940 * handler or the actual handler as installed by the process itself). */ 930 * handler or the actual handler as installed by the process itself). */
941#else 931#else
942 /* let's give the child process a chance to run execvp, 1s should 932 /* let's give the child process a chance to run execvp, 1s should
943 * be plenty in practice */ 933 * be plenty in practice */
944 sleep (1); 934 sleep (1);
945#endif 935#endif
946 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); 936 gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
947 gnunet_proc->pid = ret; 937 gnunet_proc->pid = ret;
948#if ENABLE_WINDOWS_WORKAROUNDS 938#if ENABLE_WINDOWS_WORKAROUNDS
949 gnunet_proc->control_pipe = control_pipe; 939 gnunet_proc->control_pipe = control_pipe;
950 940
951#endif 941#endif
952 } 942 }
953 GNUNET_array_grow (lscp, ls, 0); 943 GNUNET_array_grow (lscp, ls, 0);
954#if ENABLE_WINDOWS_WORKAROUNDS 944#if ENABLE_WINDOWS_WORKAROUNDS
955 GNUNET_free (childpipename); 945 GNUNET_free (childpipename);
956#endif 946#endif
957 return gnunet_proc; 947 return gnunet_proc;
958 } 948 }
959 949
960#if ENABLE_WINDOWS_WORKAROUNDS 950#if ENABLE_WINDOWS_WORKAROUNDS
961 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); 951 setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1);
@@ -963,47 +953,47 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
963#endif 953#endif
964 954
965 if (lscp != NULL) 955 if (lscp != NULL)
956 {
957 /* read systemd documentation... */
958 GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid ());
959 setenv ("LISTEN_PID", lpid, 1);
960 i = 0;
961 tgt = 3;
962 while (-1 != lscp[i])
966 { 963 {
967 /* read systemd documentation... */ 964 j = i + 1;
968 GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid ()); 965 while (-1 != lscp[j])
969 setenv ("LISTEN_PID", lpid, 1); 966 {
970 i = 0; 967 if (lscp[j] == tgt)
971 tgt = 3; 968 {
972 while (-1 != lscp[i]) 969 /* dup away */
973 { 970 k = dup (lscp[j]);
974 j = i + 1; 971 GNUNET_assert (-1 != k);
975 while (-1 != lscp[j]) 972 GNUNET_assert (0 == close (lscp[j]));
976 { 973 lscp[j] = k;
977 if (lscp[j] == tgt) 974 break;
978 { 975 }
979 /* dup away */ 976 j++;
980 k = dup (lscp[j]); 977 }
981 GNUNET_assert (-1 != k); 978 if (lscp[i] != tgt)
982 GNUNET_assert (0 == close (lscp[j])); 979 {
983 lscp[j] = k; 980 /* Bury any existing FD, no matter what; they should all be closed
984 break; 981 * on exec anyway and the important onces have been dup'ed away */
985 } 982 (void) close (tgt);
986 j++; 983 GNUNET_assert (-1 != dup2 (lscp[i], tgt));
987 } 984 }
988 if (lscp[i] != tgt) 985 /* unset close-on-exec flag */
989 { 986 flags = fcntl (tgt, F_GETFD);
990 /* Bury any existing FD, no matter what; they should all be closed 987 GNUNET_assert (flags >= 0);
991 * on exec anyway and the important onces have been dup'ed away */ 988 flags &= ~FD_CLOEXEC;
992 (void) close (tgt); 989 fflush (stderr);
993 GNUNET_assert (-1 != dup2 (lscp[i], tgt)); 990 (void) fcntl (tgt, F_SETFD, flags);
994 } 991 tgt++;
995 /* unset close-on-exec flag */ 992 i++;
996 flags = fcntl (tgt, F_GETFD);
997 GNUNET_assert (flags >= 0);
998 flags &= ~FD_CLOEXEC;
999 fflush (stderr);
1000 (void) fcntl (tgt, F_SETFD, flags);
1001 tgt++;
1002 i++;
1003 }
1004 GNUNET_snprintf (fds, sizeof (fds), "%u", i);
1005 setenv ("LISTEN_FDS", fds, 1);
1006 } 993 }
994 GNUNET_snprintf (fds, sizeof (fds), "%u", i);
995 setenv ("LISTEN_FDS", fds, 1);
996 }
1007 GNUNET_array_grow (lscp, ls, 0); 997 GNUNET_array_grow (lscp, ls, 0);
1008 execvp (filename, argv); 998 execvp (filename, argv);
1009 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 999 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
@@ -1041,8 +1031,8 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1041 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); 1031 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0);
1042 1032
1043 alloc_len = 1033 alloc_len =
1044 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + 1034 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 +
1045 strlen (libdir); 1035 strlen (libdir);
1046 1036
1047 pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); 1037 pathbuf = GNUNET_malloc (alloc_len * sizeof (char));
1048 1038
@@ -1054,11 +1044,11 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1054 1044
1055 alloc_len = GetEnvironmentVariableA ("PATH", ptr, pathbuf_len); 1045 alloc_len = GetEnvironmentVariableA ("PATH", ptr, pathbuf_len);
1056 if (alloc_len != pathbuf_len - 1) 1046 if (alloc_len != pathbuf_len - 1)
1057 { 1047 {
1058 GNUNET_free (pathbuf); 1048 GNUNET_free (pathbuf);
1059 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ 1049 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */
1060 return NULL; 1050 return NULL;
1061 } 1051 }
1062 1052
1063 cmdlen = strlen (filename); 1053 cmdlen = strlen (filename);
1064 if (cmdlen < 5 || strcmp (&filename[cmdlen - 4], ".exe") != 0) 1054 if (cmdlen < 5 || strcmp (&filename[cmdlen - 4], ".exe") != 0)
@@ -1070,26 +1060,26 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1070 if (non_const_filename[1] == ':') 1060 if (non_const_filename[1] == ':')
1071 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); 1061 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
1072 else if (!SearchPathA 1062 else if (!SearchPathA
1073 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), 1063 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char),
1074 path, NULL)) 1064 path, NULL))
1075 { 1065 {
1076 SetErrnoFromWinError (GetLastError ()); 1066 SetErrnoFromWinError (GetLastError ());
1077 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath", 1067 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath",
1078 non_const_filename); 1068 non_const_filename);
1079 GNUNET_free (non_const_filename); 1069 GNUNET_free (non_const_filename);
1080 GNUNET_free (pathbuf); 1070 GNUNET_free (pathbuf);
1081 return NULL; 1071 return NULL;
1082 } 1072 }
1083 GNUNET_free (pathbuf); 1073 GNUNET_free (pathbuf);
1084 GNUNET_free (non_const_filename); 1074 GNUNET_free (non_const_filename);
1085 1075
1086 /* Count the number of arguments */ 1076 /* Count the number of arguments */
1087 arg = (char **) argv; 1077 arg = (char **) argv;
1088 while (*arg) 1078 while (*arg)
1089 { 1079 {
1090 arg++; 1080 arg++;
1091 argcount++; 1081 argcount++;
1092 } 1082 }
1093 1083
1094 /* Allocate a copy argv */ 1084 /* Allocate a copy argv */
1095 non_const_argv = GNUNET_malloc (sizeof (char *) * (argcount + 1)); 1085 non_const_argv = GNUNET_malloc (sizeof (char *) * (argcount + 1));
@@ -1098,33 +1088,33 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1098 argcount = 0; 1088 argcount = 0;
1099 arg = (char **) argv; 1089 arg = (char **) argv;
1100 while (*arg) 1090 while (*arg)
1101 { 1091 {
1102 if (arg == argv) 1092 if (arg == argv)
1103 non_const_argv[argcount] = GNUNET_strdup (path); 1093 non_const_argv[argcount] = GNUNET_strdup (path);
1104 else 1094 else
1105 non_const_argv[argcount] = GNUNET_strdup (*arg); 1095 non_const_argv[argcount] = GNUNET_strdup (*arg);
1106 arg++; 1096 arg++;
1107 argcount++; 1097 argcount++;
1108 } 1098 }
1109 non_const_argv[argcount] = NULL; 1099 non_const_argv[argcount] = NULL;
1110 1100
1111 /* Count cmd len */ 1101 /* Count cmd len */
1112 cmdlen = 1; 1102 cmdlen = 1;
1113 arg = non_const_argv; 1103 arg = non_const_argv;
1114 while (*arg) 1104 while (*arg)
1115 { 1105 {
1116 cmdlen = cmdlen + strlen (*arg) + 3; 1106 cmdlen = cmdlen + strlen (*arg) + 3;
1117 arg++; 1107 arg++;
1118 } 1108 }
1119 1109
1120 /* Allocate and create cmd */ 1110 /* Allocate and create cmd */
1121 cmd = idx = GNUNET_malloc (sizeof (char) * cmdlen); 1111 cmd = idx = GNUNET_malloc (sizeof (char) * cmdlen);
1122 arg = non_const_argv; 1112 arg = non_const_argv;
1123 while (*arg) 1113 while (*arg)
1124 { 1114 {
1125 idx += sprintf (idx, "\"%s\" ", *arg); 1115 idx += sprintf (idx, "\"%s\" ", *arg);
1126 arg++; 1116 arg++;
1127 } 1117 }
1128 1118
1129 while (argcount > 0) 1119 while (argcount > 0)
1130 GNUNET_free (non_const_argv[--argcount]); 1120 GNUNET_free (non_const_argv[--argcount]);
@@ -1134,19 +1124,19 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1134 start.cb = sizeof (start); 1124 start.cb = sizeof (start);
1135 1125
1136 control_pipe = 1126 control_pipe =
1137 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE, 1127 GNUNET_DISK_npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE,
1138 GNUNET_DISK_PERM_USER_READ | 1128 GNUNET_DISK_PERM_USER_READ |
1139 GNUNET_DISK_PERM_USER_WRITE); 1129 GNUNET_DISK_PERM_USER_WRITE);
1140 if (control_pipe == NULL) 1130 if (control_pipe == NULL)
1141 { 1131 {
1142 GNUNET_free (cmd); 1132 GNUNET_free (cmd);
1143 GNUNET_free (path); 1133 GNUNET_free (path);
1144 return NULL; 1134 return NULL;
1145 } 1135 }
1146 1136
1147#if DEBUG_OS 1137#if DEBUG_OS
1148 LOG (GNUNET_ERROR_TYPE_DEBUG, 1138 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n",
1149 "Opened the parent end of the pipe `%s'\n", childpipename); 1139 childpipename);
1150#endif 1140#endif
1151 1141
1152 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); 1142 GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
@@ -1159,13 +1149,13 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1159 if (!CreateProcess 1149 if (!CreateProcess
1160 (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, 1150 (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED,
1161 env_block, NULL, &start, &proc)) 1151 env_block, NULL, &start, &proc))
1162 { 1152 {
1163 SetErrnoFromWinError (GetLastError ()); 1153 SetErrnoFromWinError (GetLastError ());
1164 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); 1154 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
1165 GNUNET_free (env_block); 1155 GNUNET_free (env_block);
1166 GNUNET_free (cmd); 1156 GNUNET_free (cmd);
1167 return NULL; 1157 return NULL;
1168 } 1158 }
1169 1159
1170 GNUNET_free (env_block); 1160 GNUNET_free (env_block);
1171 1161
@@ -1194,8 +1184,8 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
1194 */ 1184 */
1195int 1185int
1196GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, 1186GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1197 enum GNUNET_OS_ProcessStatusType *type, 1187 enum GNUNET_OS_ProcessStatusType *type,
1198 unsigned long *code) 1188 unsigned long *code)
1199{ 1189{
1200#ifndef MINGW 1190#ifndef MINGW
1201 int status; 1191 int status;
@@ -1204,48 +1194,48 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1204 GNUNET_assert (0 != proc); 1194 GNUNET_assert (0 != proc);
1205 ret = waitpid (proc->pid, &status, WNOHANG); 1195 ret = waitpid (proc->pid, &status, WNOHANG);
1206 if (ret < 0) 1196 if (ret < 0)
1207 { 1197 {
1208 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 1198 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1209 return GNUNET_SYSERR; 1199 return GNUNET_SYSERR;
1210 } 1200 }
1211 if (0 == ret) 1201 if (0 == ret)
1212 { 1202 {
1213 *type = GNUNET_OS_PROCESS_RUNNING; 1203 *type = GNUNET_OS_PROCESS_RUNNING;
1214 *code = 0; 1204 *code = 0;
1215 return GNUNET_NO; 1205 return GNUNET_NO;
1216 } 1206 }
1217 if (proc->pid != ret) 1207 if (proc->pid != ret)
1218 { 1208 {
1219 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 1209 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1220 return GNUNET_SYSERR; 1210 return GNUNET_SYSERR;
1221 } 1211 }
1222 if (WIFEXITED (status)) 1212 if (WIFEXITED (status))
1223 { 1213 {
1224 *type = GNUNET_OS_PROCESS_EXITED; 1214 *type = GNUNET_OS_PROCESS_EXITED;
1225 *code = WEXITSTATUS (status); 1215 *code = WEXITSTATUS (status);
1226 } 1216 }
1227 else if (WIFSIGNALED (status)) 1217 else if (WIFSIGNALED (status))
1228 { 1218 {
1229 *type = GNUNET_OS_PROCESS_SIGNALED; 1219 *type = GNUNET_OS_PROCESS_SIGNALED;
1230 *code = WTERMSIG (status); 1220 *code = WTERMSIG (status);
1231 } 1221 }
1232 else if (WIFSTOPPED (status)) 1222 else if (WIFSTOPPED (status))
1233 { 1223 {
1234 *type = GNUNET_OS_PROCESS_SIGNALED; 1224 *type = GNUNET_OS_PROCESS_SIGNALED;
1235 *code = WSTOPSIG (status); 1225 *code = WSTOPSIG (status);
1236 } 1226 }
1237#ifdef WIFCONTINUED 1227#ifdef WIFCONTINUED
1238 else if (WIFCONTINUED (status)) 1228 else if (WIFCONTINUED (status))
1239 { 1229 {
1240 *type = GNUNET_OS_PROCESS_RUNNING; 1230 *type = GNUNET_OS_PROCESS_RUNNING;
1241 *code = 0; 1231 *code = 0;
1242 } 1232 }
1243#endif 1233#endif
1244 else 1234 else
1245 { 1235 {
1246 *type = GNUNET_OS_PROCESS_UNKNOWN; 1236 *type = GNUNET_OS_PROCESS_UNKNOWN;
1247 *code = 0; 1237 *code = 0;
1248 } 1238 }
1249#else 1239#else
1250 HANDLE h; 1240 HANDLE h;
1251 DWORD c, error_code, ret; 1241 DWORD c, error_code, ret;
@@ -1253,11 +1243,11 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1253 h = proc->handle; 1243 h = proc->handle;
1254 ret = proc->pid; 1244 ret = proc->pid;
1255 if (h == NULL || ret == 0) 1245 if (h == NULL || ret == 0)
1256 { 1246 {
1257 LOG (GNUNET_ERROR_TYPE_WARNING, 1247 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n",
1258 "Invalid process information {%d, %08X}\n", ret, h); 1248 ret, h);
1259 return GNUNET_SYSERR; 1249 return GNUNET_SYSERR;
1260 } 1250 }
1261 if (h == NULL) 1251 if (h == NULL)
1262 h = GetCurrentProcess (); 1252 h = GetCurrentProcess ();
1263 1253
@@ -1265,17 +1255,17 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1265 ret = GetExitCodeProcess (h, &c); 1255 ret = GetExitCodeProcess (h, &c);
1266 error_code = GetLastError (); 1256 error_code = GetLastError ();
1267 if (ret == 0 || error_code != NO_ERROR) 1257 if (ret == 0 || error_code != NO_ERROR)
1268 { 1258 {
1269 SetErrnoFromWinError (error_code); 1259 SetErrnoFromWinError (error_code);
1270 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess"); 1260 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess");
1271 return GNUNET_SYSERR; 1261 return GNUNET_SYSERR;
1272 } 1262 }
1273 if (STILL_ACTIVE == c) 1263 if (STILL_ACTIVE == c)
1274 { 1264 {
1275 *type = GNUNET_OS_PROCESS_RUNNING; 1265 *type = GNUNET_OS_PROCESS_RUNNING;
1276 *code = 0; 1266 *code = 0;
1277 return GNUNET_NO; 1267 return GNUNET_NO;
1278 } 1268 }
1279 *type = GNUNET_OS_PROCESS_EXITED; 1269 *type = GNUNET_OS_PROCESS_EXITED;
1280 *code = c; 1270 *code = c;
1281#endif 1271#endif
@@ -1305,19 +1295,19 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1305 1295
1306 h = proc->handle; 1296 h = proc->handle;
1307 if (NULL == h) 1297 if (NULL == h)
1308 { 1298 {
1309 LOG (GNUNET_ERROR_TYPE_WARNING, 1299 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n",
1310 "Invalid process information {%d, %08X}\n", proc->pid, h); 1300 proc->pid, h);
1311 return GNUNET_SYSERR; 1301 return GNUNET_SYSERR;
1312 } 1302 }
1313 if (h == NULL) 1303 if (h == NULL)
1314 h = GetCurrentProcess (); 1304 h = GetCurrentProcess ();
1315 1305
1316 if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) 1306 if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
1317 { 1307 {
1318 SetErrnoFromWinError (GetLastError ()); 1308 SetErrnoFromWinError (GetLastError ());
1319 ret = GNUNET_SYSERR; 1309 ret = GNUNET_SYSERR;
1320 } 1310 }
1321 else 1311 else
1322 ret = GNUNET_OK; 1312 ret = GNUNET_OK;
1323 1313
@@ -1391,10 +1381,10 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
1391{ 1381{
1392 1382
1393 if (cmd->proc != NULL) 1383 if (cmd->proc != NULL)
1394 { 1384 {
1395 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cmd->rtask); 1385 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cmd->rtask);
1396 GNUNET_SCHEDULER_cancel (cmd->rtask); 1386 GNUNET_SCHEDULER_cancel (cmd->rtask);
1397 } 1387 }
1398 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL); 1388 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
1399 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip)); 1389 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip));
1400 GNUNET_OS_process_close (cmd->eip); 1390 GNUNET_OS_process_close (cmd->eip);
@@ -1418,43 +1408,42 @@ cmd_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1418 ssize_t ret; 1408 ssize_t ret;
1419 1409
1420 cmd->rtask = GNUNET_SCHEDULER_NO_TASK; 1410 cmd->rtask = GNUNET_SCHEDULER_NO_TASK;
1421 if (GNUNET_YES != 1411 if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r))
1422 GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r)) 1412 {
1423 { 1413 /* timeout, shutdown, etc. */
1424 /* timeout, shutdown, etc. */ 1414 proc = cmd->proc;
1425 proc = cmd->proc; 1415 cmd->proc = NULL;
1426 cmd->proc = NULL; 1416 proc (cmd->proc_cls, NULL);
1427 proc (cmd->proc_cls, NULL); 1417 return;
1428 return; 1418 }
1429 }
1430 ret = 1419 ret =
1431 GNUNET_DISK_file_read (cmd->r, &cmd->buf[cmd->off], 1420 GNUNET_DISK_file_read (cmd->r, &cmd->buf[cmd->off],
1432 sizeof (cmd->buf) - cmd->off); 1421 sizeof (cmd->buf) - cmd->off);
1433 if (ret <= 0) 1422 if (ret <= 0)
1423 {
1424 if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf)))
1434 { 1425 {
1435 if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf))) 1426 cmd->buf[cmd->off] = '\0';
1436 { 1427 cmd->proc (cmd->proc_cls, cmd->buf);
1437 cmd->buf[cmd->off] = '\0';
1438 cmd->proc (cmd->proc_cls, cmd->buf);
1439 }
1440 proc = cmd->proc;
1441 cmd->proc = NULL;
1442 proc (cmd->proc_cls, NULL);
1443 return;
1444 } 1428 }
1429 proc = cmd->proc;
1430 cmd->proc = NULL;
1431 proc (cmd->proc_cls, NULL);
1432 return;
1433 }
1445 end = memchr (&cmd->buf[cmd->off], '\n', ret); 1434 end = memchr (&cmd->buf[cmd->off], '\n', ret);
1446 cmd->off += ret; 1435 cmd->off += ret;
1447 while (end != NULL) 1436 while (end != NULL)
1448 { 1437 {
1449 *end = '\0'; 1438 *end = '\0';
1450 cmd->proc (cmd->proc_cls, cmd->buf); 1439 cmd->proc (cmd->proc_cls, cmd->buf);
1451 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf)); 1440 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
1452 cmd->off -= (end + 1 - cmd->buf); 1441 cmd->off -= (end + 1 - cmd->buf);
1453 end = memchr (cmd->buf, '\n', cmd->off); 1442 end = memchr (cmd->buf, '\n', cmd->off);
1454 } 1443 }
1455 cmd->rtask = 1444 cmd->rtask =
1456 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining 1445 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
1457 (cmd->timeout), cmd->r, &cmd_read, cmd); 1446 (cmd->timeout), cmd->r, &cmd_read, cmd);
1458} 1447}
1459 1448
1460 1449
@@ -1471,8 +1460,8 @@ cmd_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1471 */ 1460 */
1472struct GNUNET_OS_CommandHandle * 1461struct GNUNET_OS_CommandHandle *
1473GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls, 1462GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
1474 struct GNUNET_TIME_Relative timeout, 1463 struct GNUNET_TIME_Relative timeout, const char *binary,
1475 const char *binary, ...) 1464 ...)
1476{ 1465{
1477 struct GNUNET_OS_CommandHandle *cmd; 1466 struct GNUNET_OS_CommandHandle *cmd;
1478 struct GNUNET_OS_Process *eip; 1467 struct GNUNET_OS_Process *eip;
@@ -1486,10 +1475,10 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
1486 eip = GNUNET_OS_start_process_va (NULL, opipe, binary, ap); 1475 eip = GNUNET_OS_start_process_va (NULL, opipe, binary, ap);
1487 va_end (ap); 1476 va_end (ap);
1488 if (NULL == eip) 1477 if (NULL == eip)
1489 { 1478 {
1490 GNUNET_DISK_pipe_close (opipe); 1479 GNUNET_DISK_pipe_close (opipe);
1491 return NULL; 1480 return NULL;
1492 } 1481 }
1493 GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE); 1482 GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE);
1494 cmd = GNUNET_malloc (sizeof (struct GNUNET_OS_CommandHandle)); 1483 cmd = GNUNET_malloc (sizeof (struct GNUNET_OS_CommandHandle));
1495 cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1484 cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout);
@@ -1498,8 +1487,7 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
1498 cmd->proc = proc; 1487 cmd->proc = proc;
1499 cmd->proc_cls = proc_cls; 1488 cmd->proc_cls = proc_cls;
1500 cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ); 1489 cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ);
1501 cmd->rtask = 1490 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd);
1502 GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd);
1503 return cmd; 1491 return cmd;
1504} 1492}
1505 1493