This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
(5/8) i386-mingw32 fixes: pexecute/pwait
- To: egcs-bugs at cygnus dot com
- Subject: (5/8) i386-mingw32 fixes: pexecute/pwait
- From: Mumit Khan <khan at xraylith dot wisc dot edu>
- Date: Sun, 21 Dec 1997 02:41:19 -0600
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/