Commit 1fff69c9 by Ian Lance Taylor Committed by Ian Lance Taylor

re PR bootstrap/14316 (collect2 doesnt build on windows hosts)

	PR bootstrap/14316
	* collect2.c: Never include <vfork.h>.
	(VFORK_STRING, vfork): Don't define.
	(pid): Remove global variable.
	(handler): Call raise instead of kill (getpid(), ...).
	(collect_wait): Add pex parameter.  Change all callers.  Use
	pex_get_status rather than pwait.
	(do_wait): Add pex parameter.  Change all callers.
	(collect_execute): Return struct pex_obj * rather than void.  Use
	pex routines rather than pexecute.
	(fork_execute): Get pex_obj from collect_execute, and pass it to
	do_wait.
	(scan_prog_file): Use pex routines rather than pipe/vfork/exec.
	Only declare quit_handler if SIGQUIT is defined.
	(scan_libraries): Likewise.
	* collect2.h (collect_execute): Update declaration.
	(collect_wait): Update declaration.
	* tlink.c (tlink_execute): Get pex_obj from collect_execute, and
	pass it to collect_wait.

From-SVN: r97199
parent d1edc393
2005-03-29 Ian Lance Taylor <ian@airs.com>
PR bootstrap/14316
* collect2.c: Never include <vfork.h>.
(VFORK_STRING, vfork): Don't define.
(pid): Remove global variable.
(handler): Call raise instead of kill (getpid(), ...).
(collect_wait): Add pex parameter. Change all callers. Use
pex_get_status rather than pwait.
(do_wait): Add pex parameter. Change all callers.
(collect_execute): Return struct pex_obj * rather than void. Use
pex routines rather than pexecute.
(fork_execute): Get pex_obj from collect_execute, and pass it to
do_wait.
(scan_prog_file): Use pex routines rather than pipe/vfork/exec.
Only declare quit_handler if SIGQUIT is defined.
(scan_libraries): Likewise.
* collect2.h (collect_execute): Update declaration.
(collect_wait): Update declaration.
* tlink.c (tlink_execute): Get pex_obj from collect_execute, and
pass it to collect_wait.
2005-03-29 Joseph S. Myers <joseph@codesourcery.com> 2005-03-29 Joseph S. Myers <joseph@codesourcery.com>
PR c/20672 PR c/20672
......
...@@ -35,19 +35,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -35,19 +35,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# define SIGCHLD SIGCLD # define SIGCHLD SIGCLD
#endif #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 #ifndef LIBRARY_PATH_ENV
#define LIBRARY_PATH_ENV "LIBRARY_PATH" #define LIBRARY_PATH_ENV "LIBRARY_PATH"
#endif #endif
...@@ -217,9 +204,6 @@ static struct head frame_tables; /* list of frame unwind info tables */ ...@@ -217,9 +204,6 @@ static struct head frame_tables; /* list of frame unwind info tables */
struct obstack temporary_obstack; struct obstack temporary_obstack;
char * temporary_firstobj; char * temporary_firstobj;
/* Holds the return value of pexecute and fork. */
int pid;
/* Structure to hold all the directories in which to search for files to /* Structure to hold all the directories in which to search for files to
execute. */ execute. */
...@@ -251,7 +235,7 @@ static char *find_a_file (struct path_prefix *, const char *); ...@@ -251,7 +235,7 @@ static char *find_a_file (struct path_prefix *, const char *);
static void add_prefix (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_env (const char *, struct path_prefix *);
static void prefix_from_string (const char *, struct path_prefix *); static void prefix_from_string (const char *, struct path_prefix *);
static void do_wait (const char *); static void do_wait (const char *, struct pex_obj *);
static void fork_execute (const char *, char **); static void fork_execute (const char *, char **);
static void maybe_unlink (const char *); static void maybe_unlink (const char *);
static void add_to_list (struct head *, const char *); static void add_to_list (struct head *, const char *);
...@@ -420,7 +404,7 @@ handler (int signo) ...@@ -420,7 +404,7 @@ handler (int signo)
#endif #endif
signal (signo, SIG_DFL); signal (signo, SIG_DFL);
kill (getpid (), signo); raise (signo);
} }
...@@ -1501,11 +1485,14 @@ main (int argc, char **argv) ...@@ -1501,11 +1485,14 @@ main (int argc, char **argv)
/* Wait for a process to finish, and exit if a nonzero status is found. */ /* Wait for a process to finish, and exit if a nonzero status is found. */
int int
collect_wait (const char *prog) collect_wait (const char *prog, struct pex_obj *pex)
{ {
int status; int status;
pwait (pid, &status, 0); if (!pex_get_status (pex, 1, &status))
fatal_perror ("can't get program status");
pex_free (pex);
if (status) if (status)
{ {
if (WIFSIGNALED (status)) if (WIFSIGNALED (status))
...@@ -1524,9 +1511,9 @@ collect_wait (const char *prog) ...@@ -1524,9 +1511,9 @@ collect_wait (const char *prog)
} }
static void static void
do_wait (const char *prog) do_wait (const char *prog, struct pex_obj *pex)
{ {
int ret = collect_wait (prog); int ret = collect_wait (prog, pex);
if (ret != 0) if (ret != 0)
{ {
error ("%s returned %d exit status", prog, ret); error ("%s returned %d exit status", prog, ret);
...@@ -1537,14 +1524,12 @@ do_wait (const char *prog) ...@@ -1537,14 +1524,12 @@ do_wait (const char *prog)
/* Execute a program, and wait for the reply. */ /* Execute a program, and wait for the reply. */
void struct pex_obj *
collect_execute (const char *prog, char **argv, const char *redir) collect_execute (const char *prog, char **argv, const char *redir)
{ {
char *errmsg_fmt; struct pex_obj *pex;
char *errmsg_arg; const char *errmsg;
int redir_handle = -1; int err;
int stdout_save = -1;
int stderr_save = -1;
if (vflag || debug) if (vflag || debug)
{ {
...@@ -1571,47 +1556,35 @@ collect_execute (const char *prog, char **argv, const char *redir) ...@@ -1571,47 +1556,35 @@ collect_execute (const char *prog, char **argv, const char *redir)
if (argv[0] == 0) if (argv[0] == 0)
fatal ("cannot find '%s'", prog); fatal ("cannot find '%s'", prog);
if (redir) pex = pex_init (0, "collect2", NULL);
{ if (pex == NULL)
/* Open response file. */ fatal_perror ("pex_init failed");
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) errmsg = pex_run (pex,
(PEX_LAST | PEX_SEARCH
| (redir ? PEX_STDERR_TO_STDOUT : 0)),
argv[0], argv, redir, NULL, &err);
if (errmsg != NULL)
{ {
/* Restore stdout and stderr to their previous settings. */ if (err != 0)
dup2 (stdout_save, STDOUT_FILENO); {
dup2 (stderr_save, STDERR_FILENO); errno = err;
fatal_perror (errmsg);
/* Close response file. */ }
close (redir_handle); else
fatal (errmsg);
} }
if (pid == -1) return pex;
fatal_perror (errmsg_fmt, errmsg_arg);
} }
static void static void
fork_execute (const char *prog, char **argv) fork_execute (const char *prog, char **argv)
{ {
collect_execute (prog, argv, NULL); struct pex_obj *pex;
do_wait (prog);
pex = collect_execute (prog, argv, NULL);
do_wait (prog, pex);
} }
/* Unlink a file unless we are debugging. */ /* Unlink a file unless we are debugging. */
...@@ -2033,11 +2006,15 @@ static void ...@@ -2033,11 +2006,15 @@ static void
scan_prog_file (const char *prog_name, enum pass which_pass) scan_prog_file (const char *prog_name, enum pass which_pass)
{ {
void (*int_handler) (int); void (*int_handler) (int);
#ifdef SIGQUIT
void (*quit_handler) (int); void (*quit_handler) (int);
#endif
char *real_nm_argv[4]; char *real_nm_argv[4];
const char **nm_argv = (const char **) real_nm_argv; const char **nm_argv = (const char **) real_nm_argv;
int argc = 0; int argc = 0;
int pipe_fd[2]; struct pex_obj *pex;
const char *errmsg;
int err;
char *p, buf[1024]; char *p, buf[1024];
FILE *inf; FILE *inf;
...@@ -2055,13 +2032,6 @@ scan_prog_file (const char *prog_name, enum pass which_pass) ...@@ -2055,13 +2032,6 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
nm_argv[argc++] = prog_name; nm_argv[argc++] = prog_name;
nm_argv[argc++] = (char *) 0; 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");
/* Trace if needed. */ /* Trace if needed. */
if (vflag) if (vflag)
{ {
...@@ -2077,35 +2047,30 @@ scan_prog_file (const char *prog_name, enum pass which_pass) ...@@ -2077,35 +2047,30 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
fflush (stdout); fflush (stdout);
fflush (stderr); fflush (stderr);
/* Spawn child nm on pipe. */ pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
pid = vfork (); if (pex == NULL)
if (pid == -1) fatal_perror ("pex_init failed");
fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */ errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err);
if (errmsg != NULL)
{ {
/* setup stdout */ if (err != 0)
if (dup2 (pipe_fd[1], 1) < 0) {
fatal_perror ("dup2 %d 1", pipe_fd[1]); errno = err;
fatal_perror (errmsg);
if (close (pipe_fd[0]) < 0) }
fatal_perror ("close %d", pipe_fd[0]); else
fatal (errmsg);
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); int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT #ifdef SIGQUIT
quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif #endif
if (close (pipe_fd[1]) < 0) inf = pex_read_output (pex, 0);
fatal_perror ("close %d", pipe_fd[1]); if (inf == NULL)
fatal_perror ("can't open nm output");
if (debug) if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n"); fprintf (stderr, "\nnm output with constructors/destructors.\n");
...@@ -2179,10 +2144,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass) ...@@ -2179,10 +2144,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
if (debug) if (debug)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
if (fclose (inf) != 0) do_wait (nm_file_name, pex);
fatal_perror ("fclose");
do_wait (nm_file_name);
signal (SIGINT, int_handler); signal (SIGINT, int_handler);
#ifdef SIGQUIT #ifdef SIGQUIT
...@@ -2202,11 +2164,15 @@ scan_libraries (const char *prog_name) ...@@ -2202,11 +2164,15 @@ scan_libraries (const char *prog_name)
static struct head libraries; /* list of shared libraries found */ static struct head libraries; /* list of shared libraries found */
struct id *list; struct id *list;
void (*int_handler) (int); void (*int_handler) (int);
#ifdef SIGQUIT
void (*quit_handler) (int); void (*quit_handler) (int);
#endif
char *real_ldd_argv[4]; char *real_ldd_argv[4];
const char **ldd_argv = (const char **) real_ldd_argv; const char **ldd_argv = (const char **) real_ldd_argv;
int argc = 0; int argc = 0;
int pipe_fd[2]; struct pex_obj *pex;
const char *errmsg;
int err;
char buf[1024]; char buf[1024];
FILE *inf; FILE *inf;
...@@ -2221,13 +2187,6 @@ scan_libraries (const char *prog_name) ...@@ -2221,13 +2187,6 @@ scan_libraries (const char *prog_name)
ldd_argv[argc++] = prog_name; ldd_argv[argc++] = prog_name;
ldd_argv[argc++] = (char *) 0; 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");
/* Trace if needed. */ /* Trace if needed. */
if (vflag) if (vflag)
{ {
...@@ -2243,35 +2202,30 @@ scan_libraries (const char *prog_name) ...@@ -2243,35 +2202,30 @@ scan_libraries (const char *prog_name)
fflush (stdout); fflush (stdout);
fflush (stderr); fflush (stderr);
/* Spawn child ldd on pipe. */ pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
pid = vfork (); if (pex == NULL)
if (pid == -1) fatal_perror ("pex_init failed");
fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */ errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
if (errmsg != NULL)
{ {
/* setup stdout */ if (err != 0)
if (dup2 (pipe_fd[1], 1) < 0) {
fatal_perror ("dup2 %d 1", pipe_fd[1]); errno = err;
fatal_perror (errmsg);
if (close (pipe_fd[0]) < 0) }
fatal_perror ("close %d", pipe_fd[0]); else
fatal (errmsg);
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); int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT #ifdef SIGQUIT
quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif #endif
if (close (pipe_fd[1]) < 0) inf = pex_read_output (pex, 0);
fatal_perror ("close %d", pipe_fd[1]); if (inf == NULL)
fatal_perror ("can't open ldd output");
if (debug) if (debug)
notice ("\nldd output with constructors/destructors.\n"); notice ("\nldd output with constructors/destructors.\n");
...@@ -2309,10 +2263,7 @@ scan_libraries (const char *prog_name) ...@@ -2309,10 +2263,7 @@ scan_libraries (const char *prog_name)
if (debug) if (debug)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
if (fclose (inf) != 0) do_wait (ldd_file_name, pex);
fatal_perror ("fclose");
do_wait (ldd_file_name);
signal (SIGINT, int_handler); signal (SIGINT, int_handler);
#ifdef SIGQUIT #ifdef SIGQUIT
......
/* Header file for collect/tlink routines. /* Header file for collect/tlink routines.
Copyright (C) 1998, 2003, 2004 Free Software Foundation, Inc. Copyright (C) 1998, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -23,11 +23,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -23,11 +23,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
extern void do_tlink (char **, char **); extern void do_tlink (char **, char **);
extern void collect_execute (const char *, char **, const char *); extern struct pex_obj *collect_execute (const char *, char **, const char *);
extern void collect_exit (int) ATTRIBUTE_NORETURN; extern void collect_exit (int) ATTRIBUTE_NORETURN;
extern int collect_wait (const char *); extern int collect_wait (const char *, struct pex_obj *);
extern void dump_file (const char *); extern void dump_file (const char *);
......
/* Scan linker error messages for missing template instantiations and provide /* Scan linker error messages for missing template instantiations and provide
them. them.
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004 Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005
Free Software Foundation, Inc. Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com). Contributed by Jason Merrill (jason@cygnus.com).
...@@ -281,8 +281,10 @@ tlink_init (void) ...@@ -281,8 +281,10 @@ tlink_init (void)
static int static int
tlink_execute (const char *prog, char **argv, const char *redir) tlink_execute (const char *prog, char **argv, const char *redir)
{ {
collect_execute (prog, argv, redir); struct pex_obj *pex;
return collect_wait (prog);
pex = collect_execute (prog, argv, redir);
return collect_wait (prog, pex);
} }
static char * static char *
......
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