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