diff options
author | Mumit Khan <khan@xraylith.wisc.edu> | 1998-01-17 21:33:56 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-01-17 14:33:56 -0700 |
commit | a3105a8956f319e63594d92be80f10d87f3b23c7 (patch) | |
tree | 4ddabc9c801c690d8e76c304fa2ac8d55ea7828e /gcc | |
parent | 77aff459558ec67ceafc407420e014433828f7a5 (diff) | |
download | gcc-a3105a8956f319e63594d92be80f10d87f3b23c7.zip gcc-a3105a8956f319e63594d92be80f10d87f3b23c7.tar.gz gcc-a3105a8956f319e63594d92be80f10d87f3b23c7.tar.bz2 |
pexecute.c (pexecute): New function for mingw32.
* 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/gcc.c | 2 | ||||
-rw-r--r-- | gcc/pexecute.c | 147 |
3 files changed, 143 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 06df5a3..7a660ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. @@ -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. */ diff --git a/gcc/pexecute.c b/gcc/pexecute.c index 5c2779f..f9690e4 100644 --- a/gcc/pexecute.c +++ b/gcc/pexecute.c @@ -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 |