0001602: A patch to fix process spawning with redirected std streams
authorMatthias Wachs <wachs@net.in.tum.de>
Wed, 15 Sep 2010 08:31:21 +0000 (08:31 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Wed, 15 Sep 2010 08:31:21 +0000 (08:31 +0000)
src/util/Makefile.am
src/util/disk.c
src/util/scheduler.c
src/util/test_os_start_process.c
src/util/test_scheduler.c

index 6d88537e5ce2693e205eaf3574d183aac532a2d9..38d60167bea07af0ca7155f9ad937e9423b74e85 100644 (file)
@@ -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
index 88f11be51993a8413926b7cfb320a7c3478c243c..fbcf6b964be2e35f028d6db95e62594a84fce96a 100644 (file)
@@ -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;
index 628e80afd81d8b530350cd39e4b4ad8ada30d893..3acb27aa073b23bc71bed9981750b23f513c1f52 100644 (file)
@@ -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);
index 550ea0b39c2d945ee64435f7aed3e6b0b33d32cc..97c5e99c0646f7f57f40ee6d5c3b45ed967bc587 100644 (file)
@@ -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))
     {
index 52e4b36849b4a7da446ae674c4b8adcdb7249c2b..0ac18658869c72b8e244212ee16f97bf7a62ffad 100644 (file)
@@ -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);