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