pexecute.c (pexecute): New function for mingw32.
authorMumit Khan <khan@xraylith.wisc.edu>
Sat, 17 Jan 1998 21:33:56 +0000 (21:33 +0000)
committerJeff Law <law@gcc.gnu.org>
Sat, 17 Jan 1998 21:33:56 +0000 (14:33 -0700)
        * pexecute.c (pexecute): New function for mingw32. Supports pipes.
        (pwait): New function for mingw32.
        * gcc.c (execute): Mingw32 pexecute() supports pipes, but cygwin32
        pipe support is broken for now.

Co-Authored-By: J.J. VanderHeijden <J.J.vanderHeijden@student.utwente.nl>
From-SVN: r17396

gcc/ChangeLog
gcc/gcc.c
gcc/pexecute.c

index 06df5a33ddb9c3dc5fec3387493e5c3408d7d4ce..7a660ffad31f515b64096b7e82efc212cc60ca9e 100644 (file)
@@ -1,3 +1,12 @@
+Sat Jan 17 22:35:39 1998  Mumit Khan <khan@xraylith.wisc.edu>
+                         J.J VanderHeijden <J.J.vanderHeijden@student.utwente.nl>
+       
+       * pexecute.c (pexecute): New function for mingw32. Supports pipes.
+       (pwait): New function for mingw32.
+
+       * gcc.c (execute): Mingw32 pexecute() supports pipes, but cygwin32
+       pipe support is broken for now.
+
 1998-01-17  Lee Iverson  <leei@Canada.AI.SRI.COM>
 
        * reorg.c: #include "expr.h" for rtx prototypes.
