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