From 5c434a60afadd065ab25900dc11756067d58fc1d Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Wed, 15 Sep 2010 08:31:21 +0000 Subject: [PATCH] 0001602: A patch to fix process spawning with redirected std streams --- src/util/Makefile.am | 2 ++ src/util/disk.c | 28 +++++++++++++++++++++++++++- src/util/scheduler.c | 2 +- src/util/test_os_start_process.c | 9 ++++++--- src/util/test_scheduler.c | 2 +- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 6d88537e5..38d60167b 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -14,6 +14,8 @@ libgnunetutilwin_la_LIBADD = \ -lshell32 -liconv -lstdc++ \ -lcomdlg32 -lgdi32 WINLIB = libgnunetutilwin.la +noinst_PROGRAMS = test_os_start_process_cat + test_os_start_process_cat_SOURCES = test_os_start_process_cat.c endif if USE_COVERAGE diff --git a/src/util/disk.c b/src/util/disk.c index 88f11be51..fbcf6b964 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -1649,7 +1649,7 @@ GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h) * @return handle to the new pipe, NULL on error */ struct GNUNET_DISK_PipeHandle * -GNUNET_DISK_pipe (int blocking) +GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write) { struct GNUNET_DISK_PipeHandle *p; struct GNUNET_DISK_FileHandle *fds; @@ -1699,6 +1699,7 @@ GNUNET_DISK_pipe (int blocking) } #else BOOL ret; + HANDLE tmp_handle; ret = CreatePipe (&p->fd[0]->h, &p->fd[1]->h, NULL, 0); if (!ret) @@ -1707,6 +1708,31 @@ GNUNET_DISK_pipe (int blocking) SetErrnoFromWinError (GetLastError ()); return NULL; } + if (!DuplicateHandle (GetCurrentProcess (), p->fd[0]->h, + GetCurrentProcess (), &tmp_handle, 0, inherit_read == GNUNET_YES ? TRUE : FALSE, + DUPLICATE_SAME_ACCESS)) + { + SetErrnoFromWinError (GetLastError ()); + CloseHandle (p->fd[0]->h); + CloseHandle (p->fd[1]->h); + GNUNET_free (p); + return NULL; + } + CloseHandle (p->fd[0]->h); + p->fd[0]->h = tmp_handle; + + if (!DuplicateHandle (GetCurrentProcess (), p->fd[1]->h, + GetCurrentProcess (), &tmp_handle, 0, inherit_write == GNUNET_YES ? TRUE : FALSE, + DUPLICATE_SAME_ACCESS)) + { + SetErrnoFromWinError (GetLastError ()); + CloseHandle (p->fd[0]->h); + CloseHandle (p->fd[1]->h); + GNUNET_free (p); + return NULL; + } + CloseHandle (p->fd[1]->h); + p->fd[1]->h = tmp_handle; if (!blocking) { DWORD mode; diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 628e80afd..3acb27aa0 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c @@ -749,7 +749,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls) rs = GNUNET_NETWORK_fdset_create (); ws = GNUNET_NETWORK_fdset_create (); GNUNET_assert (shutdown_pipe_handle == NULL); - shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO); + shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); GNUNET_assert (shutdown_pipe_handle != NULL); pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_READ); GNUNET_assert (pr != NULL); diff --git a/src/util/test_os_start_process.c b/src/util/test_os_start_process.c index 550ea0b39..97c5e99c0 100644 --- a/src/util/test_os_start_process.c +++ b/src/util/test_os_start_process.c @@ -105,11 +105,14 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *fn; const struct GNUNET_DISK_FileHandle *stdout_read_handle; const struct GNUNET_DISK_FileHandle *wh; - +#ifndef WINDOWS GNUNET_asprintf(&fn, "cat"); +#else + GNUNET_asprintf(&fn, "./.libs/test_os_start_process_cat.exe"); +#endif - hello_pipe_stdin = GNUNET_DISK_pipe(GNUNET_YES); - hello_pipe_stdout = GNUNET_DISK_pipe(GNUNET_YES); + hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO); + hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES); if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) { diff --git a/src/util/test_scheduler.c b/src/util/test_scheduler.c index 52e4b3684..0ac186588 100644 --- a/src/util/test_scheduler.c +++ b/src/util/test_scheduler.c @@ -114,7 +114,7 @@ task5 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) int *ok = cls; GNUNET_assert (5 == *ok); (*ok) = 6; - p = GNUNET_DISK_pipe (GNUNET_NO); + p = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); GNUNET_assert (NULL != p); fds[0] = GNUNET_DISK_pipe_handle (p, GNUNET_DISK_PIPE_END_READ); fds[1] = GNUNET_DISK_pipe_handle (p, GNUNET_DISK_PIPE_END_WRITE); -- 2.25.1