This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH to support native Windows builds
Paolo Carlini wrote:
Mark Mitchell wrote:
This patch provides support for building GCC on native Windows (i.e.,
MinGW) as opposed to Cygwin.
Mark, it looks like nobody wants to see the actual patch ;)
Out of curiosity, I would.
Didn't I attach it? OK, here it is again.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
Index: libiberty/pex-unix.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pex-unix.c,v
retrieving revision 1.1
retrieving revision 1.1.20.1
diff -c -5 -p -r1.1 -r1.1.20.1
*** libiberty/pex-unix.c 24 Jan 2003 20:02:11 -0000 1.1
--- libiberty/pex-unix.c 23 Dec 2003 21:43:48 -0000 1.1.20.1
*************** Boston, MA 02111-1307, USA. */
*** 22,31 ****
--- 22,32 ----
#include "pex-common.h"
#include <stdio.h>
#include <errno.h>
+ #include <fcntl.h>
#ifdef NEED_DECLARATION_ERRNO
extern int errno;
#endif
#ifdef HAVE_STRING_H
#include <string.h>
*************** extern int errno;
*** 42,158 ****
#ifndef HAVE_WAITPID
#define waitpid(pid, status, flags) wait(status)
#endif
! extern int execv ();
! extern int execvp ();
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 ATTRIBUTE_UNUSED;
! char **errmsg_fmt, **errmsg_arg;
! int flags;
{
- int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
int pid;
- int pdes[2];
- 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) < 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;
! }
/* Fork a subprocess; wait and retry if it fails. */
sleep_interval = 1;
pid = -1;
for (retries = 0; retries < 4; retries++)
{
pid = fork ();
! if (pid >= 0)
break;
sleep (sleep_interval);
sleep_interval *= 2;
}
! switch (pid)
{
! case -1:
! *errmsg_fmt = "fork";
! *errmsg_arg = NULL;
return -1;
! case 0: /* child */
! /* Move the input and output pipes into place, if necessary. */
! if (input_desc != STDIN_FILE_NO)
! {
! close (STDIN_FILE_NO);
! dup (input_desc);
! close (input_desc);
! }
! if (output_desc != STDOUT_FILE_NO)
{
! close (STDOUT_FILE_NO);
! dup (output_desc);
! close (output_desc);
}
! /* Close the parent's descs that aren't wanted here. */
! if (last_pipe_input != STDIN_FILE_NO)
! close (last_pipe_input);
!
! /* Exec the program. */
! (*func) (program, argv);
!
! fprintf (stderr, "%s: ", this_pname);
! fprintf (stderr, install_error_msg, program);
! fprintf (stderr, ": %s\n", xstrerror (errno));
! exit (-1);
! /* NOTREACHED */
! return 0;
!
! default:
! /* In the parent, after forking.
! Close the descriptors that we made for this child. */
! if (input_desc != STDIN_FILE_NO)
! close (input_desc);
! if (output_desc != STDOUT_FILE_NO)
! close (output_desc);
! /* Return child's process number. */
! return pid;
}
}
int
pwait (pid, status, flags)
int pid;
--- 43,245 ----
#ifndef HAVE_WAITPID
#define waitpid(pid, status, flags) wait(status)
#endif
! /* These are needed to prevent the build from bombing out on
! platforms (such as embedded targets) where no pex-*.c
! will work at all (but we try to build this one anyway). */
! extern int execvp();
! extern int execv();
!
! #define xdup2(a, b) do { \
! if (a != -1) \
! if (dup2 (a, b) < 0) \
! { \
! fprintf (stderr, "%s: dup2(%d, %d): %s\n", \
! this_program, a, b, xstrerror(errno)); \
! exit(127); \
! } \
! } while (0);
!
! #define xclose(fd) do { \
! if (fd != -1) \
! { \
! close (fd); \
! fd = -1; \
! } \
! } while (0)
!
! static const char *this_program = "<unknown>";
!
! /* Execute PROGRAM with argument vector ARGV. If SEARCH is false,
! PROGRAM is expected to be a usable pathname already; otherwise it
! is looked for in the locations specified by the PATH environment
! variable (as per execvp).
!
! STDIN_FD, STDOUT_FD, and STDERR_FD are file descriptors which
! should be established as the child process's stdin, stdout, or
! stderr, respectively, or -1 if the child should inherit the
! parent's value of that descriptor. If any of these is not -1, it
! should be a valid file descriptor marked close-on-exec. */
int
! pexec (program, argv, search, stdin_fd, stdout_fd, stderr_fd)
const char *program;
! char *const *argv;
! int search;
! int stdin_fd;
! int stdout_fd;
! int stderr_fd;
{
int pid;
int retries, sleep_interval;
! /* Canonicalize file descriptor arguments. */
! stdin_fd = (stdin_fd == STDIN_FILE_NO) ? -1 : stdin_fd;
! stdout_fd = (stdout_fd == STDOUT_FILE_NO) ? -1 : stdout_fd;
! stderr_fd = (stderr_fd == STDERR_FILE_NO) ? -1 : stderr_fd;
!
! /* If exec fails, the child will write a message to stderr, using
! fprintf. It must therefore use exit(), not _exit(). So we have
! to flush pending output here to avoid duplicate output. */
! fflush (NULL);
/* Fork a subprocess; wait and retry if it fails. */
sleep_interval = 1;
pid = -1;
for (retries = 0; retries < 4; retries++)
{
pid = fork ();
! if (__builtin_expect (pid >= 0, 1))
break;
sleep (sleep_interval);
sleep_interval *= 2;
}
! if (pid != 0)
{
! /* Parent; fork either succeeded or failed. In either case we
! close the file descriptors passed to the child, to make life
! easier for callers. Don't clobber errno while doing so. */
! int serrno = errno;
! xclose (stdin_fd);
! xclose (stdout_fd);
! xclose (stderr_fd);
! errno = serrno;
!
! return pid;
! }
!
! /* We are the child. Set up I/O redirections and call exec.
! FIXME: Report errors without calling fprintf() in the child
! (so we can use vfork). */
! xdup2 (stdin_fd, STDIN_FILE_NO);
! xdup2 (stdout_fd, STDOUT_FILE_NO);
! xdup2 (stderr_fd, STDERR_FILE_NO);
!
! (search ? execvp : execv) (program, argv);
!
! /* If we got here exec failed. */
! /*fprintf (stderr, install_error_msg, XXX completely wrong format string */
! fprintf (stderr, "%s tried to exec %s but failed (%s)\n",
! this_program, program, xstrerror (errno));
! exit (127);
! }
!
! /* Create a pipe suitable for use with pexec - in particular, both
! ends of the pipe are set close-on-exec. Returns 0 if successful,
! -1 otherwise. Returns the pipe in the array argument, just as
! pipe(2) does. */
!
! int
! pmkpipe (thepipe)
! int thepipe[2];
! {
! if (pipe (thepipe))
! return -1;
!
! if (fcntl (thepipe[0], F_SETFD, FD_CLOEXEC)
! || fcntl (thepipe[1], F_SETFD, FD_CLOEXEC))
! {
! int serrno = errno;
! close (thepipe[0]);
! close (thepipe[1]);
! errno = serrno;
return -1;
+ }
+ return 0;
+ }
! int
! pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
! const char *program;
! char * const *argv;
! const char *this_pname ATTRIBUTE_UNUSED;
! const char *temp_base ATTRIBUTE_UNUSED;
! char **errmsg_fmt, **errmsg_arg;
! int flags;
! {
! /* Pipe waiting from last process, to be used as input for the next
! one. Value is -1 if no pipe is waiting (i.e. the next command is
! the first of a group). */
! static int last_pipe_input = -1;
!
! int pid;
! int pdesc[2];
! int serrno;
! int child_stdin = -2, child_stdout = -2;
! #if 0
! FILE* P = fopen("/dev/pts/1", "w");
! printf(P, "pex-unix.c:pexecute called with program %s\n", program);
! #endif
! /* If this is the first process, last_pipe_input ought to be -1. */
! if (flags & PEXECUTE_FIRST)
! if (last_pipe_input != -1)
! abort ();
!
! child_stdin = last_pipe_input;
!
! /* If this is the last process, don't do anything with its output
! pipe. */
! if (flags & PEXECUTE_LAST)
! child_stdout = -1;
! else
! {
! /* Create a pipe to go between this process and the next one in
! the pipeline. */
! if (pmkpipe (pdesc))
{
! *errmsg_fmt = "pipe";
! *errmsg_arg = NULL;
! return -1;
}
+ last_pipe_input = pdesc[READ_PORT];
+ child_stdout = pdesc[WRITE_PORT];
+ }
! pid = pexec (program, argv, (flags & PEXECUTE_SEARCH),
! child_stdin, child_stdout, -1);
! serrno = errno;
! xclose (child_stdin);
! xclose (child_stdout);
!
! /* To prevent a file descriptor leak, close last_pipe_input if pexec
! failed. */
! if (pid == -1)
! xclose (last_pipe_input);
!
! errno = serrno;
!
! if (pid == -1)
! {
! *errmsg_fmt = "fork";
! *errmsg_arg = NULL;
}
+
+ return pid;
}
int
pwait (pid, status, flags)
int pid;
*************** pwait (pid, status, flags)
*** 162,166 ****
--- 249,260 ----
/* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */
pid = waitpid (pid, status, 0);
return pid;
}
+
+ void
+ pexec_set_program_name (name)
+ const char *name;
+ {
+ this_program = name;
+ }
Index: libiberty/pex-win32.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pex-win32.c,v
retrieving revision 1.3
retrieving revision 1.3.10.2
diff -c -5 -p -r1.3 -r1.3.10.2
*** libiberty/pex-win32.c 5 Jul 2003 00:52:07 -0000 1.3
--- libiberty/pex-win32.c 12 Feb 2004 04:48:13 -0000 1.3.10.2
*************** License along with libiberty; see the fi
*** 19,250 ****
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "pex-common.h"
! #ifdef HAVE_STRING_H
! #include <string.h>
! #endif
! #ifdef HAVE_UNISTD_H
! #include <unistd.h>
! #endif
! #ifdef HAVE_SYS_WAIT_H
! #include <sys/wait.h>
! #endif
!
! #include <process.h>
#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
!
! /* This is a kludge to get around the Microsoft C spawn functions' propensity
! to remove the outermost set of double quotes from all arguments. */
!
! static const char * const *
! fix_argv (argvec)
! char **argvec;
! {
! int i;
! char * command0 = argvec[0];
!
! /* Ensure that the executable pathname uses Win32 backslashes. */
! for (; *command0 != '\0'; command0++)
! if (*command0 == '/')
! *command0 = '\\';
!
! for (i = 1; argvec[i] != 0; i++)
{
! int len, j;
! char *temp, *newtemp;
! temp = argvec[i];
! len = strlen (temp);
! for (j = 0; j < len; j++)
! {
! if (temp[j] == '"')
! {
! newtemp = xmalloc (len + 2);
! strncpy (newtemp, temp, j);
! newtemp [j] = '\\';
! strncpy (&newtemp [j+1], &temp [j], len-j);
! newtemp [len+1] = 0;
! temp = newtemp;
! len++;
! j++;
! }
! }
!
! argvec[i] = temp;
! }
!
! for (i = 0; argvec[i] != 0; i++)
! {
! if (strpbrk (argvec[i], " \t"))
! {
! int len, trailing_backslash;
! char *temp;
!
! len = strlen (argvec[i]);
! trailing_backslash = 0;
!
! /* There is an added complication when an arg with embedded white
! space ends in a backslash (such as in the case of -iprefix arg
! passed to cpp). The resulting quoted strings gets misinterpreted
! by the command interpreter -- it thinks that the ending quote
! is escaped by the trailing backslash and things get confused.
! We handle this case by escaping the trailing backslash, provided
! it was not escaped in the first place. */
! if (len > 1
! && argvec[i][len-1] == '\\'
! && argvec[i][len-2] != '\\')
! {
! trailing_backslash = 1;
! ++len; /* to escape the final backslash. */
! }
!
! len += 2; /* and for the enclosing quotes. */
!
! temp = xmalloc (len + 1);
! temp[0] = '"';
! strcpy (temp + 1, argvec[i]);
! if (trailing_backslash)
! temp[len-2] = '\\';
! temp[len-1] = '"';
! temp[len] = '\0';
! argvec[i] = temp;
}
}
! return (const char * const *) argvec;
}
- /* 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 ATTRIBUTE_UNUSED;
const char *temp_base ATTRIBUTE_UNUSED;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
int pid;
! int pdes[2];
! int org_stdin = -1;
! int org_stdout = -1;
! int input_desc, output_desc;
!
! /* 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 = (char*) 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;
int *status;
int flags ATTRIBUTE_UNUSED;
{
! int termstat;
!
! pid = _cwait (&termstat, pid, WAIT_CHILD);
!
! /* ??? Here's an opportunity to canonicalize the values in STATUS.
! Needed? */
!
! /* cwait returns the child process exit code in termstat.
! A value of 3 indicates that the child caught a signal, but not
! which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we
! report SIGABRT. */
! if (termstat == 3)
! *status = SIGABRT;
! else
! *status = (((termstat) & 0xff) << 8);
return pid;
}
--- 19,425 ----
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "pex-common.h"
! #define WIN32_LEAN_AND_MEAN
! #include <windows.h>
#include <io.h>
#include <fcntl.h>
! #include <string.h>
! #include <stdlib.h>
! static const char *this_program;
! #define xclose(fd) do { \
! if (fd != -1) \
! { \
! _close (fd); \
! fd = -1; \
! } \
! } while (0)
!
! /* Returns a string containing a text error message, after a Windows
! "system call" failed. Caller is responsible for deallocating it
! (with LocalFree()). */
! static char *
! get_last_error_as_text ()
! {
! DWORD last_error = GetLastError();
! LPSTR result;
!
! /* We assume the error message belongs to 'the system' as opposed
! to some module (which we would have to load, and we don't know
! which one it is). */
! DWORD flags = (FORMAT_MESSAGE_ALLOCATE_BUFFER
! | FORMAT_MESSAGE_IGNORE_INSERTS
! | FORMAT_MESSAGE_FROM_SYSTEM);
!
! /* Default language. */
! DWORD langid = MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT);
!
! /* Yes, you are supposed to cast LPSTR* to LPSTR in the fifth
! argument. This interface is intrinsically type-unsafe. */
! FormatMessageA(flags, 0, last_error, langid, (LPSTR) &result, 0, 0);
!
! return result;
! }
!
! static char *
! argv_to_cmdline(argv)
! char *const *argv;
! {
! char *cmdline;
! char *p;
! size_t cmdline_len;
! int i, j;
!
! cmdline_len = 0;
! for (i = 0; argv[i]; i++)
! {
! /* We quote every last argument. This simplifies the problem;
! we need only escape embedded double-quote and backslash
! characters. */
! for (j = 0; argv[i][j]; j++)
! if (argv[i][j] == '\\' || argv[i][j] == '"')
! cmdline_len++;
! cmdline_len += j;
! cmdline_len += 3; /* for leading and trailing quotes and space */
! }
!
! cmdline = xmalloc (cmdline_len);
! p = cmdline;
! for (i = 0; argv[i]; i++)
{
! *p++ = '"';
! for (j = 0; argv[i][j]; j++)
! {
! if (argv[i][j] == '\\' || argv[i][j] == '"')
! *p++ = '\\';
! *p++ = argv[i][j];
! }
! *p++ = '"';
! *p++ = ' ';
! }
! p[-1] = '\0';
! return cmdline;
! }
! static const char *const
! std_suffixes[] = {
! ".com",
! ".exe",
! ".bat",
! ".cmd",
! 0
! };
! static const char *const
! no_suffixes[] = {
! "",
! 0
! };
! static char *
! find_executable (program, search)
! const char *program;
! int search;
! {
! char *full_executable;
! char *e;
! size_t fe_len;
! const char *path = 0;
! const char *const *ext;
! const char *p, *q;
! size_t proglen = strlen (program);
! int has_extension = !!strchr (program, '.');
! int has_slash = (strchr (program, '/') || strchr (program, '\\'));
! HANDLE h;
!
! if (has_slash)
! search = 0;
!
! if (search)
! path = getenv ("PATH");
! if (!path)
! path = "";
!
! fe_len = 0;
! for (p = path; *p; p = q)
! {
! q = p;
! while (*q != ';' && *q != '\0')
! q++;
! if ((size_t)(q - p) > fe_len)
! fe_len = q - p;
! if (*q == ';')
! q++;
! }
! fe_len = fe_len + 1 + proglen + (has_extension ? 1 : 5);
! full_executable = xmalloc (fe_len);
!
! p = path;
! do
! {
! q = p;
! while (*q != ';' && *q != '\0')
! q++;
!
! e = full_executable;
! memcpy (e, p, q - p);
! e += (q - p);
! if (q - p)
! *e++ = '\\';
! strcpy (e, program);
!
! if (*q == ';')
! q++;
!
! for (e = full_executable; *e; e++)
! if (*e == '/')
! *e = '\\';
!
! /* At this point, e points to the terminating NUL character for
! full_executable. */
! for (ext = has_extension ? no_suffixes : std_suffixes; *ext; ext++)
! {
! /* Remove any current extension. */
! *e = '\0';
! /* Add the new one. */
! strcat (full_executable, *ext);
!
! /* Attempt to open this file. */
! h = CreateFile (full_executable, GENERIC_READ,
! FILE_SHARE_READ | FILE_SHARE_WRITE,
! 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
! if (h != INVALID_HANDLE_VALUE)
! goto found;
}
+ p = q;
}
+ while (*p);
+ free (full_executable);
+ return 0;
+
+ found:
+ CloseHandle (h);
+ return full_executable;
+ }
! int
! pexec (program, argv, search, stdin_fd, stdout_fd, stderr_fd)
! const char *program;
! char *const *argv;
! int search;
! int stdin_fd;
! int stdout_fd;
! int stderr_fd;
! {
! char *cmdline = argv_to_cmdline (argv);
! char *executable = find_executable (program, search);
! STARTUPINFO si;
! PROCESS_INFORMATION pinf;
! HANDLE me;
!
! /* Canonicalize file descriptor arguments. */
! stdin_fd = (stdin_fd == STDIN_FILE_NO) ? -1 : stdin_fd;
! stdout_fd = (stdout_fd == STDOUT_FILE_NO) ? -1 : stdout_fd;
! stderr_fd = (stderr_fd == STDERR_FILE_NO) ? -1 : stderr_fd;
!
! memset (&si, 0, sizeof si);
! si.cb = sizeof si;
! si.dwFlags = STARTF_USESTDHANDLES;
! si.hStdInput = INVALID_HANDLE_VALUE;
! si.hStdOutput = INVALID_HANDLE_VALUE;
! si.hStdError = INVALID_HANDLE_VALUE;
!
! me = GetCurrentProcess();
!
! if (!DuplicateHandle (me,
! (stdin_fd == -1)
! ? GetStdHandle (STD_INPUT_HANDLE)
! : (HANDLE)_get_osfhandle (stdin_fd),
! me, &si.hStdInput,
! 0, TRUE, DUPLICATE_SAME_ACCESS))
! goto cleanup;
! if (!DuplicateHandle (me,
! (stdout_fd == -1)
! ? GetStdHandle (STD_OUTPUT_HANDLE)
! : (HANDLE)_get_osfhandle (stdout_fd),
! me, &si.hStdOutput,
! 0, TRUE, DUPLICATE_SAME_ACCESS))
! goto cleanup;
! if (!DuplicateHandle (me,
! (stderr_fd == -1)
! ? GetStdHandle (STD_ERROR_HANDLE)
! : (HANDLE)_get_osfhandle (stderr_fd),
! me, &si.hStdError,
! 0, TRUE, DUPLICATE_SAME_ACCESS))
! goto cleanup;
!
!
! if (!CreateProcess (executable, cmdline,
! 0, 0, TRUE, 0, 0, 0,
! &si, &pinf))
! goto cleanup;
!
! CloseHandle (pinf.hThread);
!
! done:
! /* Close file descriptors passed to the child (whether or not we
! managed to create a child). */
! xclose (stdin_fd);
! xclose (stdout_fd);
! if (stderr_fd != stdout_fd)
! xclose (stderr_fd);
! if (si.hStdInput != INVALID_HANDLE_VALUE)
! CloseHandle (si.hStdInput);
! if (si.hStdOutput != INVALID_HANDLE_VALUE)
! CloseHandle (si.hStdOutput);
! if (si.hStdError != INVALID_HANDLE_VALUE)
! CloseHandle (si.hStdError);
!
! free (executable);
! free (cmdline);
!
! /* Treat the process handle as an integer. It would be cleaner to
! define a pid_t type that would be used by all libiberty callers;
! that type would be HANDLE under Windows. However, that would
! require changing a lot of existing code. */
! if (sizeof (HANDLE) != sizeof (int))
! abort ();
! return (int) pinf.hProcess;
!
! cleanup:
! {
! /* Error strings on win32 include newlines. */
! char *errstr = get_last_error_as_text ();
! fprintf (stderr, "%s tried to spawn %s but failed: %s",
! this_program, program, errstr);
! LocalFree (errstr);
! }
! /* Fortuitously, INVALID_HANDLE_VALUE is -1, which is the
! conventional error return value for pwait. */
! pinf.hProcess = INVALID_HANDLE_VALUE;
! goto done;
! }
!
! /* MSVCRT's _pipe() creates pipes that can be inherited, which is not
! what we want, so we go directly to CreatePipe(). */
! int
! pmkpipe (thepipe)
! int thepipe[2];
! {
! HANDLE read_port;
! HANDLE write_port;
!
! if (!CreatePipe (&read_port, &write_port, 0, 0))
! return -1;
!
! thepipe[0] = _open_osfhandle ((long)read_port, _O_RDONLY);
! thepipe[1] = _open_osfhandle ((long)write_port, _O_WRONLY);
! if (thepipe[0] == -1 || thepipe[1] == -1)
! {
! if (thepipe[0] == -1)
! CloseHandle (read_port);
! else
! _close (thepipe[0]);
! if (thepipe[1] == -1)
! CloseHandle (write_port);
! else
! _close (thepipe[1]);
! return -1;
! }
! return 0;
}
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname ATTRIBUTE_UNUSED;
const char *temp_base ATTRIBUTE_UNUSED;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
+ /* Pipe waiting from last process, to be used as input for the next
+ one. Value is -1 if no pipe is waiting (i.e. the next command is
+ the first of a group). */
+ static int last_pipe_input = -1;
+
int pid;
! int pdesc[2];
! int serrno;
! int child_stdin = -2, child_stdout = -2;
! /* If this is the first process, last_pipe_input ought to be -1. */
if (flags & PEXECUTE_FIRST)
! if (last_pipe_input != -1)
! abort ();
! child_stdin = last_pipe_input;
! /* If this is the last process, don't do anything with its output
! pipe. */
! if (flags & PEXECUTE_LAST)
! child_stdout = -1;
! else
{
! /* Create a pipe to go between this process and the next one in
! the pipeline. */
! if (pmkpipe (pdesc))
{
*errmsg_fmt = "pipe";
*errmsg_arg = NULL;
return -1;
}
! last_pipe_input = pdesc[READ_PORT];
! child_stdout = pdesc[WRITE_PORT];
}
! pid = pexec (program, argv, (flags & PEXECUTE_SEARCH),
! child_stdin, child_stdout, -1);
! serrno = errno;
! xclose (child_stdin);
! xclose (child_stdout);
! /* To prevent a file descriptor leak, close last_pipe_input if pexec
! failed. */
! if (pid == -1)
! xclose (last_pipe_input);
! errno = serrno;
if (pid == -1)
{
! *errmsg_fmt = "spawn";
! *errmsg_arg = NULL;
}
return pid;
}
int
pwait (pid, status, flags)
int pid;
int *status;
int flags ATTRIBUTE_UNUSED;
{
! /* The return value from pexecute is actually a HANDLE. */
! HANDLE proch = (HANDLE) pid;
! if (WaitForSingleObject (proch, INFINITE) != WAIT_OBJECT_0)
! {
! CloseHandle (proch);
! return -1;
! }
+ GetExitCodeProcess (proch, (DWORD *)status);
+ CloseHandle (proch);
return pid;
}
+
+ void
+ pexec_set_program_name (name)
+ const char *name;
+ {
+ this_program = name;
+ }
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.35
retrieving revision 1.35.10.1
diff -c -5 -p -r1.35 -r1.35.10.1
*** include/libiberty.h 15 May 2003 19:02:12 -0000 1.35
--- include/libiberty.h 23 Dec 2003 17:25:29 -0000 1.35.10.1
*************** extern char **dupargv PARAMS ((char **))
*** 72,82 ****
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_BASENAME
! #if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (HAVE_DECL_BASENAME)
extern char *basename PARAMS ((const char *));
#else
extern char *basename ();
#endif
#endif
--- 72,82 ----
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_BASENAME
! #if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__sun__) || defined (HAVE_DECL_BASENAME)
extern char *basename PARAMS ((const char *));
#else
extern char *basename ();
#endif
#endif
*************** extern void hex_init PARAMS ((void));
*** 272,285 ****
/* Execute a program. */
extern int pexecute PARAMS ((const char *, char * const *, const char *,
const char *, char **, char **, int));
! /* Wait for pexecute to finish. */
extern int pwait PARAMS ((int, int *, int));
#if !HAVE_DECL_ASPRINTF
/* Like sprintf but provides a pointer to malloc'd storage, which must
be freed by the caller. */
extern int asprintf PARAMS ((char **, const char *, ...)) ATTRIBUTE_PRINTF_2;
--- 272,340 ----
/* Execute a program. */
extern int pexecute PARAMS ((const char *, char * const *, const char *,
const char *, char **, char **, int));
! /* Slightly lower level routines which are more flexible than pexecute: */
! extern int pmkpipe PARAMS ((int[2]));
!
! extern int pexec PARAMS ((const char *, char * const *, int, int, int, int));
!
! /* Wait for a process created by pexecute or pexec to finish. */
extern int pwait PARAMS ((int, int *, int));
+ /* Set the program name used for error messages by pexec. */
+ extern void pexec_set_program_name PARAMS ((const char *));
+
+ #if !defined(_WIN32) || defined(__CYGWIN__)
+
+ #ifndef WIFSIGNALED
+ #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
+ #endif
+ #ifndef WTERMSIG
+ #define WTERMSIG(S) ((S) & 0x7f)
+ #endif
+ #ifndef WIFEXITED
+ #define WIFEXITED(S) (((S) & 0xff) == 0)
+ #endif
+ #ifndef WEXITSTATUS
+ #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+ #endif
+ #ifndef WSTOPSIG
+ #define WSTOPSIG WEXITSTATUS
+ #endif
+ #ifndef WCOREDUMP
+ #define WCOREDUMP(S) ((S) & WCOREFLG)
+ #endif
+ #ifndef WCOREFLG
+ #define WCOREFLG 0200
+ #endif
+
+ #else /* defined(_WIN32) && ! defined(__CYGWIN__) */
+
+ #ifndef WIFSIGNALED
+ #define WIFSIGNALED(S) ((void)(S), 0)
+ #endif
+ #ifndef WTERMSIG
+ #define WTERMSIG(S) ((void)(S), 0)
+ #endif
+ #ifndef WIFEXITED
+ #define WIFEXITED(S) ((void)(S), 1)
+ #endif
+ #ifndef WEXITSTATUS
+ #define WEXITSTATUS(S) (S)
+ #endif
+ #ifndef WSTOPSIG
+ #define WSTOPSIG WEXITSTATUS
+ #endif
+ #ifndef WCOREDUMP
+ #define WCOREDUMP(S) ((void)(S), 0)
+ #endif
+
+ #endif
+
#if !HAVE_DECL_ASPRINTF
/* Like sprintf but provides a pointer to malloc'd storage, which must
be freed by the caller. */
extern int asprintf PARAMS ((char **, const char *, ...)) ATTRIBUTE_PRINTF_2;
Index: gcc/collect2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/collect2.c,v
retrieving revision 1.154
retrieving revision 1.154.4.4
diff -c -5 -p -r1.154 -r1.154.4.4
*** gcc/collect2.c 17 Oct 2003 11:27:13 -0000 1.154
--- gcc/collect2.c 3 Mar 2004 16:02:17 -0000 1.154.4.4
*************** Software Foundation, 59 Temple Place - S
*** 28,54 ****
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
! #include <signal.h>
! #if ! defined( SIGCHLD ) && defined( SIGCLD )
! # define SIGCHLD SIGCLD
! #endif
!
! #ifdef vfork /* Autoconf may define this to fork for us. */
! # define VFORK_STRING "fork"
#else
! # define VFORK_STRING "vfork"
! #endif
! #ifdef HAVE_VFORK_H
! #include <vfork.h>
! #endif
! #ifdef VMS
! #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
! lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
! #endif /* VMS */
#ifndef LIBRARY_PATH_ENV
#define LIBRARY_PATH_ENV "LIBRARY_PATH"
#endif
--- 28,46 ----
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
! #ifdef _WIN32
! # define WIN32_LEAN_AND_MEAN
! # include <windows.h>
#else
! # include <signal.h>
! # if ! defined( SIGCHLD ) && defined( SIGCLD )
! # define SIGCHLD SIGCLD
! # endif
! #endif
#ifndef LIBRARY_PATH_ENV
#define LIBRARY_PATH_ENV "LIBRARY_PATH"
#endif
*************** static struct path_prefix libpath_lib_di
*** 247,257 ****
static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
&libpath_lib_dirs, NULL};
static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
#endif
! static void handler (int);
static int is_ctor_dtor (const char *);
static char *find_a_file (struct path_prefix *, const char *);
static void add_prefix (struct path_prefix *, const char *);
static void prefix_from_env (const char *, struct path_prefix *);
static void prefix_from_string (const char *, struct path_prefix *);
--- 239,259 ----
static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
&libpath_lib_dirs, NULL};
static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
#endif
! static void clean_up_temp_files (void);
! #ifdef _WIN32
! static BOOL WINAPI handler (DWORD);
! static LONG unhanded_filter (LPEXCEPTION_POINTERS);
! #else
! static void handler (int);
! #endif
! static void install_handlers (void);
! static void disable_break (void);
! static void enable_break (void);
!
static int is_ctor_dtor (const char *);
static char *find_a_file (struct path_prefix *, const char *);
static void add_prefix (struct path_prefix *, const char *);
static void prefix_from_env (const char *, struct path_prefix *);
static void prefix_from_string (const char *, struct path_prefix *);
*************** static int is_in_list (const char *, str
*** 288,317 ****
static void write_aix_file (FILE *, struct id *);
static char *resolve_lib_name (const char *);
#endif
static char *extract_string (const char **);
- #ifndef HAVE_DUP2
- static int
- dup2 (int oldfd, int newfd)
- {
- int fdtmp[256];
- int fdx = 0;
- int fd;
-
- if (oldfd == newfd)
- return oldfd;
- close (newfd);
- while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
- fdtmp[fdx++] = fd;
- while (fdx > 0)
- close (fdtmp[--fdx]);
-
- return fd;
- }
- #endif /* ! HAVE_DUP2 */
-
/* Delete tempfiles and exit function. */
void
collect_exit (int status)
{
--- 290,299 ----
*************** fancy_abort (void)
*** 405,415 ****
{
fatal ("internal error");
}
static void
! handler (int signo)
{
if (c_file != 0 && c_file[0])
maybe_unlink (c_file);
if (o_file != 0 && o_file[0])
--- 387,397 ----
{
fatal ("internal error");
}
static void
! clean_up_temp_files (void)
{
if (c_file != 0 && c_file[0])
maybe_unlink (c_file);
if (o_file != 0 && o_file[0])
*************** handler (int signo)
*** 420,434 ****
--- 402,522 ----
#ifdef COLLECT_EXPORT_LIST
if (export_file != 0 && export_file[0])
maybe_unlink (export_file);
#endif
+ }
+
+ /* Signal handling needs to be drastically different between Windows
+ and Unix. */
+ #ifdef _WIN32
+
+ static BOOL WINAPI
+ handler (DWORD signo ATTRIBUTE_UNUSED)
+ {
+ clean_up_temp_files ();
+ return FALSE; /* not handled - default handler will terminate process */
+ }
+
+ static LONG
+ unhandled_filter (LPEXCEPTION_POINTERS pointers ATTRIBUTE_UNUSED)
+ {
+ clean_up_temp_files ();
+ return EXCEPTION_CONTINUE_SEARCH; /* carry on and terminate process */
+ }
+
+
+ static void
+ install_handlers (void)
+ {
+ SetConsoleCtrlHandler (handler, TRUE);
+ /* This is not really the right way to do this; in fact I'm not
+ sure it will work. But it might. */
+ SetUnhandledExceptionFilter (unhandled_filter);
+ }
+ static void
+ disable_break (void)
+ {
+ /* This only works on Windows NT, and only disables CTRL-C;
+ CTRL-BREAK is not disabled (but does get caught by the handler). */
+ if (!(GetVersion() & 0x80000000))
+ SetConsoleCtrlHandler (NULL, TRUE);
+ }
+
+ static void
+ enable_break (void)
+ {
+ if (!(GetVersion() & 0x80000000))
+ SetConsoleCtrlHandler (NULL, FALSE);
+ }
+
+ #else /* not _WIN32 */
+
+ static void
+ handler (int signo)
+ {
+ clean_up_temp_files ();
signal (signo, SIG_DFL);
kill (getpid (), signo);
}
+ static void
+ install_handlers ()
+ {
+ #ifdef SIGQUIT
+ if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
+ signal (SIGQUIT, handler);
+ #endif
+ if (signal (SIGINT, SIG_IGN) != SIG_IGN)
+ signal (SIGINT, handler);
+ #ifdef SIGALRM
+ if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
+ signal (SIGALRM, handler);
+ #endif
+ #ifdef SIGHUP
+ if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
+ signal (SIGHUP, handler);
+ #endif
+ if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
+ signal (SIGSEGV, handler);
+ #ifdef SIGBUS
+ if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
+ signal (SIGBUS, handler);
+ #endif
+ #ifdef SIGCHLD
+ /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+ receive the signal. A different setting is inheritable */
+ signal (SIGCHLD, SIG_DFL);
+ #endif
+ }
+
+ static void (*int_handler) PARAMS ((int));
+ #ifdef SIGQUIT
+ static void (*quit_handler) PARAMS ((int));
+ #endif
+
+ static void
+ disable_break ()
+ {
+ int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
+ #ifdef SIGQUIT
+ quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
+ #endif
+ }
+
+ static void
+ enable_break ()
+ {
+ signal (SIGINT, int_handler);
+ #ifdef SIGQUIT
+ signal (SIGQUIT, quit_handler);
+ #endif
+ }
+
+ #endif /* not _WIN32 */
+
int
file_exists (const char *name)
{
return access (name, R_OK) == 0;
*************** main (int argc, char **argv)
*** 819,844 ****
char **object_lst;
const char **object;
int first_file;
int num_c_args = argc+9;
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
/* Suppress demangling by the real linker, which may be broken. */
putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
#if defined (COLLECT2_HOST_INITIALIZATION)
/* Perform system dependent initialization, if necessary. */
COLLECT2_HOST_INITIALIZATION;
#endif
- #ifdef SIGCHLD
- /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
- receive the signal. A different setting is inheritable */
- signal (SIGCHLD, SIG_DFL);
- #endif
-
gcc_init_libintl ();
/* Do not invoke xcalloc before this point, since locale needs to be
set first, in case a diagnostic is issued. */
--- 907,928 ----
char **object_lst;
const char **object;
int first_file;
int num_c_args = argc+9;
+ pexec_set_program_name (argv[0]);
+
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
/* Suppress demangling by the real linker, which may be broken. */
putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
#if defined (COLLECT2_HOST_INITIALIZATION)
/* Perform system dependent initialization, if necessary. */
COLLECT2_HOST_INITIALIZATION;
#endif
gcc_init_libintl ();
/* Do not invoke xcalloc before this point, since locale needs to be
set first, in case a diagnostic is issued. */
*************** main (int argc, char **argv)
*** 882,919 ****
if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
num_c_args++;
}
obstack_free (&temporary_obstack, temporary_firstobj);
! /* -fno-exceptions -w */
! num_c_args += 2;
c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
if (argc < 2)
fatal ("no arguments");
! #ifdef SIGQUIT
! if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
! signal (SIGQUIT, handler);
! #endif
! if (signal (SIGINT, SIG_IGN) != SIG_IGN)
! signal (SIGINT, handler);
! #ifdef SIGALRM
! if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
! signal (SIGALRM, handler);
! #endif
! #ifdef SIGHUP
! if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
! signal (SIGHUP, handler);
! #endif
! if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
! signal (SIGSEGV, handler);
! #ifdef SIGBUS
! if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
! signal (SIGBUS, handler);
! #endif
/* Extract COMPILER_PATH and PATH into our prefix list. */
prefix_from_env ("COMPILER_PATH", &cpath);
prefix_from_env ("PATH", &path);
--- 966,985 ----
if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
num_c_args++;
}
obstack_free (&temporary_obstack, temporary_firstobj);
! /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
! -fno-exceptions -w */
! num_c_args += 5;
c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
if (argc < 2)
fatal ("no arguments");
! install_handlers ();
/* Extract COMPILER_PATH and PATH into our prefix list. */
prefix_from_env ("COMPILER_PATH", &cpath);
prefix_from_env ("PATH", &path);
*************** do_wait (const char *prog)
*** 1490,1504 ****
/* Execute a program, and wait for the reply. */
void
collect_execute (const char *prog, char **argv, const char *redir)
{
- char *errmsg_fmt;
- char *errmsg_arg;
int redir_handle = -1;
- int stdout_save = -1;
- int stderr_save = -1;
if (vflag || debug)
{
char **p_argv;
const char *str;
--- 1560,1570 ----
*************** collect_execute (const char *prog, char
*** 1512,1564 ****
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
- fflush (stdout);
- fflush (stderr);
-
/* If we cannot find a program we need, complain error. Do this here
since we might not end up needing something that we could not find. */
if (argv[0] == 0)
fatal ("cannot find `%s'", prog);
if (redir)
{
! /* Open response file. */
! redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
!
! /* Duplicate the stdout and stderr file handles
! so they can be restored later. */
! stdout_save = dup (STDOUT_FILENO);
! if (stdout_save == -1)
! fatal_perror ("redirecting stdout: %s", redir);
! stderr_save = dup (STDERR_FILENO);
! if (stderr_save == -1)
! fatal_perror ("redirecting stdout: %s", redir);
!
! /* Redirect stdout & stderr to our response file. */
! dup2 (redir_handle, STDOUT_FILENO);
! dup2 (redir_handle, STDERR_FILENO);
}
! pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
! (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
! if (redir)
! {
! /* Restore stdout and stderr to their previous settings. */
! dup2 (stdout_save, STDOUT_FILENO);
! dup2 (stderr_save, STDERR_FILENO);
!
! /* Close response file. */
! close (redir_handle);
! }
!
! if (pid == -1)
! fatal_perror (errmsg_fmt, errmsg_arg);
}
static void
fork_execute (const char *prog, char **argv)
{
--- 1578,1604 ----
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
/* If we cannot find a program we need, complain error. Do this here
since we might not end up needing something that we could not find. */
if (argv[0] == 0)
fatal ("cannot find `%s'", prog);
if (redir)
{
! redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, S_IWUSR);
! if (redir_handle == -1)
! fatal ("cannot open `%s' for writing", redir);
}
! pid = pexec (argv[0], argv, 1, -1, redir_handle, redir_handle);
! if (pid == -1)
! fatal_perror ("pexec");
}
static void
fork_execute (const char *prog, char **argv)
{
*************** write_aix_file (FILE *stream, struct id
*** 1982,1993 ****
destructor table has the same format, and begins at __DTOR_LIST__. */
static void
scan_prog_file (const char *prog_name, enum pass which_pass)
{
- void (*int_handler) (int);
- void (*quit_handler) (int);
char *real_nm_argv[4];
const char **nm_argv = (const char **) real_nm_argv;
int argc = 0;
int pipe_fd[2];
char *p, buf[1024];
--- 2022,2031 ----
*************** scan_prog_file (const char *prog_name, e
*** 2005,2015 ****
nm_argv[argc++] = NM_FLAGS;
nm_argv[argc++] = prog_name;
nm_argv[argc++] = (char *) 0;
! if (pipe (pipe_fd) < 0)
fatal_perror ("pipe");
inf = fdopen (pipe_fd[0], "r");
if (inf == (FILE *) 0)
fatal_perror ("fdopen");
--- 2043,2053 ----
nm_argv[argc++] = NM_FLAGS;
nm_argv[argc++] = prog_name;
nm_argv[argc++] = (char *) 0;
! if (pmkpipe (pipe_fd) < 0)
fatal_perror ("pipe");
inf = fdopen (pipe_fd[0], "r");
if (inf == (FILE *) 0)
fatal_perror ("fdopen");
*************** scan_prog_file (const char *prog_name, e
*** 2024,2065 ****
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
- fflush (stdout);
- fflush (stderr);
-
/* Spawn child nm on pipe. */
! pid = vfork ();
if (pid == -1)
! fatal_perror (VFORK_STRING);
!
! if (pid == 0) /* child context */
! {
! /* setup stdout */
! if (dup2 (pipe_fd[1], 1) < 0)
! fatal_perror ("dup2 %d 1", pipe_fd[1]);
!
! if (close (pipe_fd[0]) < 0)
! fatal_perror ("close %d", pipe_fd[0]);
!
! if (close (pipe_fd[1]) < 0)
! fatal_perror ("close %d", pipe_fd[1]);
!
! execv (nm_file_name, real_nm_argv);
! fatal_perror ("execv %s", nm_file_name);
! }
!
/* Parent context from here on. */
! int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
! #ifdef SIGQUIT
! quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
! #endif
!
! if (close (pipe_fd[1]) < 0)
! fatal_perror ("close %d", pipe_fd[1]);
if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
/* Read each line of nm output. */
--- 2062,2079 ----
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
/* Spawn child nm on pipe. */
! pid = pexec (nm_file_name, real_nm_argv, 0, -1, pipe_fd[1], -1);
!
if (pid == -1)
! fatal_perror ("pexec");
!
/* Parent context from here on. */
! disable_break ();
if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
/* Read each line of nm output. */
*************** scan_prog_file (const char *prog_name, e
*** 2134,2147 ****
if (fclose (inf) != 0)
fatal_perror ("fclose");
do_wait (nm_file_name);
! signal (SIGINT, int_handler);
! #ifdef SIGQUIT
! signal (SIGQUIT, quit_handler);
! #endif
}
#if SUNOS4_SHARED_LIBRARIES
/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
--- 2148,2158 ----
if (fclose (inf) != 0)
fatal_perror ("fclose");
do_wait (nm_file_name);
! enable_break ();
}
#if SUNOS4_SHARED_LIBRARIES
/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
*************** scan_libraries (const char *prog_name)
*** 2414,2425 ****
static void
scan_libraries (const char *prog_name)
{
static struct head libraries; /* list of shared libraries found */
struct id *list;
- void (*int_handler) (int);
- void (*quit_handler) (int);
char *real_ldd_argv[4];
const char **ldd_argv = (const char **) real_ldd_argv;
int argc = 0;
int pipe_fd[2];
char buf[1024];
--- 2425,2434 ----
*************** scan_libraries (const char *prog_name)
*** 2434,2444 ****
ldd_argv[argc++] = ldd_file_name;
ldd_argv[argc++] = prog_name;
ldd_argv[argc++] = (char *) 0;
! if (pipe (pipe_fd) < 0)
fatal_perror ("pipe");
inf = fdopen (pipe_fd[0], "r");
if (inf == (FILE *) 0)
fatal_perror ("fdopen");
--- 2443,2453 ----
ldd_argv[argc++] = ldd_file_name;
ldd_argv[argc++] = prog_name;
ldd_argv[argc++] = (char *) 0;
! if (pmkpipe (pipe_fd) < 0)
fatal_perror ("pipe");
inf = fdopen (pipe_fd[0], "r");
if (inf == (FILE *) 0)
fatal_perror ("fdopen");
*************** scan_libraries (const char *prog_name)
*** 2453,2494 ****
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
- fflush (stdout);
- fflush (stderr);
-
/* Spawn child ldd on pipe. */
! pid = vfork ();
! if (pid == -1)
! fatal_perror (VFORK_STRING);
!
! if (pid == 0) /* child context */
! {
! /* setup stdout */
! if (dup2 (pipe_fd[1], 1) < 0)
! fatal_perror ("dup2 %d 1", pipe_fd[1]);
!
! if (close (pipe_fd[0]) < 0)
! fatal_perror ("close %d", pipe_fd[0]);
!
! if (close (pipe_fd[1]) < 0)
! fatal_perror ("close %d", pipe_fd[1]);
!
! execv (ldd_file_name, real_ldd_argv);
! fatal_perror ("execv %s", ldd_file_name);
! }
/* Parent context from here on. */
! int_handler = (void (*) (int))) signal (SIGINT, SIG_IGN;
! #ifdef SIGQUIT
! quit_handler = (void (*) (int))) signal (SIGQUIT, SIG_IGN;
! #endif
!
! if (close (pipe_fd[1]) < 0)
! fatal_perror ("close %d", pipe_fd[1]);
if (debug)
notice ("\nldd output with constructors/destructors.\n");
/* Read each line of ldd output. */
--- 2462,2479 ----
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
}
/* Spawn child ldd on pipe. */
! pexecute_pid = pexec (ldd_file_name, real_ldd_argv, 0, -1, infpipe[1], -1);
!
! if (pexecute_pid == -1)
! fatal_perror ("pexec");
/* Parent context from here on. */
! disable_break ();
if (debug)
notice ("\nldd output with constructors/destructors.\n");
/* Read each line of ldd output. */
*************** scan_libraries (const char *prog_name)
*** 2527,2542 ****
if (fclose (inf) != 0)
fatal_perror ("fclose");
do_wait (ldd_file_name);
! signal (SIGINT, int_handler);
! #ifdef SIGQUIT
! signal (SIGQUIT, quit_handler);
! #endif
!
! /* now iterate through the library list adding their symbols to
the list. */
for (list = libraries.first; list; list = list->next)
scan_prog_file (list->name, PASS_LIB);
}
--- 2512,2523 ----
if (fclose (inf) != 0)
fatal_perror ("fclose");
do_wait (ldd_file_name);
! enable_break ();
! /* Now iterate through the library list adding their symbols to
the list. */
for (list = libraries.first; list; list = list->next)
scan_prog_file (list->name, PASS_LIB);
}
Index: gcc/system.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/system.h,v
retrieving revision 1.171
retrieving revision 1.171.4.3
diff -c -5 -p -r1.171 -r1.171.4.3
*** gcc/system.h 16 Oct 2003 18:05:57 -0000 1.171
--- gcc/system.h 3 Mar 2004 16:02:47 -0000 1.171.4.3
*************** extern int errno;
*** 249,280 ****
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
- #ifndef WIFSIGNALED
- #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
- #endif
- #ifndef WTERMSIG
- #define WTERMSIG(S) ((S) & 0x7f)
- #endif
- #ifndef WIFEXITED
- #define WIFEXITED(S) (((S) & 0xff) == 0)
- #endif
- #ifndef WEXITSTATUS
- #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
- #endif
- #ifndef WSTOPSIG
- #define WSTOPSIG WEXITSTATUS
- #endif
- #ifndef WCOREDUMP
- #define WCOREDUMP(S) ((S) & WCOREFLG)
- #endif
- #ifndef WCOREFLG
- #define WCOREFLG 0200
- #endif
-
/* The HAVE_DECL_* macros are three-state, undefined, 0 or 1. If they
are defined to 0 then we must provide the relevant declaration
here. These checks will be in the undefined state while configure
is running so be careful to test "defined (HAVE_DECL_*)". */
--- 250,259 ----