index 6e4a10d95158609afc9d294ebc71cfdade534d42..52a23bb82d51cf4ae334374966af6773177c9355 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -2159,7 +2159,7 @@ execute ()
   for (n_commands = 1, i = 0; i < argbuf_index; i++)
     if (strcmp (argbuf[i], "|") == 0)
       {                                /* each command.  */
-#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__)) || defined (OS2) || defined (VMS)
+#if defined (__MSDOS__) || (defined (_WIN32) && defined (__CYGWIN32_)) || defined (OS2) || defined (VMS)
         fatal ("-pipe not supported");
 #endif
        argbuf[i] = 0;  /* termination of command args.  */
index 5c2779fcc22c7e67929c77a000882fe1fd8dbf73..f9690e446e699d13aa45bf9652c74083c8057ac7 100644 (file)
@@ -223,20 +223,55 @@ pwait (pid, status, flags)
 #if defined (_WIN32)
 
 #include <process.h>
-#include <signal.h>
-extern int _spawnv ();
-extern int _spawnvp ();
 
 #ifdef __CYGWIN32__
 
 #define fix_argv(argvec) (argvec)
 
-#else
+extern int _spawnv ();
+extern int _spawnvp ();
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+     const char *program;
+     char * const *argv;
+     const char *this_pname;
+     const char *temp_base;
+     char **errmsg_fmt, **errmsg_arg;
+     int flags;
+{
+  int pid;
+
+  if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
+    abort ();
+  pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
+    (_P_NOWAIT, program, fix_argv(argv));
+  if (pid == -1)
+    {
+      *errmsg_fmt = install_error_msg;
+      *errmsg_arg = program;
+      return -1;
+    }
+  return pid;
+}
+
+int
+pwait (pid, status, flags)
+     int pid;
+     int *status;
+     int flags;
+{
+  /* ??? Here's an opportunity to canonicalize the values in STATUS.
+     Needed?  */
+  return cwait (status, pid, WAIT_CHILD);
+}
+
+#else /* ! __CYGWIN32__ */
 
 /* This is a kludge to get around the Microsoft C spawn functions' propensity
    to remove the outermost set of double quotes from all arguments.  */
 
-char * const *
+const char * const *
 fix_argv (argvec)
      char **argvec;
 {
@@ -253,7 +288,7 @@ fix_argv (argvec)
         {
           if (temp[j] == '"')
             {
-              newtemp = (char *) xmalloc (len + 2);
+              newtemp = xmalloc (len + 2);
               strncpy (newtemp, temp, j);
               newtemp [j] = '\\';
               strncpy (&newtemp [j+1], &temp [j], len-j);
@@ -267,36 +302,118 @@ fix_argv (argvec)
         argvec[i] = temp;
       }
 
-  return (char * const *) argvec;
+  return (const char * const *) argvec;
 }
 
-#endif /* ! defined (__CYGWIN32__) */
+#include <io.h>
+#include <fcntl.h>
+#include <signal.h>
+
+/* mingw32 headers may not define the following.  */
 
+#ifndef _P_WAIT
+#  define _P_WAIT      0
+#  define _P_NOWAIT    1
+#  define _P_OVERLAY   2
+#  define _P_NOWAITO   3
+#  define _P_DETACH    4
+
+#  define WAIT_CHILD   0
+#  define WAIT_GRANDCHILD      1
+#endif
+
+/* Win32 supports pipes */
 int
 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
      const char *program;
      char * const *argv;
      const char *this_pname;
      const char *temp_base;
-     char **errmsg_fmt;
-     const char **errmsg_arg;
+     char **errmsg_fmt, **errmsg_arg;
      int flags;
 {
   int pid;
+  int pdes[2], org_stdin, org_stdout;
+  int input_desc, output_desc;
+  int retries, sleep_interval;
+
+  /* Pipe waiting from last process, to be used as input for the next one.
+     Value is STDIN_FILE_NO if no pipe is waiting
+     (i.e. the next command is the first of a group).  */
+  static int last_pipe_input;
+
+  /* If this is the first process, initialize.  */
+  if (flags & PEXECUTE_FIRST)
+    last_pipe_input = STDIN_FILE_NO;
+
+  input_desc = last_pipe_input;
+
+  /* If this isn't the last process, make a pipe for its output,
+     and record it as waiting to be the input to the next process.  */
+  if (! (flags & PEXECUTE_LAST))
+    {
+      if (_pipe (pdes, 256, O_BINARY) < 0)
+       {
+         *errmsg_fmt = "pipe";
+         *errmsg_arg = NULL;
+         return -1;
+       }
+      output_desc = pdes[WRITE_PORT];
+      last_pipe_input = pdes[READ_PORT];
+    }
+  else
+    {
+      /* Last process.  */
+      output_desc = STDOUT_FILE_NO;
+      last_pipe_input = STDIN_FILE_NO;
+    }
+
+  if (input_desc != STDIN_FILE_NO)
+    {
+      org_stdin = dup (STDIN_FILE_NO);
+      dup2 (input_desc, STDIN_FILE_NO);
+      close (input_desc); 
+    }
+
+  if (output_desc != STDOUT_FILE_NO)
+    {
+      org_stdout = dup (STDOUT_FILE_NO);
+      dup2 (output_desc, STDOUT_FILE_NO);
+      close (output_desc);
+    }
 
-  if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
-    abort ();
   pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
-    (_P_NOWAIT, program, fix_argv (argv));
+    (_P_NOWAIT, program, fix_argv(argv));
+
+  if (input_desc != STDIN_FILE_NO)
+    {
+      dup2 (org_stdin, STDIN_FILE_NO);
+      close (org_stdin);
+    }
+
+  if (output_desc != STDOUT_FILE_NO)
+    {
+      dup2 (org_stdout, STDOUT_FILE_NO);
+      close (org_stdout);
+    }
+
   if (pid == -1)
     {
       *errmsg_fmt = install_error_msg;
       *errmsg_arg = program;
       return -1;
     }
+
   return pid;
 }
 
+/* MS CRTDLL doesn't return enough information in status to decide if the
+   child exited due to a signal or not, rather it simply returns an
+   integer with the exit code of the child; eg., if the child exited with 
+   an abort() call and didn't have a handler for SIGABRT, it simply returns
+   with status = 3. We fix the status code to conform to the usual WIF*
+   macros. Note that WIFSIGNALED will never be true under CRTDLL. */
+
 int
 pwait (pid, status, flags)
      int pid;
@@ -305,7 +422,7 @@ pwait (pid, status, flags)
 {
   int termstat;
 
-  pid = cwait (&termstat, pid, WAIT_CHILD);
+  pid = _cwait (&termstat, pid, WAIT_CHILD);
 
   /* ??? Here's an opportunity to canonicalize the values in STATUS.
      Needed?  */
@@ -322,6 +439,8 @@ pwait (pid, status, flags)
   return pid;
 }
 
+#endif /* ! defined (__CYGWIN32__) */
+
 #endif /* _WIN32 */
 
 #ifdef OS2