Commit a3105a89 by Mumit Khan Committed by Jeff Law

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
parent 77aff459
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> 1998-01-17 Lee Iverson <leei@Canada.AI.SRI.COM>
* reorg.c: #include "expr.h" for rtx prototypes. * reorg.c: #include "expr.h" for rtx prototypes.
......
...@@ -2159,7 +2159,7 @@ execute () ...@@ -2159,7 +2159,7 @@ execute ()
for (n_commands = 1, i = 0; i < argbuf_index; i++) for (n_commands = 1, i = 0; i < argbuf_index; i++)
if (strcmp (argbuf[i], "|") == 0) if (strcmp (argbuf[i], "|") == 0)
{ /* each command. */ { /* 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"); fatal ("-pipe not supported");
#endif #endif
argbuf[i] = 0; /* termination of command args. */ argbuf[i] = 0; /* termination of command args. */
......
...@@ -223,20 +223,55 @@ pwait (pid, status, flags) ...@@ -223,20 +223,55 @@ pwait (pid, status, flags)
#if defined (_WIN32) #if defined (_WIN32)
#include <process.h> #include <process.h>
#include <signal.h>
extern int _spawnv ();
extern int _spawnvp ();
#ifdef __CYGWIN32__ #ifdef __CYGWIN32__
#define fix_argv(argvec) (argvec) #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 /* This is a kludge to get around the Microsoft C spawn functions' propensity
to remove the outermost set of double quotes from all arguments. */ to remove the outermost set of double quotes from all arguments. */
char * const * const char * const *
fix_argv (argvec) fix_argv (argvec)
char **argvec; char **argvec;
{ {
...@@ -253,7 +288,7 @@ fix_argv (argvec) ...@@ -253,7 +288,7 @@ fix_argv (argvec)
{ {
if (temp[j] == '"') if (temp[j] == '"')
{ {
newtemp = (char *) xmalloc (len + 2); newtemp = xmalloc (len + 2);
strncpy (newtemp, temp, j); strncpy (newtemp, temp, j);
newtemp [j] = '\\'; newtemp [j] = '\\';
strncpy (&newtemp [j+1], &temp [j], len-j); strncpy (&newtemp [j+1], &temp [j], len-j);
...@@ -267,36 +302,118 @@ fix_argv (argvec) ...@@ -267,36 +302,118 @@ fix_argv (argvec)
argvec[i] = temp; 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 int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program; const char *program;
char * const *argv; char * const *argv;
const char *this_pname; const char *this_pname;
const char *temp_base; const char *temp_base;
char **errmsg_fmt; char **errmsg_fmt, **errmsg_arg;
const char **errmsg_arg;
int flags; int flags;
{ {
int pid; 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) 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) if (pid == -1)
{ {
*errmsg_fmt = install_error_msg; *errmsg_fmt = install_error_msg;
*errmsg_arg = program; *errmsg_arg = program;
return -1; return -1;
} }
return pid; 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 int
pwait (pid, status, flags) pwait (pid, status, flags)
int pid; int pid;
...@@ -305,7 +422,7 @@ pwait (pid, status, flags) ...@@ -305,7 +422,7 @@ pwait (pid, status, flags)
{ {
int termstat; int termstat;
pid = cwait (&termstat, pid, WAIT_CHILD); pid = _cwait (&termstat, pid, WAIT_CHILD);
/* ??? Here's an opportunity to canonicalize the values in STATUS. /* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */ Needed? */
...@@ -322,6 +439,8 @@ pwait (pid, status, flags) ...@@ -322,6 +439,8 @@ pwait (pid, status, flags)
return pid; return pid;
} }
#endif /* ! defined (__CYGWIN32__) */
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifdef OS2 #ifdef OS2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment