This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

(5/8) i386-mingw32 fixes: pexecute/pwait


Patch for egcs toplevel to enable i386-mingw32 support.

Thu Dec 18 18:40:17 1997  Mumit Khan <khan@xraylith.wisc.edu>
	
	* pexecute.c (pexecute): New function for mingw32. Supports pipes.
	(pwait): New function for mingw32 that fixes the status code from 
	MS CRTDLL to conform to the usual wait macros. Originally from
        Jan-Jaap VanderHeijden  <J.J.vanderHeijden@student.utwente.nl>. 

	* gcc.c (execute): Mingw32 pexecute() supports pipes, but cygwin32
	pipe support is broken for now.

Index: egcs/gcc/gcc.c
diff -c egcs/gcc/gcc.c:1.1.1.1 egcs/gcc/gcc.c:1.2
*** egcs/gcc/gcc.c:1.1.1.1	Sat Dec 20 12:10:24 1997
--- egcs/gcc/gcc.c	Sat Dec 20 16:36:54 1997
***************
*** 2159,2165 ****
    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)
          fatal ("-pipe not supported");
  #endif
  	argbuf[i] = 0;	/* termination of command args.  */
--- 2159,2165 ----
    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)
          fatal ("-pipe not supported");
  #endif
  	argbuf[i] = 0;	/* termination of command args.  */
Index: egcs/gcc/pexecute.c
diff -c egcs/gcc/pexecute.c:1.1.1.1 egcs/gcc/pexecute.c:1.2
*** egcs/gcc/pexecute.c:1.1.1.1	Sat Dec 20 12:10:28 1997
--- egcs/gcc/pexecute.c	Sat Dec 20 16:36:53 1997
***************
*** 223,242 ****
  #if defined (_WIN32)
  
  #include <process.h>
- #include <signal.h>
- extern int _spawnv ();
- extern int _spawnvp ();
  
  #ifdef __CYGWIN32__
  
  #define fix_argv(argvec) (argvec)
  
! #else
  
  /* 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 *
  fix_argv (argvec)
       char **argvec;
  {
--- 223,277 ----
  #if defined (_WIN32)
  
  #include <process.h>
  
  #ifdef __CYGWIN32__
  
  #define fix_argv(argvec) (argvec)
  
! 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.  */
  
! const char * const *
  fix_argv (argvec)
       char **argvec;
  {
***************
*** 253,259 ****
          {
            if (temp[j] == '"')
              {
!               newtemp = (char *) xmalloc (len + 2);
                strncpy (newtemp, temp, j);
                newtemp [j] = '\\';
                strncpy (&newtemp [j+1], &temp [j], len-j);
--- 288,294 ----
          {
            if (temp[j] == '"')
              {
!               newtemp = xmalloc (len + 2);
                strncpy (newtemp, temp, j);
                newtemp [j] = '\\';
                strncpy (&newtemp [j+1], &temp [j], len-j);
***************
*** 267,302 ****
          argvec[i] = temp;
        }
  
!   return (char * const *) argvec;
  }
  
! #endif /* ! defined (__CYGWIN32__) */
  
  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;
       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;
--- 302,419 ----
          argvec[i] = temp;
        }
  
!   return (const char * const *) argvec;
  }
  
! #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, **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);
+     }
  
    pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
!     (_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,311 ****
  {
    int termstat;
  
!   pid = cwait (&termstat, pid, WAIT_CHILD);
  
    /* ??? Here's an opportunity to canonicalize the values in STATUS.
       Needed?  */
--- 422,428 ----
  {
    int termstat;
  
!   pid = _cwait (&termstat, pid, WAIT_CHILD);
  
    /* ??? Here's an opportunity to canonicalize the values in STATUS.
       Needed?  */
***************
*** 321,326 ****
--- 438,445 ----
  
    return pid;
  }
+ 
+ #endif /* ! defined (__CYGWIN32__) */
  
  #endif /* _WIN32 */
  

Regards,
Mumit -- khan@xraylith.wisc.edu
http://www.xraylith.wisc.edu/~khan/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]