aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_priority.c
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-06 22:46:29 +0000
committerng0 <ng0@n0.is>2019-09-06 22:46:29 +0000
commit6e599264ad13e8fc105493d74d7c11d46f8739ed (patch)
tree169bef1ecbade5a659831fb169f3ae6943af127f /src/util/os_priority.c
parent4f13bc15113021ebf71d5d81e99bc29f8a07fc9c (diff)
downloadgnunet-6e599264ad13e8fc105493d74d7c11d46f8739ed.tar.gz
gnunet-6e599264ad13e8fc105493d74d7c11d46f8739ed.zip
first step to remove plibc
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r--src/util/os_priority.c604
1 files changed, 316 insertions, 288 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index 03d4bde9e..17baa0df8 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -29,11 +29,13 @@
29#include "disk.h" 29#include "disk.h"
30#include <unistr.h> 30#include <unistr.h>
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
33 33
34#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-os-priority", syscall) 34#define LOG_STRERROR(kind, syscall) \
35 GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
35 36
36#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename) 37#define LOG_STRERROR_FILE(kind, syscall, filename) \
38 GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename)
37 39
38#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" 40#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
39 41
@@ -107,16 +109,12 @@ parent_control_handler (void *cls)
107 ssize_t ret; 109 ssize_t ret;
108 110
109 pch = NULL; 111 pch = NULL;
110 ret = GNUNET_DISK_file_read (control_pipe, 112 ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig));
111 &sig,
112 sizeof (sig));
113 if (sizeof (sig) != ret) 113 if (sizeof (sig) != ret)
114 { 114 {
115 if (-1 == ret) 115 if (-1 == ret)
116 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 116 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
117 "GNUNET_DISK_file_read"); 117 LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n");
118 LOG (GNUNET_ERROR_TYPE_DEBUG,
119 "Closing control pipe\n");
120 GNUNET_DISK_file_close (control_pipe); 118 GNUNET_DISK_file_close (control_pipe);
121 control_pipe = NULL; 119 control_pipe = NULL;
122 GNUNET_SCHEDULER_cancel (spch); 120 GNUNET_SCHEDULER_cancel (spch);
@@ -124,16 +122,15 @@ parent_control_handler (void *cls)
124 return; 122 return;
125 } 123 }
126 pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE); 124 pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE);
127 GNUNET_assert ( (NULL == pipe_fd) || 125 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
128 (strlen (pipe_fd) <= 0) );
129 LOG (GNUNET_ERROR_TYPE_DEBUG, 126 LOG (GNUNET_ERROR_TYPE_DEBUG,
130 "Got control code %d from parent via pipe %s\n", 127 "Got control code %d from parent via pipe %s\n",
131 sig, 128 sig,
132 pipe_fd); 129 pipe_fd);
133 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 130 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
134 control_pipe, 131 control_pipe,
135 &parent_control_handler, 132 &parent_control_handler,
136 control_pipe); 133 control_pipe);
137 GNUNET_SIGNAL_raise ((int) sig); 134 GNUNET_SIGNAL_raise ((int) sig);
138} 135}
139 136
@@ -162,10 +159,10 @@ GNUNET_OS_install_parent_control_handler (void *cls)
162 return; 159 return;
163 } 160 }
164 env_buf = getenv (GNUNET_OS_CONTROL_PIPE); 161 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
165 if ( (NULL == env_buf) || (strlen (env_buf) <= 0) ) 162 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
166 { 163 {
167 LOG (GNUNET_ERROR_TYPE_DEBUG, 164 LOG (GNUNET_ERROR_TYPE_DEBUG,
168 "Not installing a handler because $%s is empty\n", 165 "Not installing a handler because $%s is empty\n",
169 GNUNET_OS_CONTROL_PIPE); 166 GNUNET_OS_CONTROL_PIPE);
170 putenv (GNUNET_OS_CONTROL_PIPE "="); 167 putenv (GNUNET_OS_CONTROL_PIPE "=");
171 return; 168 return;
@@ -174,35 +171,32 @@ GNUNET_OS_install_parent_control_handler (void *cls)
174 pipe_fd = strtoull (env_buf, &env_buf_end, 16); 171 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
175 if ((0 != errno) || (env_buf == env_buf_end)) 172 if ((0 != errno) || (env_buf == env_buf_end))
176 { 173 {
177 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, 174 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf);
178 "strtoull",
179 env_buf);
180 putenv (GNUNET_OS_CONTROL_PIPE "="); 175 putenv (GNUNET_OS_CONTROL_PIPE "=");
181 return; 176 return;
182 } 177 }
183#if !defined (WINDOWS) 178#if ! defined(WINDOWS)
184 if (pipe_fd >= FD_SETSIZE) 179 if (pipe_fd >= FD_SETSIZE)
185#else 180#else
186 if ((FILE_TYPE_UNKNOWN == GetFileType ((HANDLE) (uintptr_t) pipe_fd)) 181 if ((FILE_TYPE_UNKNOWN == GetFileType ((HANDLE) (uintptr_t) pipe_fd)) &&
187 && (0 != GetLastError ())) 182 (0 != GetLastError ()))
188#endif 183#endif
189 { 184 {
190 LOG (GNUNET_ERROR_TYPE_ERROR, 185 LOG (GNUNET_ERROR_TYPE_ERROR,
191 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n", 186 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
192 env_buf); 187 env_buf);
193 putenv (GNUNET_OS_CONTROL_PIPE "="); 188 putenv (GNUNET_OS_CONTROL_PIPE "=");
194 return; 189 return;
195 } 190 }
196#if WINDOWS 191#if WINDOWS
197 control_pipe = GNUNET_DISK_get_handle_from_w32_handle ((HANDLE) (uintptr_t) pipe_fd); 192 control_pipe =
193 GNUNET_DISK_get_handle_from_w32_handle ((HANDLE) (uintptr_t) pipe_fd);
198#else 194#else
199 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd); 195 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd);
200#endif 196#endif
201 if (NULL == control_pipe) 197 if (NULL == control_pipe)
202 { 198 {
203 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, 199 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf);
204 "open",
205 env_buf);
206 putenv (GNUNET_OS_CONTROL_PIPE "="); 200 putenv (GNUNET_OS_CONTROL_PIPE "=");
207 return; 201 return;
208 } 202 }
@@ -210,11 +204,10 @@ GNUNET_OS_install_parent_control_handler (void *cls)
210 "Adding parent control handler pipe `%s' to the scheduler\n", 204 "Adding parent control handler pipe `%s' to the scheduler\n",
211 env_buf); 205 env_buf);
212 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 206 pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
213 control_pipe, 207 control_pipe,
214 &parent_control_handler, 208 &parent_control_handler,
215 control_pipe);
216 spch = GNUNET_SCHEDULER_add_shutdown (&shutdown_pch,
217 control_pipe); 209 control_pipe);
210 spch = GNUNET_SCHEDULER_add_shutdown (&shutdown_pch, control_pipe);
218 putenv (GNUNET_OS_CONTROL_PIPE "="); 211 putenv (GNUNET_OS_CONTROL_PIPE "=");
219} 212}
220 213
@@ -248,8 +241,7 @@ GNUNET_OS_process_current ()
248 * @return 0 on success, -1 on error 241 * @return 0 on success, -1 on error
249 */ 242 */
250int 243int
251GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, 244GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
252 int sig)
253{ 245{
254 int ret; 246 int ret;
255 char csig; 247 char csig;
@@ -258,19 +250,17 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc,
258 if (NULL != proc->control_pipe) 250 if (NULL != proc->control_pipe)
259 { 251 {
260 LOG (GNUNET_ERROR_TYPE_DEBUG, 252 LOG (GNUNET_ERROR_TYPE_DEBUG,
261 "Sending signal %d to pid: %u via pipe\n", 253 "Sending signal %d to pid: %u via pipe\n",
262 sig, 254 sig,
263 proc->pid); 255 proc->pid);
264 ret = GNUNET_DISK_file_write (proc->control_pipe, 256 ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig));
265 &csig,
266 sizeof (csig));
267 if (sizeof (csig) == ret) 257 if (sizeof (csig) == ret)
268 return 0; 258 return 0;
269 } 259 }
270 /* pipe failed or non-existent, try other methods */ 260 /* pipe failed or non-existent, try other methods */
271 switch (sig) 261 switch (sig)
272 { 262 {
273#if !defined (WINDOWS) 263#if ! defined(WINDOWS)
274 case SIGHUP: 264 case SIGHUP:
275#endif 265#endif
276 case SIGINT: 266 case SIGINT:
@@ -279,62 +269,62 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc,
279#if (SIGTERM != GNUNET_TERM_SIG) 269#if (SIGTERM != GNUNET_TERM_SIG)
280 case GNUNET_TERM_SIG: 270 case GNUNET_TERM_SIG:
281#endif 271#endif
282#if defined(WINDOWS) && !defined(__CYGWIN__) 272#if defined(WINDOWS) && ! defined(__CYGWIN__)
273 {
274 DWORD exitcode;
275 int must_kill = GNUNET_YES;
276 if (0 != GetExitCodeProcess (proc->handle, &exitcode))
277 must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO;
278 if (GNUNET_YES == must_kill)
283 { 279 {
284 DWORD exitcode; 280 if (0 == SafeTerminateProcess (proc->handle, 0, 0))
285 int must_kill = GNUNET_YES;
286 if (0 != GetExitCodeProcess (proc->handle, &exitcode))
287 must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO;
288 if (GNUNET_YES == must_kill)
289 { 281 {
290 if (0 == SafeTerminateProcess (proc->handle, 0, 0)) 282 DWORD error_code = GetLastError ();
283 if ((error_code != WAIT_TIMEOUT) &&
284 (error_code != ERROR_PROCESS_ABORTED))
291 { 285 {
292 DWORD error_code = GetLastError (); 286 LOG ((error_code == ERROR_ACCESS_DENIED) ? GNUNET_ERROR_TYPE_INFO
293 if ( (error_code != WAIT_TIMEOUT) && 287 : GNUNET_ERROR_TYPE_WARNING,
294 (error_code != ERROR_PROCESS_ABORTED) ) 288 "SafeTermiateProcess failed with code %lu\n",
295 { 289 error_code);
296 LOG ((error_code == ERROR_ACCESS_DENIED) ? 290 /* The problem here is that a process that is already dying
297 GNUNET_ERROR_TYPE_INFO : GNUNET_ERROR_TYPE_WARNING,
298 "SafeTermiateProcess failed with code %lu\n",
299 error_code);
300 /* The problem here is that a process that is already dying
301 * might cause SafeTerminateProcess to fail with 291 * might cause SafeTerminateProcess to fail with
302 * ERROR_ACCESS_DENIED, but the process WILL die eventually. 292 * ERROR_ACCESS_DENIED, but the process WILL die eventually.
303 * If we really had a permissions problem, hanging up (which 293 * If we really had a permissions problem, hanging up (which
304 * is what will happen in process_wait() in that case) is 294 * is what will happen in process_wait() in that case) is
305 * a valid option. 295 * a valid option.
306 */ 296 */
307 if (ERROR_ACCESS_DENIED == error_code) 297 if (ERROR_ACCESS_DENIED == error_code)
308 { 298 {
309 errno = 0; 299 errno = 0;
310 } 300 }
311 else 301 else
312 { 302 {
313 SetErrnoFromWinError (error_code); 303 SetErrnoFromWinError (error_code);
314 return -1; 304 return -1;
315 }
316 } 305 }
317 } 306 }
318 } 307 }
319 } 308 }
309 }
320 return 0; 310 return 0;
321#else 311#else
322 LOG (GNUNET_ERROR_TYPE_DEBUG, 312 LOG (GNUNET_ERROR_TYPE_DEBUG,
323 "Sending signal %d to pid: %u via system call\n", 313 "Sending signal %d to pid: %u via system call\n",
324 sig, 314 sig,
325 proc->pid); 315 proc->pid);
326 return PLIBC_KILL (proc->pid, sig); 316 return kill (proc->pid, sig);
327#endif 317#endif
328 default: 318 default:
329#if defined (WINDOWS) 319#if defined(WINDOWS)
330 errno = EINVAL; 320 errno = EINVAL;
331 return -1; 321 return -1;
332#else 322#else
333 LOG (GNUNET_ERROR_TYPE_DEBUG, 323 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Sending signal %d to pid: %u via system call\n", 324 "Sending signal %d to pid: %u via system call\n",
335 sig, 325 sig,
336 proc->pid); 326 proc->pid);
337 return PLIBC_KILL (proc->pid, sig); 327 return kill (proc->pid, sig);
338#endif 328#endif
339 } 329 }
340} 330}
@@ -348,7 +338,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc,
348 * @return the current process id 338 * @return the current process id
349 */ 339 */
350pid_t 340pid_t
351GNUNET_OS_process_get_pid (struct GNUNET_OS_Process * proc) 341GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc)
352{ 342{
353 return proc->pid; 343 return proc->pid;
354} 344}
@@ -365,7 +355,7 @@ GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc)
365{ 355{
366 if (NULL != proc->control_pipe) 356 if (NULL != proc->control_pipe)
367 GNUNET_DISK_file_close (proc->control_pipe); 357 GNUNET_DISK_file_close (proc->control_pipe);
368#if defined (WINDOWS) 358#if defined(WINDOWS)
369 if (NULL != proc->handle) 359 if (NULL != proc->handle)
370 CloseHandle (proc->handle); 360 CloseHandle (proc->handle);
371#endif 361#endif
@@ -425,7 +415,8 @@ CreateCustomEnvTable (char **vars)
425 win32_env_table = GetEnvironmentStringsA (); 415 win32_env_table = GetEnvironmentStringsA ();
426 if (NULL == win32_env_table) 416 if (NULL == win32_env_table)
427 return NULL; 417 return NULL;
428 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) ; 418 for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++)
419 ;
429 n_var = c; 420 n_var = c;
430 index = GNUNET_malloc (sizeof (char *) * n_var); 421 index = GNUNET_malloc (sizeof (char *) * n_var);
431 for (c = 0; c < n_var; c++) 422 for (c = 0; c < n_var; c++)
@@ -448,7 +439,7 @@ CreateCustomEnvTable (char **vars)
448 break; 439 break;
449 } 440 }
450 } 441 }
451 if (!found) 442 if (! found)
452 tablesize += len + 1; 443 tablesize += len + 1;
453 ptr += len + 1; 444 ptr += len + 1;
454 } 445 }
@@ -476,7 +467,7 @@ CreateCustomEnvTable (char **vars)
476 break; 467 break;
477 } 468 }
478 } 469 }
479 if (!found) 470 if (! found)
480 { 471 {
481 strcpy (result_ptr, ptr); 472 strcpy (result_ptr, ptr);
482 result_ptr += len + 1; 473 result_ptr += len + 1;
@@ -519,17 +510,14 @@ CreateCustomEnvTable (char **vars)
519 * @param flags open flags (O_RDONLY, O_WRONLY) 510 * @param flags open flags (O_RDONLY, O_WRONLY)
520 */ 511 */
521static void 512static void
522open_dev_null (int target_fd, 513open_dev_null (int target_fd, int flags)
523 int flags)
524{ 514{
525 int fd; 515 int fd;
526 516
527 fd = open ("/dev/null", flags); 517 fd = open ("/dev/null", flags);
528 if (-1 == fd) 518 if (-1 == fd)
529 { 519 {
530 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 520 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", "/dev/null");
531 "open",
532 "/dev/null");
533 return; 521 return;
534 } 522 }
535 if (fd == target_fd) 523 if (fd == target_fd)
@@ -565,12 +553,12 @@ open_dev_null (int target_fd,
565static struct GNUNET_OS_Process * 553static struct GNUNET_OS_Process *
566start_process (int pipe_control, 554start_process (int pipe_control,
567 enum GNUNET_OS_InheritStdioFlags std_inheritance, 555 enum GNUNET_OS_InheritStdioFlags std_inheritance,
568 struct GNUNET_DISK_PipeHandle *pipe_stdin, 556 struct GNUNET_DISK_PipeHandle *pipe_stdin,
569 struct GNUNET_DISK_PipeHandle *pipe_stdout, 557 struct GNUNET_DISK_PipeHandle *pipe_stdout,
570 struct GNUNET_DISK_PipeHandle *pipe_stderr, 558 struct GNUNET_DISK_PipeHandle *pipe_stderr,
571 const SOCKTYPE *lsocks, 559 const SOCKTYPE *lsocks,
572 const char *filename, 560 const char *filename,
573 char *const argv[]) 561 char *const argv[])
574{ 562{
575#ifndef MINGW 563#ifndef MINGW
576 pid_t ret; 564 pid_t ret;
@@ -601,22 +589,19 @@ start_process (int pipe_control,
601 struct GNUNET_DISK_PipeHandle *childpipe; 589 struct GNUNET_DISK_PipeHandle *childpipe;
602 int dup_childpipe_read_fd = -1; 590 int dup_childpipe_read_fd = -1;
603 591
604 childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 592 childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
605 GNUNET_YES, GNUNET_NO);
606 if (NULL == childpipe) 593 if (NULL == childpipe)
607 return NULL; 594 return NULL;
608 childpipe_read = GNUNET_DISK_pipe_detach_end (childpipe, 595 childpipe_read =
609 GNUNET_DISK_PIPE_END_READ); 596 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ);
610 childpipe_write = GNUNET_DISK_pipe_detach_end (childpipe, 597 childpipe_write =
611 GNUNET_DISK_PIPE_END_WRITE); 598 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE);
612 GNUNET_DISK_pipe_close (childpipe); 599 GNUNET_DISK_pipe_close (childpipe);
613 if ( (NULL == childpipe_read) || 600 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
614 (NULL == childpipe_write) || 601 (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read,
615 (GNUNET_OK != 602 &childpipe_read_fd,
616 GNUNET_DISK_internal_file_handle_ (childpipe_read, 603 sizeof (int))) ||
617 &childpipe_read_fd, 604 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
618 sizeof (int))) ||
619 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
620 { 605 {
621 if (NULL != childpipe_read) 606 if (NULL != childpipe_read)
622 GNUNET_DISK_file_close (childpipe_read); 607 GNUNET_DISK_file_close (childpipe_read);
@@ -636,39 +621,48 @@ start_process (int pipe_control,
636 } 621 }
637 if (NULL != pipe_stdin) 622 if (NULL != pipe_stdin)
638 { 623 {
639 GNUNET_assert (GNUNET_OK == 624 GNUNET_assert (
640 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 625 GNUNET_OK ==
641 (pipe_stdin, GNUNET_DISK_PIPE_END_READ), 626 GNUNET_DISK_internal_file_handle_ (
642 &fd_stdin_read, sizeof (int))); 627 GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
643 GNUNET_assert (GNUNET_OK == 628 &fd_stdin_read,
644 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 629 sizeof (int)));
645 (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE), 630 GNUNET_assert (
646 &fd_stdin_write, sizeof (int))); 631 GNUNET_OK ==
632 GNUNET_DISK_internal_file_handle_ (
633 GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
634 &fd_stdin_write,
635 sizeof (int)));
647 } 636 }
648 if (NULL != pipe_stdout) 637 if (NULL != pipe_stdout)
649 { 638 {
650 GNUNET_assert (GNUNET_OK == 639 GNUNET_assert (
651 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 640 GNUNET_OK ==
652 (pipe_stdout, 641 GNUNET_DISK_internal_file_handle_ (
653 GNUNET_DISK_PIPE_END_WRITE), 642 GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE),
654 &fd_stdout_write, sizeof (int))); 643 &fd_stdout_write,
655 GNUNET_assert (GNUNET_OK == 644 sizeof (int)));
656 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 645 GNUNET_assert (
657 (pipe_stdout, GNUNET_DISK_PIPE_END_READ), 646 GNUNET_OK ==
658 &fd_stdout_read, sizeof (int))); 647 GNUNET_DISK_internal_file_handle_ (
648 GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
649 &fd_stdout_read,
650 sizeof (int)));
659 } 651 }
660 if (NULL != pipe_stderr) 652 if (NULL != pipe_stderr)
661 { 653 {
662 GNUNET_assert (GNUNET_OK == 654 GNUNET_assert (
663 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 655 GNUNET_OK ==
664 (pipe_stderr, 656 GNUNET_DISK_internal_file_handle_ (
665 GNUNET_DISK_PIPE_END_READ), 657 GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_READ),
666 &fd_stderr_read, sizeof (int))); 658 &fd_stderr_read,
667 GNUNET_assert (GNUNET_OK == 659 sizeof (int)));
668 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 660 GNUNET_assert (
669 (pipe_stderr, 661 GNUNET_OK ==
670 GNUNET_DISK_PIPE_END_WRITE), 662 GNUNET_DISK_internal_file_handle_ (
671 &fd_stderr_write, sizeof (int))); 663 GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_WRITE),
664 &fd_stderr_write,
665 sizeof (int)));
672 } 666 }
673 lscp = NULL; 667 lscp = NULL;
674 ls = 0; 668 ls = 0;
@@ -819,7 +813,7 @@ start_process (int pipe_control,
819 int argcount = 0; 813 int argcount = 0;
820 struct GNUNET_OS_Process *gnunet_proc; 814 struct GNUNET_OS_Process *gnunet_proc;
821 char path[MAX_PATH + 1]; 815 char path[MAX_PATH + 1];
822 char *our_env[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 816 char *our_env[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
823 char *env_block = NULL; 817 char *env_block = NULL;
824 char *pathbuf; 818 char *pathbuf;
825 DWORD pathbuf_len; 819 DWORD pathbuf_len;
@@ -849,7 +843,8 @@ start_process (int pipe_control,
849 DWORD error_code; 843 DWORD error_code;
850 DWORD create_no_window; 844 DWORD create_no_window;
851 845
852 if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename, GNUNET_NO, NULL)) 846 if (GNUNET_SYSERR ==
847 GNUNET_OS_check_helper_binary (filename, GNUNET_NO, NULL))
853 return NULL; /* not executable */ 848 return NULL; /* not executable */
854 849
855 /* Search in prefix dir (hopefully - the directory from which 850 /* Search in prefix dir (hopefully - the directory from which
@@ -861,9 +856,8 @@ start_process (int pipe_control,
861 856
862 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); 857 pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0);
863 858
864 alloc_len = 859 alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 +
865 pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + 860 strlen (libdir);
866 strlen (libdir);
867 861
868 pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); 862 pathbuf = GNUNET_malloc (alloc_len * sizeof (char));
869 863
@@ -877,21 +871,23 @@ start_process (int pipe_control,
877 if (alloc_len != pathbuf_len - 1) 871 if (alloc_len != pathbuf_len - 1)
878 { 872 {
879 GNUNET_free (pathbuf); 873 GNUNET_free (pathbuf);
880 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ 874 errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */
881 return NULL; 875 return NULL;
882 } 876 }
883 877
884 cmdlen = strlen (filename); 878 cmdlen = strlen (filename);
885 if ( (cmdlen < 5) || (0 != strcmp (&filename[cmdlen - 4], ".exe")) ) 879 if ((cmdlen < 5) || (0 != strcmp (&filename[cmdlen - 4], ".exe")))
886 GNUNET_asprintf (&non_const_filename, "%s.exe", filename); 880 GNUNET_asprintf (&non_const_filename, "%s.exe", filename);
887 else 881 else
888 GNUNET_asprintf (&non_const_filename, "%s", filename); 882 GNUNET_asprintf (&non_const_filename, "%s", filename);
889 883
890 /* It could be in POSIX form, convert it to a DOS path early on */ 884 /* It could be in POSIX form, convert it to a DOS path early on */
891 if (ERROR_SUCCESS != (lRet = plibc_conv_to_win_path (non_const_filename, win_path))) 885 if (ERROR_SUCCESS !=
886 (lRet = plibc_conv_to_win_path (non_const_filename, win_path)))
892 { 887 {
893 SetErrnoFromWinError (lRet); 888 SetErrnoFromWinError (lRet);
894 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path", 889 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR,
890 "plibc_conv_to_win_path",
895 non_const_filename); 891 non_const_filename);
896 GNUNET_free (non_const_filename); 892 GNUNET_free (non_const_filename);
897 GNUNET_free (pathbuf); 893 GNUNET_free (pathbuf);
@@ -899,7 +895,7 @@ start_process (int pipe_control,
899 } 895 }
900 GNUNET_free (non_const_filename); 896 GNUNET_free (non_const_filename);
901 non_const_filename = GNUNET_strdup (win_path); 897 non_const_filename = GNUNET_strdup (win_path);
902 /* Check that this is the full path. If it isn't, search. */ 898 /* Check that this is the full path. If it isn't, search. */
903 /* FIXME: convert it to wchar_t and use SearchPathW? 899 /* FIXME: convert it to wchar_t and use SearchPathW?
904 * Remember: arguments to _start_process() are technically in UTF-8... 900 * Remember: arguments to _start_process() are technically in UTF-8...
905 */ 901 */
@@ -907,22 +903,27 @@ start_process (int pipe_control,
907 { 903 {
908 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); 904 snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
909 LOG (GNUNET_ERROR_TYPE_DEBUG, 905 LOG (GNUNET_ERROR_TYPE_DEBUG,
910 "Using path `%s' as-is. PATH is %s\n", path, ptr); 906 "Using path `%s' as-is. PATH is %s\n",
907 path,
908 ptr);
911 } 909 }
912 else if (!SearchPathA 910 else if (! SearchPathA (pathbuf,
913 (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), 911 non_const_filename,
914 path, NULL)) 912 NULL,
913 sizeof (path) / sizeof (char),
914 path,
915 NULL))
915 { 916 {
916 SetErrnoFromWinError (GetLastError ()); 917 SetErrnoFromWinError (GetLastError ());
917 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath", 918 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR,
919 "SearchPath",
918 non_const_filename); 920 non_const_filename);
919 GNUNET_free (non_const_filename); 921 GNUNET_free (non_const_filename);
920 GNUNET_free (pathbuf); 922 GNUNET_free (pathbuf);
921 return NULL; 923 return NULL;
922 } 924 }
923 else 925 else
924 LOG (GNUNET_ERROR_TYPE_DEBUG, 926 LOG (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' in PATH `%s'\n", path, pathbuf);
925 "Found `%s' in PATH `%s'\n", path, pathbuf);
926 GNUNET_free (pathbuf); 927 GNUNET_free (pathbuf);
927 GNUNET_free (non_const_filename); 928 GNUNET_free (non_const_filename);
928 929
@@ -966,8 +967,11 @@ start_process (int pipe_control,
966 while (*arg) 967 while (*arg)
967 { 968 {
968 char arg_last_char = (*arg)[strlen (*arg) - 1]; 969 char arg_last_char = (*arg)[strlen (*arg) - 1];
969 idx += sprintf (idx, "\"%s%s\"%s", *arg, 970 idx += sprintf (idx,
970 arg_last_char == '\\' ? "\\" : "", *(arg + 1) ? " " : ""); 971 "\"%s%s\"%s",
972 *arg,
973 arg_last_char == '\\' ? "\\" : "",
974 *(arg + 1) ? " " : "");
971 arg++; 975 arg++;
972 } 976 }
973 977
@@ -984,9 +988,10 @@ start_process (int pipe_control,
984 GetHandleInformation (stdih, &stdif); 988 GetHandleInformation (stdih, &stdif);
985 if (pipe_stdin != NULL) 989 if (pipe_stdin != NULL)
986 { 990 {
987 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 991 GNUNET_DISK_internal_file_handle_ (
988 (pipe_stdin, GNUNET_DISK_PIPE_END_READ), 992 GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
989 &stdin_handle, sizeof (HANDLE)); 993 &stdin_handle,
994 sizeof (HANDLE));
990 start.hStdInput = stdin_handle; 995 start.hStdInput = stdin_handle;
991 } 996 }
992 else if (stdih) 997 else if (stdih)
@@ -1006,10 +1011,10 @@ start_process (int pipe_control,
1006 GetHandleInformation (stdoh, &stdof); 1011 GetHandleInformation (stdoh, &stdof);
1007 if (NULL != pipe_stdout) 1012 if (NULL != pipe_stdout)
1008 { 1013 {
1009 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 1014 GNUNET_DISK_internal_file_handle_ (
1010 (pipe_stdout, 1015 GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE),
1011 GNUNET_DISK_PIPE_END_WRITE), 1016 &stdout_handle,
1012 &stdout_handle, sizeof (HANDLE)); 1017 sizeof (HANDLE));
1013 start.hStdOutput = stdout_handle; 1018 start.hStdOutput = stdout_handle;
1014 } 1019 }
1015 else if (stdoh) 1020 else if (stdoh)
@@ -1043,12 +1048,15 @@ start_process (int pipe_control,
1043 childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); 1048 childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
1044 if (NULL == childpipe) 1049 if (NULL == childpipe)
1045 return NULL; 1050 return NULL;
1046 childpipe_read = GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ); 1051 childpipe_read =
1047 childpipe_write = GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE); 1052 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ);
1053 childpipe_write =
1054 GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE);
1048 GNUNET_DISK_pipe_close (childpipe); 1055 GNUNET_DISK_pipe_close (childpipe);
1049 if ((NULL == childpipe_read) || (NULL == childpipe_write) || 1056 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
1050 (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read, 1057 (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read,
1051 &childpipe_read_handle, sizeof (HANDLE)))) 1058 &childpipe_read_handle,
1059 sizeof (HANDLE))))
1052 { 1060 {
1053 if (childpipe_read) 1061 if (childpipe_read)
1054 GNUNET_DISK_file_close (childpipe_read); 1062 GNUNET_DISK_file_close (childpipe_read);
@@ -1070,7 +1078,8 @@ start_process (int pipe_control,
1070 1078
1071 if (lsocks != NULL && lsocks[0] != INVALID_SOCKET) 1079 if (lsocks != NULL && lsocks[0] != INVALID_SOCKET)
1072 { 1080 {
1073 lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); 1081 lsocks_pipe =
1082 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
1074 1083
1075 if (lsocks_pipe == NULL) 1084 if (lsocks_pipe == NULL)
1076 { 1085 {
@@ -1083,13 +1092,15 @@ start_process (int pipe_control,
1083 } 1092 }
1084 return NULL; 1093 return NULL;
1085 } 1094 }
1086 lsocks_write_fd = GNUNET_DISK_pipe_handle (lsocks_pipe, 1095 lsocks_write_fd =
1087 GNUNET_DISK_PIPE_END_WRITE); 1096 GNUNET_DISK_pipe_handle (lsocks_pipe, GNUNET_DISK_PIPE_END_WRITE);
1088 GNUNET_DISK_internal_file_handle_ (lsocks_write_fd, 1097 GNUNET_DISK_internal_file_handle_ (lsocks_write_fd,
1089 &lsocks_write, sizeof (HANDLE)); 1098 &lsocks_write,
1090 GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle 1099 sizeof (HANDLE));
1091 (lsocks_pipe, GNUNET_DISK_PIPE_END_READ), 1100 GNUNET_DISK_internal_file_handle_ (
1092 &lsocks_read, sizeof (HANDLE)); 1101 GNUNET_DISK_pipe_handle (lsocks_pipe, GNUNET_DISK_PIPE_END_READ),
1102 &lsocks_read,
1103 sizeof (HANDLE));
1093 } 1104 }
1094 else 1105 else
1095 { 1106 {
@@ -1103,7 +1114,7 @@ start_process (int pipe_control,
1103 GNUNET_asprintf (&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE); 1114 GNUNET_asprintf (&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE);
1104 GNUNET_asprintf (&our_env[env_off++], "%p", childpipe_read_handle); 1115 GNUNET_asprintf (&our_env[env_off++], "%p", childpipe_read_handle);
1105 } 1116 }
1106 if ( (lsocks != NULL) && (lsocks[0] != INVALID_SOCKET)) 1117 if ((lsocks != NULL) && (lsocks[0] != INVALID_SOCKET))
1107 { 1118 {
1108 /*This will tell the child that we're going to send lsocks over the pipe*/ 1119 /*This will tell the child that we're going to send lsocks over the pipe*/
1109 GNUNET_asprintf (&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS"); 1120 GNUNET_asprintf (&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS");
@@ -1115,10 +1126,14 @@ start_process (int pipe_control,
1115 GNUNET_free_non_null (our_env[--env_off]); 1126 GNUNET_free_non_null (our_env[--env_off]);
1116 1127
1117 wpath_len = 0; 1128 wpath_len = 0;
1118 if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len))) 1129 if (NULL ==
1130 (wpath =
1131 u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len)))
1119 { 1132 {
1120 LOG (GNUNET_ERROR_TYPE_DEBUG, 1133 LOG (GNUNET_ERROR_TYPE_DEBUG,
1121 "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno); 1134 "Failed to convert `%s' from UTF-8 to UTF-16: %d\n",
1135 path,
1136 errno);
1122 GNUNET_free (env_block); 1137 GNUNET_free (env_block);
1123 GNUNET_free (cmd); 1138 GNUNET_free (cmd);
1124 if (lsocks_pipe) 1139 if (lsocks_pipe)
@@ -1132,7 +1147,8 @@ start_process (int pipe_control,
1132 } 1147 }
1133 1148
1134 wcmd_len = 0; 1149 wcmd_len = 0;
1135 if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len))) 1150 if (NULL ==
1151 (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len)))
1136 { 1152 {
1137 LOG (GNUNET_ERROR_TYPE_DEBUG, 1153 LOG (GNUNET_ERROR_TYPE_DEBUG,
1138 "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", 1154 "Failed to convert `%s' from UTF-8 to UTF-16: %d\n",
@@ -1153,15 +1169,29 @@ start_process (int pipe_control,
1153 1169
1154 create_no_window = 0; 1170 create_no_window = 0;
1155 { 1171 {
1156 HANDLE console_input = CreateFile ("CONIN$", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 1172 HANDLE console_input = CreateFile ("CONIN$",
1173 GENERIC_READ,
1174 FILE_SHARE_READ | FILE_SHARE_WRITE,
1175 NULL,
1176 OPEN_EXISTING,
1177 0,
1178 NULL);
1157 if (INVALID_HANDLE_VALUE == console_input) 1179 if (INVALID_HANDLE_VALUE == console_input)
1158 create_no_window = CREATE_NO_WINDOW; 1180 create_no_window = CREATE_NO_WINDOW;
1159 else 1181 else
1160 CloseHandle (console_input); 1182 CloseHandle (console_input);
1161 } 1183 }
1162 1184
1163 bresult = CreateProcessW (wpath, wcmd, NULL, NULL, GNUNET_YES, 1185 bresult = CreateProcessW (wpath,
1164 create_no_window | CREATE_SUSPENDED, env_block, NULL, &start, &proc); 1186 wcmd,
1187 NULL,
1188 NULL,
1189 GNUNET_YES,
1190 create_no_window | CREATE_SUSPENDED,
1191 env_block,
1192 NULL,
1193 &start,
1194 &proc);
1165 error_code = GetLastError (); 1195 error_code = GetLastError ();
1166 1196
1167 if ((NULL == pipe_stdin) && (stdih)) 1197 if ((NULL == pipe_stdin) && (stdih))
@@ -1174,7 +1204,7 @@ start_process (int pipe_control,
1174 if (stdeh) 1204 if (stdeh)
1175 SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, stdef); 1205 SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, stdef);
1176 1206
1177 if (!bresult) 1207 if (! bresult)
1178 LOG (GNUNET_ERROR_TYPE_ERROR, 1208 LOG (GNUNET_ERROR_TYPE_ERROR,
1179 "CreateProcess(%s, %s) failed: %lu\n", 1209 "CreateProcess(%s, %s) failed: %lu\n",
1180 path, 1210 path,
@@ -1190,7 +1220,7 @@ start_process (int pipe_control,
1190 GNUNET_DISK_file_close (childpipe_read); 1220 GNUNET_DISK_file_close (childpipe_read);
1191 } 1221 }
1192 1222
1193 if (!bresult) 1223 if (! bresult)
1194 { 1224 {
1195 if (GNUNET_YES == pipe_control) 1225 if (GNUNET_YES == pipe_control)
1196 { 1226 {
@@ -1212,7 +1242,7 @@ start_process (int pipe_control,
1212 ResumeThread (proc.hThread); 1242 ResumeThread (proc.hThread);
1213 CloseHandle (proc.hThread); 1243 CloseHandle (proc.hThread);
1214 1244
1215 if ( (NULL == lsocks) || (INVALID_SOCKET == lsocks[0]) ) 1245 if ((NULL == lsocks) || (INVALID_SOCKET == lsocks[0]))
1216 return gnunet_proc; 1246 return gnunet_proc;
1217 1247
1218 GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ); 1248 GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ);
@@ -1227,25 +1257,29 @@ start_process (int pipe_control,
1227 unsigned int i; 1257 unsigned int i;
1228 1258
1229 /* Tell the number of sockets */ 1259 /* Tell the number of sockets */
1230 for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++); 1260 for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++)
1261 ;
1231 1262
1232 wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); 1263 wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count));
1233 if (sizeof (count) != wrote) 1264 if (sizeof (count) != wrote)
1234 { 1265 {
1235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1266 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1236 "Failed to write %u count bytes to the child: %lu\n", 1267 "Failed to write %u count bytes to the child: %lu\n",
1237 sizeof (count), GetLastError ()); 1268 sizeof (count),
1269 GetLastError ());
1238 break; 1270 break;
1239 } 1271 }
1240 for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++) 1272 for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++)
1241 { 1273 {
1242 WSAPROTOCOL_INFOA pi; 1274 WSAPROTOCOL_INFOA pi;
1243 /* Get a socket duplication info */ 1275 /* Get a socket duplication info */
1244 if (SOCKET_ERROR == WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi)) 1276 if (SOCKET_ERROR ==
1277 WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi))
1245 { 1278 {
1246 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1247 "Failed to duplicate an socket[%u]: %lu\n", i, 1280 "Failed to duplicate an socket[%u]: %lu\n",
1248 GetLastError ()); 1281 i,
1282 GetLastError ());
1249 break; 1283 break;
1250 } 1284 }
1251 /* Synchronous I/O is not nice, but we can't schedule this: 1285 /* Synchronous I/O is not nice, but we can't schedule this:
@@ -1261,8 +1295,10 @@ start_process (int pipe_control,
1261 if (sizeof (size) != wrote) 1295 if (sizeof (size) != wrote)
1262 { 1296 {
1263 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1297 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1264 "Failed to write %u size[%u] bytes to the child: %lu\n", 1298 "Failed to write %u size[%u] bytes to the child: %lu\n",
1265 sizeof (size), i, GetLastError ()); 1299 sizeof (size),
1300 i,
1301 GetLastError ());
1266 break; 1302 break;
1267 } 1303 }
1268 /* Finally! Send the data */ 1304 /* Finally! Send the data */
@@ -1270,8 +1306,10 @@ start_process (int pipe_control,
1270 if (sizeof (pi) != wrote) 1306 if (sizeof (pi) != wrote)
1271 { 1307 {
1272 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1308 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1273 "Failed to write %u socket[%u] bytes to the child: %lu\n", 1309 "Failed to write %u socket[%u] bytes to the child: %lu\n",
1274 sizeof (pi), i, GetLastError ()); 1310 sizeof (pi),
1311 i,
1312 GetLastError ());
1275 break; 1313 break;
1276 } 1314 }
1277 } 1315 }
@@ -1282,8 +1320,7 @@ start_process (int pipe_control,
1282 */ 1320 */
1283 wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); 1321 wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count));
1284 fail = 0; 1322 fail = 0;
1285 } 1323 } while (fail);
1286 while (fail);
1287 1324
1288 GNUNET_DISK_file_sync (lsocks_write_fd); 1325 GNUNET_DISK_file_sync (lsocks_write_fd);
1289 GNUNET_DISK_pipe_close (lsocks_pipe); 1326 GNUNET_DISK_pipe_close (lsocks_pipe);
@@ -1320,20 +1357,20 @@ start_process (int pipe_control,
1320struct GNUNET_OS_Process * 1357struct GNUNET_OS_Process *
1321GNUNET_OS_start_process_vap (int pipe_control, 1358GNUNET_OS_start_process_vap (int pipe_control,
1322 enum GNUNET_OS_InheritStdioFlags std_inheritance, 1359 enum GNUNET_OS_InheritStdioFlags std_inheritance,
1323 struct GNUNET_DISK_PipeHandle *pipe_stdin, 1360 struct GNUNET_DISK_PipeHandle *pipe_stdin,
1324 struct GNUNET_DISK_PipeHandle *pipe_stdout, 1361 struct GNUNET_DISK_PipeHandle *pipe_stdout,
1325 struct GNUNET_DISK_PipeHandle *pipe_stderr, 1362 struct GNUNET_DISK_PipeHandle *pipe_stderr,
1326 const char *filename, 1363 const char *filename,
1327 char *const argv[]) 1364 char *const argv[])
1328{ 1365{
1329 return start_process (pipe_control, 1366 return start_process (pipe_control,
1330 std_inheritance, 1367 std_inheritance,
1331 pipe_stdin, 1368 pipe_stdin,
1332 pipe_stdout, 1369 pipe_stdout,
1333 pipe_stderr, 1370 pipe_stderr,
1334 NULL, 1371 NULL,
1335 filename, 1372 filename,
1336 argv); 1373 argv);
1337} 1374}
1338 1375
1339 1376
@@ -1352,10 +1389,11 @@ GNUNET_OS_start_process_vap (int pipe_control,
1352struct GNUNET_OS_Process * 1389struct GNUNET_OS_Process *
1353GNUNET_OS_start_process_va (int pipe_control, 1390GNUNET_OS_start_process_va (int pipe_control,
1354 enum GNUNET_OS_InheritStdioFlags std_inheritance, 1391 enum GNUNET_OS_InheritStdioFlags std_inheritance,
1355 struct GNUNET_DISK_PipeHandle *pipe_stdin, 1392 struct GNUNET_DISK_PipeHandle *pipe_stdin,
1356 struct GNUNET_DISK_PipeHandle *pipe_stdout, 1393 struct GNUNET_DISK_PipeHandle *pipe_stdout,
1357 struct GNUNET_DISK_PipeHandle *pipe_stderr, 1394 struct GNUNET_DISK_PipeHandle *pipe_stderr,
1358 const char *filename, va_list va) 1395 const char *filename,
1396 va_list va)
1359{ 1397{
1360 struct GNUNET_OS_Process *ret; 1398 struct GNUNET_OS_Process *ret;
1361 va_list ap; 1399 va_list ap;
@@ -1375,11 +1413,11 @@ GNUNET_OS_start_process_va (int pipe_control,
1375 va_end (ap); 1413 va_end (ap);
1376 ret = GNUNET_OS_start_process_vap (pipe_control, 1414 ret = GNUNET_OS_start_process_vap (pipe_control,
1377 std_inheritance, 1415 std_inheritance,
1378 pipe_stdin, 1416 pipe_stdin,
1379 pipe_stdout, 1417 pipe_stdout,
1380 pipe_stderr, 1418 pipe_stderr,
1381 filename, 1419 filename,
1382 argv); 1420 argv);
1383 GNUNET_free (argv); 1421 GNUNET_free (argv);
1384 return ret; 1422 return ret;
1385} 1423}
@@ -1399,10 +1437,11 @@ GNUNET_OS_start_process_va (int pipe_control,
1399struct GNUNET_OS_Process * 1437struct GNUNET_OS_Process *
1400GNUNET_OS_start_process (int pipe_control, 1438GNUNET_OS_start_process (int pipe_control,
1401 enum GNUNET_OS_InheritStdioFlags std_inheritance, 1439 enum GNUNET_OS_InheritStdioFlags std_inheritance,
1402 struct GNUNET_DISK_PipeHandle *pipe_stdin, 1440 struct GNUNET_DISK_PipeHandle *pipe_stdin,
1403 struct GNUNET_DISK_PipeHandle *pipe_stdout, 1441 struct GNUNET_DISK_PipeHandle *pipe_stdout,
1404 struct GNUNET_DISK_PipeHandle *pipe_stderr, 1442 struct GNUNET_DISK_PipeHandle *pipe_stderr,
1405 const char *filename, ...) 1443 const char *filename,
1444 ...)
1406{ 1445{
1407 struct GNUNET_OS_Process *ret; 1446 struct GNUNET_OS_Process *ret;
1408 va_list ap; 1447 va_list ap;
@@ -1411,7 +1450,7 @@ GNUNET_OS_start_process (int pipe_control,
1411 ret = GNUNET_OS_start_process_va (pipe_control, 1450 ret = GNUNET_OS_start_process_va (pipe_control,
1412 std_inheritance, 1451 std_inheritance,
1413 pipe_stdin, 1452 pipe_stdin,
1414 pipe_stdout, 1453 pipe_stdout,
1415 pipe_stderr, 1454 pipe_stderr,
1416 filename, 1455 filename,
1417 ap); 1456 ap);
@@ -1437,18 +1476,18 @@ GNUNET_OS_start_process (int pipe_control,
1437struct GNUNET_OS_Process * 1476struct GNUNET_OS_Process *
1438GNUNET_OS_start_process_v (int pipe_control, 1477GNUNET_OS_start_process_v (int pipe_control,
1439 enum GNUNET_OS_InheritStdioFlags std_inheritance, 1478 enum GNUNET_OS_InheritStdioFlags std_inheritance,
1440 const SOCKTYPE *lsocks, 1479 const SOCKTYPE *lsocks,
1441 const char *filename, 1480 const char *filename,
1442 char *const argv[]) 1481 char *const argv[])
1443{ 1482{
1444 return start_process (pipe_control, 1483 return start_process (pipe_control,
1445 std_inheritance, 1484 std_inheritance,
1446 NULL,
1447 NULL,
1448 NULL, 1485 NULL,
1449 lsocks, 1486 NULL,
1450 filename, 1487 NULL,
1451 argv); 1488 lsocks,
1489 filename,
1490 argv);
1452} 1491}
1453 1492
1454 1493
@@ -1473,8 +1512,9 @@ GNUNET_OS_start_process_v (int pipe_control,
1473struct GNUNET_OS_Process * 1512struct GNUNET_OS_Process *
1474GNUNET_OS_start_process_s (int pipe_control, 1513GNUNET_OS_start_process_s (int pipe_control,
1475 unsigned int std_inheritance, 1514 unsigned int std_inheritance,
1476 const SOCKTYPE * lsocks, 1515 const SOCKTYPE *lsocks,
1477 const char *filename, ...) 1516 const char *filename,
1517 ...)
1478{ 1518{
1479 va_list ap; 1519 va_list ap;
1480 char **argv; 1520 char **argv;
@@ -1502,29 +1542,28 @@ GNUNET_OS_start_process_s (int pipe_control,
1502 { 1542 {
1503 if ('"' == *rpos) 1543 if ('"' == *rpos)
1504 { 1544 {
1505 if (1 == quote_on) 1545 if (1 == quote_on)
1506 quote_on = 0; 1546 quote_on = 0;
1507 else 1547 else
1508 quote_on = 1; 1548 quote_on = 1;
1509 } 1549 }
1510 if ( (' ' == *rpos) && (0 == quote_on) ) 1550 if ((' ' == *rpos) && (0 == quote_on))
1511 { 1551 {
1512 if (NULL != last) 1552 if (NULL != last)
1513 argv_size++; 1553 argv_size++;
1514 last = NULL; 1554 last = NULL;
1515 rpos++; 1555 rpos++;
1516 while (' ' == *rpos) 1556 while (' ' == *rpos)
1517 rpos++; 1557 rpos++;
1518 } 1558 }
1519 if ( (NULL == last) && ('\0' != *rpos) ) // FIXME: == or !=? 1559 if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=?
1520 last = rpos; 1560 last = rpos;
1521 if ('\0' != *rpos) 1561 if ('\0' != *rpos)
1522 rpos++; 1562 rpos++;
1523 } 1563 }
1524 if (NULL != last) 1564 if (NULL != last)
1525 argv_size++; 1565 argv_size++;
1526 } 1566 } while (NULL != (arg = (va_arg (ap, const char *))));
1527 while (NULL != (arg = (va_arg (ap, const char*))));
1528 va_end (ap); 1567 va_end (ap);
1529 1568
1530 argv = GNUNET_malloc (argv_size * sizeof (char *)); 1569 argv = GNUNET_malloc (argv_size * sizeof (char *));
@@ -1541,47 +1580,49 @@ GNUNET_OS_start_process_s (int pipe_control,
1541 { 1580 {
1542 if ('"' == *pos) 1581 if ('"' == *pos)
1543 { 1582 {
1544 if (1 == quote_on) 1583 if (1 == quote_on)
1545 quote_on = 0; 1584 quote_on = 0;
1546 else 1585 else
1547 quote_on = 1; 1586 quote_on = 1;
1548 } 1587 }
1549 if ( (' ' == *pos) && (0 == quote_on) ) 1588 if ((' ' == *pos) && (0 == quote_on))
1550 { 1589 {
1551 *pos = '\0'; 1590 *pos = '\0';
1552 if (NULL != last) 1591 if (NULL != last)
1553 argv[argv_size++] = GNUNET_strdup (last); 1592 argv[argv_size++] = GNUNET_strdup (last);
1554 last = NULL; 1593 last = NULL;
1555 pos++; 1594 pos++;
1556 while (' ' == *pos) 1595 while (' ' == *pos)
1557 pos++; 1596 pos++;
1558 } 1597 }
1559 if ( (NULL == last) && ('\0' != *pos)) // FIXME: == or !=? 1598 if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
1560 last = pos; 1599 last = pos;
1561 if ('\0' != *pos) 1600 if ('\0' != *pos)
1562 pos++; 1601 pos++;
1563 } 1602 }
1564 if (NULL != last) 1603 if (NULL != last)
1565 argv[argv_size++] = GNUNET_strdup (last); 1604 argv[argv_size++] = GNUNET_strdup (last);
1566 last = NULL; 1605 last = NULL;
1567 GNUNET_free (cp); 1606 GNUNET_free (cp);
1568 } 1607 } while (NULL != (arg = (va_arg (ap, const char *))));
1569 while (NULL != (arg = (va_arg (ap, const char*))));
1570 va_end (ap); 1608 va_end (ap);
1571 argv[argv_size] = NULL; 1609 argv[argv_size] = NULL;
1572 1610
1573 for(i = 0; i < argv_size; i++) 1611 for (i = 0; i < argv_size; i++)
1574 { 1612 {
1575 len = strlen (argv[i]); 1613 len = strlen (argv[i]);
1576 if ( (argv[i][0] == '"') && (argv[i][len-1] == '"')) 1614 if ((argv[i][0] == '"') && (argv[i][len - 1] == '"'))
1577 { 1615 {
1578 memmove (&argv[i][0], &argv[i][1], len - 2); 1616 memmove (&argv[i][0], &argv[i][1], len - 2);
1579 argv[i][len-2] = '\0'; 1617 argv[i][len - 2] = '\0';
1580 } 1618 }
1581 } 1619 }
1582 binary_path = argv[0]; 1620 binary_path = argv[0];
1583 proc = GNUNET_OS_start_process_v (pipe_control, std_inheritance, lsocks, 1621 proc = GNUNET_OS_start_process_v (pipe_control,
1584 binary_path, argv); 1622 std_inheritance,
1623 lsocks,
1624 binary_path,
1625 argv);
1585 while (argv_size > 0) 1626 while (argv_size > 0)
1586 GNUNET_free (argv[--argv_size]); 1627 GNUNET_free (argv[--argv_size]);
1587 GNUNET_free (argv); 1628 GNUNET_free (argv);
@@ -1613,8 +1654,7 @@ process_status (struct GNUNET_OS_Process *proc,
1613 ret = waitpid (proc->pid, &status, options); 1654 ret = waitpid (proc->pid, &status, options);
1614 if (ret < 0) 1655 if (ret < 0)
1615 { 1656 {
1616 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, 1657 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1617 "waitpid");
1618 return GNUNET_SYSERR; 1658 return GNUNET_SYSERR;
1619 } 1659 }
1620 if (0 == ret) 1660 if (0 == ret)
@@ -1657,7 +1697,7 @@ process_status (struct GNUNET_OS_Process *proc,
1657 } 1697 }
1658#else 1698#else
1659#ifndef WNOHANG 1699#ifndef WNOHANG
1660#define WNOHANG 42 /* just a flag for W32, purely internal at this point */ 1700#define WNOHANG 42 /* just a flag for W32, purely internal at this point */
1661#endif 1701#endif
1662 1702
1663 HANDLE h; 1703 HANDLE h;
@@ -1669,7 +1709,8 @@ process_status (struct GNUNET_OS_Process *proc,
1669 { 1709 {
1670 LOG (GNUNET_ERROR_TYPE_WARNING, 1710 LOG (GNUNET_ERROR_TYPE_WARNING,
1671 "Invalid process information {%d, %08X}\n", 1711 "Invalid process information {%d, %08X}\n",
1672 ret, h); 1712 ret,
1713 h);
1673 return GNUNET_SYSERR; 1714 return GNUNET_SYSERR;
1674 } 1715 }
1675 if (h == NULL) 1716 if (h == NULL)
@@ -1720,10 +1761,7 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1720 enum GNUNET_OS_ProcessStatusType *type, 1761 enum GNUNET_OS_ProcessStatusType *type,
1721 unsigned long *code) 1762 unsigned long *code)
1722{ 1763{
1723 return process_status (proc, 1764 return process_status (proc, type, code, WNOHANG);
1724 type,
1725 code,
1726 WNOHANG);
1727} 1765}
1728 1766
1729 1767
@@ -1741,10 +1779,7 @@ GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
1741 enum GNUNET_OS_ProcessStatusType *type, 1779 enum GNUNET_OS_ProcessStatusType *type,
1742 unsigned long *code) 1780 unsigned long *code)
1743{ 1781{
1744 return process_status (proc, 1782 return process_status (proc, type, code, 0);
1745 type,
1746 code,
1747 0);
1748} 1783}
1749 1784
1750 1785
@@ -1765,12 +1800,11 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1765 pid_t pid = proc->pid; 1800 pid_t pid = proc->pid;
1766 pid_t ret; 1801 pid_t ret;
1767 1802
1768 while ( (pid != (ret = waitpid (pid, NULL, 0))) && 1803 while ((pid != (ret = waitpid (pid, NULL, 0))) && (EINTR == errno))
1769 (EINTR == errno) ) ; 1804 ;
1770 if (pid != ret) 1805 if (pid != ret)
1771 { 1806 {
1772 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, 1807 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
1773 "waitpid");
1774 return GNUNET_SYSERR; 1808 return GNUNET_SYSERR;
1775 } 1809 }
1776 return GNUNET_OK; 1810 return GNUNET_OK;
@@ -1782,7 +1816,8 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
1782 { 1816 {
1783 LOG (GNUNET_ERROR_TYPE_WARNING, 1817 LOG (GNUNET_ERROR_TYPE_WARNING,
1784 "Invalid process information {%d, %08X}\n", 1818 "Invalid process information {%d, %08X}\n",
1785 proc->pid, h); 1819 proc->pid,
1820 h);
1786 return GNUNET_SYSERR; 1821 return GNUNET_SYSERR;
1787 } 1822 }
1788 if (NULL == h) 1823 if (NULL == h)
@@ -1890,9 +1925,7 @@ cmd_read (void *cls)
1890 1925
1891 cmd->rtask = NULL; 1926 cmd->rtask = NULL;
1892 tc = GNUNET_SCHEDULER_get_task_context (); 1927 tc = GNUNET_SCHEDULER_get_task_context ();
1893 if (GNUNET_YES != 1928 if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r))
1894 GNUNET_NETWORK_fdset_handle_isset (tc->read_ready,
1895 cmd->r))
1896 { 1929 {
1897 /* timeout */ 1930 /* timeout */
1898 proc = cmd->proc; 1931 proc = cmd->proc;
@@ -1901,8 +1934,8 @@ cmd_read (void *cls)
1901 return; 1934 return;
1902 } 1935 }
1903 ret = GNUNET_DISK_file_read (cmd->r, 1936 ret = GNUNET_DISK_file_read (cmd->r,
1904 &cmd->buf[cmd->off], 1937 &cmd->buf[cmd->off],
1905 sizeof (cmd->buf) - cmd->off); 1938 sizeof (cmd->buf) - cmd->off);
1906 if (ret <= 0) 1939 if (ret <= 0)
1907 { 1940 {
1908 if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf))) 1941 if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf)))
@@ -1925,11 +1958,12 @@ cmd_read (void *cls)
1925 cmd->off -= (end + 1 - cmd->buf); 1958 cmd->off -= (end + 1 - cmd->buf);
1926 end = memchr (cmd->buf, '\n', cmd->off); 1959 end = memchr (cmd->buf, '\n', cmd->off);
1927 } 1960 }
1928 cmd->rtask 1961 cmd->rtask =
1929 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining 1962 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (
1930 (cmd->timeout), 1963 cmd->timeout),
1931 cmd->r, 1964 cmd->r,
1932 &cmd_read, cmd); 1965 &cmd_read,
1966 cmd);
1933} 1967}
1934 1968
1935 1969
@@ -1956,15 +1990,13 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
1956 struct GNUNET_DISK_PipeHandle *opipe; 1990 struct GNUNET_DISK_PipeHandle *opipe;
1957 va_list ap; 1991 va_list ap;
1958 1992
1959 opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, 1993 opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
1960 GNUNET_NO, GNUNET_YES);
1961 if (NULL == opipe) 1994 if (NULL == opipe)
1962 return NULL; 1995 return NULL;
1963 va_start (ap, binary); 1996 va_start (ap, binary);
1964 /* redirect stdout, don't inherit stderr/stdin */ 1997 /* redirect stdout, don't inherit stderr/stdin */
1965 eip = GNUNET_OS_start_process_va (GNUNET_NO, 0, NULL, 1998 eip =
1966 opipe, NULL, binary, 1999 GNUNET_OS_start_process_va (GNUNET_NO, 0, NULL, opipe, NULL, binary, ap);
1967 ap);
1968 va_end (ap); 2000 va_end (ap);
1969 if (NULL == eip) 2001 if (NULL == eip)
1970 { 2002 {
@@ -1978,12 +2010,8 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
1978 cmd->opipe = opipe; 2010 cmd->opipe = opipe;
1979 cmd->proc = proc; 2011 cmd->proc = proc;
1980 cmd->proc_cls = proc_cls; 2012 cmd->proc_cls = proc_cls;
1981 cmd->r = GNUNET_DISK_pipe_handle (opipe, 2013 cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ);
1982 GNUNET_DISK_PIPE_END_READ); 2014 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd);
1983 cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout,
1984 cmd->r,
1985 &cmd_read,
1986 cmd);
1987 return cmd; 2015 return cmd;
1988} 2016}
1989 2017