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