This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch for PR 14316: collect2 doesnt build on windows hosts- refresh


Aaron W. LaFramboise wrote:

> With this patch, I needed to conditionally define quit_handler on
> SIGQUIT to prevent bootstrap from dying in stage 2.  When SIGQUIT is not
> defined, this variable is never used, and so -Werror stops the build.

Attached is the slightly revised patch that does this.

Aaron W. LaFramboise

? gcc/include/pex-read.h
? gcc/libiberty/pexrd-generic.c
? gcc/libiberty/pexrd-unix.c
Index: gcc/gcc/collect2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/collect2.c,v
retrieving revision 1.166
diff -c -3 -p -r1.166 collect2.c
*** gcc/gcc/collect2.c	1 Oct 2004 18:45:26 -0000	1.166
--- gcc/gcc/collect2.c	25 Oct 2004 06:51:25 -0000
*************** Software Foundation, 59 Temple Place - S
*** 35,52 ****
  #  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"
--- 35,43 ----
  #  define SIGCHLD SIGCLD
  #endif
  
! #ifndef HAVE_KILL
! #define kill(p,s) raise(s)
  #endif
  
  #ifndef LIBRARY_PATH_ENV
  #define LIBRARY_PATH_ENV "LIBRARY_PATH"
*************** Software Foundation, 59 Temple Place - S
*** 55,60 ****
--- 46,52 ----
  #define COLLECT
  
  #include "collect2.h"
+ #include "pex-read.h"
  #include "demangle.h"
  #include "obstack.h"
  #include "intl.h"
*************** static char *find_a_file (struct path_pr
*** 251,257 ****
--- 243,251 ----
  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 collect_status (const char *, int status);
  static void do_wait (const char *);
+ static void do_read_wait (const char *, FILE *);
  static void fork_execute (const char *, char **);
  static void maybe_unlink (const char *);
  static void add_to_list (struct head *, const char *);
*************** main (int argc, char **argv)
*** 1491,1504 ****
  }
  
  
! /* Wait for a process to finish, and exit if a nonzero status is found.  */
  
! int
! collect_wait (const char *prog)
  {
-   int status;
- 
-   pwait (pid, &status, 0);
    if (status)
      {
        if (WIFSIGNALED (status))
--- 1485,1495 ----
  }
  
  
! /* Handle error status returned by a finished process.  */
  
! static int
! collect_status (const char *prog, int status)
  {
    if (status)
      {
        if (WIFSIGNALED (status))
*************** collect_wait (const char *prog)
*** 1516,1521 ****
--- 1507,1523 ----
    return 0;
  }
  
+ /* Wait for a process to finish, and exit if a nonzero status is found.  */
+ 
+ int
+ collect_wait (const char *prog)
+ {
+   int status;
+ 
+   pwait (pid, &status, 0);
+   return collect_status (prog, status);
+ }
+ 
  static void
  do_wait (const char *prog)
  {
*************** do_wait (const char *prog)
*** 1527,1532 ****
--- 1529,1547 ----
      }
  }
  
+ static void
+ do_read_wait (const char *prog, FILE *inf)
+ {
+   int status;
+ 
+   pex_read_close (pid, inf, &status, 0);
+   status = collect_status (prog, status);
+   if (status != 0)
+     {
+       error ("%s returned %d exit status", prog, status);
+       collect_exit (status);
+     }
+ }
  
  /* Execute a program, and wait for the reply.  */
  
*************** collect_execute (const char *prog, char 
*** 1567,1573 ****
    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.  */
--- 1582,1588 ----
    if (redir)
      {
        /* Open response file.  */
!       redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, S_IWUSR);
  
        /* Duplicate the stdout and stderr file handles
  	 so they can be restored later.  */
*************** static void
*** 2026,2038 ****
  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];
    FILE *inf;
  
    if (which_pass == PASS_SECOND)
      return;
--- 2041,2056 ----
  scan_prog_file (const char *prog_name, enum pass which_pass)
  {
    void (*int_handler) (int);
+ #ifdef SIGQUIT
    void (*quit_handler) (int);
+ #endif
    char *real_nm_argv[4];
    const char **nm_argv = (const char **) real_nm_argv;
    int argc = 0;
    char *p, buf[1024];
    FILE *inf;
+   char *errmsg_fmt;
+   char *errmsg_arg;
  
    if (which_pass == PASS_SECOND)
      return;
*************** scan_prog_file (const char *prog_name, e
*** 2048,2060 ****
    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");
- 
    /* Trace if needed.  */
    if (vflag)
      {
--- 2066,2071 ----
*************** scan_prog_file (const char *prog_name, e
*** 2070,2105 ****
    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");
  
--- 2081,2096 ----
    fflush (stdout);
    fflush (stderr);
  
!   inf = pex_read (nm_file_name, real_nm_argv, nm_file_name, NULL,
! 		  &errmsg_fmt, &errmsg_arg, 0, &pid);
!   if (inf == (FILE *) 0)
!     fatal_perror (errmsg_fmt, errmsg_arg);
  
    int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
  #ifdef SIGQUIT
    quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
  #endif
  
    if (debug)
      fprintf (stderr, "\nnm output with constructors/destructors.\n");
  
*************** scan_prog_file (const char *prog_name, e
*** 2172,2181 ****
    if (debug)
      fprintf (stderr, "\n");
  
!   if (fclose (inf) != 0)
!     fatal_perror ("fclose");
! 
!   do_wait (nm_file_name);
  
    signal (SIGINT,  int_handler);
  #ifdef SIGQUIT
--- 2163,2169 ----
    if (debug)
      fprintf (stderr, "\n");
  
!   do_read_wait (nm_file_name, inf);
  
    signal (SIGINT,  int_handler);
  #ifdef SIGQUIT
*************** scan_libraries (const char *prog_name)
*** 2195,2207 ****
    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];
    FILE *inf;
  
    /* If we do not have an `ldd', complain.  */
    if (ldd_file_name == 0)
--- 2183,2198 ----
    static struct head libraries;		/* list of shared libraries found */
    struct id *list;
    void (*int_handler) (int);
+ #ifdef SIGQUIT
    void (*quit_handler) (int);
+ #endif
    char *real_ldd_argv[4];
    const char **ldd_argv = (const char **) real_ldd_argv;
    int argc = 0;
    char buf[1024];
    FILE *inf;
+   char *errmsg_fmt;
+   char *errmsg_arg;
  
    /* If we do not have an `ldd', complain.  */
    if (ldd_file_name == 0)
*************** scan_libraries (const char *prog_name)
*** 2236,2261 ****
    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);
--- 2227,2236 ----
    fflush (stdout);
    fflush (stderr);
  
!   inf = pex_read (ldd_file_name, real_ldd_argv, ldd_file_name, NULL,
! 		  &errmsg_fmt, &errmsg_arg, 0, &pid);
!   if (inf == (FILE *) 0)
!     fatal_perror (errmsg_fmt, errmsg_arg);
  
    /* Parent context from here on.  */
    int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
*************** scan_libraries (const char *prog_name)
*** 2263,2271 ****
    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");
  
--- 2238,2243 ----
*************** scan_libraries (const char *prog_name)
*** 2302,2311 ****
    if (debug)
      fprintf (stderr, "\n");
  
!   if (fclose (inf) != 0)
!     fatal_perror ("fclose");
! 
!   do_wait (ldd_file_name);
  
    signal (SIGINT,  int_handler);
  #ifdef SIGQUIT
--- 2274,2280 ----
    if (debug)
      fprintf (stderr, "\n");
  
!   do_read_wait (ldd_file_name, inf);
  
    signal (SIGINT,  int_handler);
  #ifdef SIGQUIT
Index: gcc/gcc/config.host
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.host,v
retrieving revision 2.11
diff -c -3 -p -r2.11 config.host
*** gcc/gcc/config.host	31 Aug 2004 00:28:56 -0000	2.11
--- gcc/gcc/config.host	14 Oct 2004 10:10:30 -0000
*************** case ${host} in
*** 147,153 ****
      host_xm_file=i386/xm-mingw32.h
      host_xmake_file=i386/x-mingw32
      host_exeext=.exe
-     host_can_use_collect2=no
      out_host_hook_obj=host-mingw32.o
      ;;
    i[34567]86-*-uwin*)
--- 147,152 ----
Index: gcc/gcc/tlink.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tlink.c,v
retrieving revision 1.57
diff -c -3 -p -r1.57 tlink.c
*** gcc/gcc/tlink.c	25 Aug 2004 20:51:19 -0000	1.57
--- gcc/gcc/tlink.c	14 Oct 2004 10:11:01 -0000
*************** recompile_files (void)
*** 468,474 ****
  	}
        fclose (stream);
        fclose (output);
!       rename (outname, f->key);
  
        if (!f->args)
  	{
--- 468,480 ----
  	}
        fclose (stream);
        fclose (output);
!       /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if
! 	 the new file name already exists.  Therefore, we explicitly
! 	 remove the old file first.  */
!       if (remove (f->key) == -1)
! 	fatal_perror ("removing .rpo file");
!       if (rename (outname, f->key) == -1)
! 	fatal_perror ("renaming .rpo file");
  
        if (!f->args)
  	{
Index: gcc/libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.101
diff -c -3 -p -r1.101 Makefile.in
*** gcc/libiberty/Makefile.in	25 May 2004 19:37:02 -0000	1.101
--- gcc/libiberty/Makefile.in	14 Oct 2004 10:14:45 -0000
*************** CFILES = alloca.c argv.c asprintf.c atex
*** 144,149 ****
--- 144,150 ----
  	partition.c							\
  	 pex-djgpp.c pex-mpw.c pex-msdos.c pex-os2.c			\
  	 pex-unix.c pex-win32.c						\
+ 	 pexrd-unix.c pexrd-generic.c					\
           physmem.c putenv.c						\
  	random.c regex.c rename.c rindex.c				\
  	safe-ctype.c setenv.c sigsetmask.c snprintf.c sort.c spaces.c	\
*************** $(CONFIGURED_OFILES): stamp-picdir
*** 790,795 ****
--- 791,810 ----
  	else true; fi
  	$(COMPILE.c) $(srcdir)/pex-win32.c $(OUTPUT_OPTION)
  
+ ./pexrd-generic.o: $(srcdir)/pexrd-generic.c config.h $(INCDIR)/ansidecl.h \
+ 	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h  $(INCDIR)/pex-read.h
+ 	if [ x"$(PICFLAG)" != x ]; then \
+ 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pexrd-generic.c -o pic/$@; \
+ 	else true; fi
+ 	$(COMPILE.c) $(srcdir)/pexrd-generic.c $(OUTPUT_OPTION)
+ 
+ ./pexrd-unix.o: $(srcdir)/pexrd-unix.c config.h $(INCDIR)/ansidecl.h \
+ 	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h  $(INCDIR)/pex-read.h
+ 	if [ x"$(PICFLAG)" != x ]; then \
+ 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pexrd-unix.c -o pic/$@; \
+ 	else true; fi
+ 	$(COMPILE.c) $(srcdir)/pexrd-unix.c $(OUTPUT_OPTION)
+ 
  ./physmem.o: $(srcdir)/physmem.c config.h $(INCDIR)/ansidecl.h \
  	$(INCDIR)/libiberty.h
  	if [ x"$(PICFLAG)" != x ]; then \
Index: gcc/libiberty/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/configure.ac,v
retrieving revision 1.7
diff -c -3 -p -r1.7 configure.ac
*** gcc/libiberty/configure.ac	2 Sep 2004 07:05:24 -0000	1.7
--- gcc/libiberty/configure.ac	14 Oct 2004 10:14:58 -0000
*************** fi
*** 512,522 ****
  
  # Figure out which version of pexecute to use.
  case "${host}" in
!      *-*-mingw* | *-*-winnt*)	pexecute=./pex-win32.o  ;;
!      *-*-msdosdjgpp*)		pexecute=./pex-djgpp.o  ;;
!      *-*-msdos*)		pexecute=./pex-msdos.o  ;;
!      *-*-os2-emx*)		pexecute=./pex-os2.o    ;;
!      *)				pexecute=./pex-unix.o   ;;
  esac
  AC_SUBST(pexecute)
  
--- 512,522 ----
  
  # Figure out which version of pexecute to use.
  case "${host}" in
!      *-*-mingw* | *-*-winnt*)	pexecute="./pex-win32.o ./pexrd-generic.o"  ;;
!      *-*-msdosdjgpp*)		pexecute="./pex-djgpp.o ./pexrd-generic.o"  ;;
!      *-*-msdos*)		pexecute="./pex-msdos.o ./pexrd-generic.o"  ;;
!      *-*-os2-emx*)		pexecute="./pex-os2.o   ./pexrd-generic.o"  ;;
!      *)				pexecute="./pex-unix.o  ./pexrd-unix.o"     ;;
  esac
  AC_SUBST(pexecute)
  
Index: gcc/libiberty/pexecute.txh
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pexecute.txh,v
retrieving revision 1.1
diff -c -3 -p -r1.1 pexecute.txh
*** gcc/libiberty/pexecute.txh	24 Jan 2003 20:02:11 -0000	1.1
--- gcc/libiberty/pexecute.txh	14 Oct 2004 10:15:00 -0000
***************
*** 1,4 ****
! @deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags)
  
  Executes a program.
  
--- 1,4 ----
! @deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int @var{flags})
  
  Executes a program.
  
*************** pfinish: finish generation of script
*** 61,63 ****
--- 61,99 ----
  
  pfinish is necessary for systems like MPW where a script is generated
  that runs the requested programs.
+ 
+ @end undocumented
+ 
+ @deftypefn Extension FILE* pex_read (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int @var{flags}, int *@var{pidptr})
+ 
+ Executes a program and returns a stdio file for the program's standard
+ output.  This is a safe version of the usual Unix function
+ @code{popen}.
+ 
+ The first seven parameters are the same as for @code{pexecute}.  The
+ last parameter returns a process identifier to be passed to
+ @code{pex_read_close}.
+ 
+ The only flags used for the @var{flags} parameter is
+ @code{PEXECUTE_SEARCH}.
+ 
+ Upon failure, @var{errmsg_fmt} and @var{errmsg_arg} are set to the
+ text of the error message with an optional argument (if not needed,
+ @var{errmsg_arg} is set to @code{NULL}), and @code{NULL} is returned.
+ @code{errno} is available to the caller to use.
+ 
+ @end deftypefn
+ 
+ @deftypefn Extension int pex_read_close (int @var{pid}, FILE *@var{file}, int *@var{status}, int @var{flags})
+ 
+ Close a file opened by @code{pex_read}, and wait for the subprocess to
+ complete.  The @var{pid} and @var{file} arguments should have been
+ obtained from a call to @code{pex_read}.
+ 
+ The result is the pid of the child reaped, or -1 for failure
+ (@code{errno} says why).
+ 
+ On a successful return, *@var{status} is set to the exit status of the
+ subprocess.
+ 
+ @end deftypefn
*** /dev/null	Thu Oct 14 23:40:20 2004
--- gcc/include/pex-read.h	Sat Jun 12 12:37:02 2004
***************
*** 0 ****
--- 1,41 ----
+ /* Declarations of the pex-read functions for libiberty.
+    Copyright 2004 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #ifndef PEX_READ_H
+ #define PEX_READ_H
+ 
+ #include <stdio.h>
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+  
+ /* Execute a program and read its standard output.  */
+ 
+ extern FILE *pex_read (const char *, char * const *, const char *,
+ 		       const char *, char **, char **, int, int *);
+ 
+ /* Wait for pex_read to finish.  */
+ 
+ extern int pex_read_close (int, FILE *, int *, int);
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif /* PEX_READ_H */
*** /dev/null	Thu Oct 14 23:41:20 2004
--- gcc/libiberty/pexrd-generic.c	Sat Jun 12 14:19:29 2004
***************
*** 0 ****
--- 1,68 ----
+ /* Execute a program and read stdout.  Generic version.
+    Copyright (C) 2004 Free Software Foundation, Inc.
+ 
+ This file is part of the libiberty library.
+ Libiberty is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+ 
+ Libiberty is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+ 
+ You should have received a copy of the GNU Library General Public
+ License along with libiberty; see the file COPYING.LIB.  If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+ 
+ #include "pex-common.h"
+ #include "pex-read.h"
+ 
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
+ 
+ FILE *
+ pex_read (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags,
+ 	  pidptr)
+      const char *program;
+      char * const *argv;
+      const char *this_pname ATTRIBUTE_UNUSED;
+      const char *temp_base ATTRIBUTE_UNUSED;
+      char **errmsg_fmt;
+      char **errmsg_arg;
+      int flags ATTRIBUTE_UNUSED;
+      int *pidptr ATTRIBUTE_UNUSED;
+ {
+   char *cmd;
+   int i;
+   FILE *ret;
+ 
+   cmd = xstrdup (program);
+   for (i = 0; argv[i] != NULL; ++i)
+     cmd = reconcat (cmd, cmd, " ", argv[i], NULL);
+ 
+   ret = popen (cmd, "r");
+   if (ret == NULL)
+     {
+       *errmsg_fmt = "popen";
+       *errmsg_arg = NULL;
+     }
+ 
+   free (cmd);
+ 
+   return ret;
+ }
+ 
+ int
+ pex_read_close (pid, file, status, flags)
+      int pid ATTRIBUTE_UNUSED;
+      FILE *file;
+      int *status;
+      int flags ATTRIBUTE_UNUSED;
+ {
+   *status = pclose (file);
+   return 0;
+ }
*** /dev/null	Thu Oct 14 23:41:29 2004
--- gcc/libiberty/pexrd-unix.c	Sat Jun 12 14:24:28 2004
***************
*** 0 ****
--- 1,165 ----
+ /* Execute a program and read stdout.  Generic Unix version.
+    Copyright (C) 2004 Free Software Foundation, Inc.
+ 
+ This file is part of the libiberty library.
+ Libiberty is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+ 
+ Libiberty is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+ 
+ You should have received a copy of the GNU Library General Public
+ License along with libiberty; see the file COPYING.LIB.  If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+ 
+ #include "pex-read.h"
+ #include "pex-common.h"
+ 
+ #include <stdio.h>
+ #include <errno.h>
+ #ifdef NEED_DECLARATION_ERRNO
+ extern int errno;
+ #endif
+ #ifdef HAVE_STRING_H
+ #include <string.h>
+ #endif
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
+ #if HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ #ifdef HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+ #endif
+ 
+ #ifndef HAVE_WAITPID
+ #define waitpid(pid, status, flags) wait(status)
+ #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 */
+ 
+ /* A safe version of popen.  See pex-unix.c for notes on vfork.  */
+ 
+ FILE *
+ pex_read (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg,
+ 	  flagsarg, pidptr)
+      const char *program;
+      char * const *argv;
+      const char *this_pname;
+      const char *temp_base ATTRIBUTE_UNUSED;
+      char **errmsg_fmt;
+      char **errmsg_arg;
+      int flagsarg;
+      int *pidptr;
+ {
+   int flags;
+   int pid;
+   int pdes[2];
+   int in;
+   int out;
+   FILE *ret;
+   /* We declare these to be volatile to avoid warnings from gcc about
+      them being clobbered by vfork.  */
+   volatile int retries;
+   volatile int sleep_interval;
+ 
+   flags = flagsarg;
+ 
+   if (pipe (pdes) < 0)
+     {
+       *errmsg_fmt = "pipe";
+       *errmsg_arg = NULL;
+       return NULL;
+     }
+ 
+   in = pdes[READ_PORT];
+   out = pdes[WRITE_PORT];
+ 
+   sleep_interval = 1;
+   pid = -1;
+   for (retries = 0; retries < 4; retries++)
+     {
+       pid = vfork ();
+       if (pid >= 0)
+ 	break;
+       sleep (sleep_interval);
+       sleep_interval *= 2;
+     }
+ 
+   switch (pid)
+     {
+     case -1:
+       *errmsg_fmt = "fork";
+       *errmsg_arg = NULL;
+       return NULL;
+ 
+     case 0:
+       if (out != STDOUT_FILE_NO)
+ 	{
+ 	  close (STDOUT_FILE_NO);
+ 	  dup (out);
+ 	  close (out);
+ 	}
+       close (in);
+ 
+       if (flags & PEXECUTE_SEARCH)
+ 	execvp (program, argv);
+       else
+ 	execv (program, argv);
+ 
+       /* We don't want to call fprintf after vfork.  */
+ #define writeerr(s) write (STDERR_FILE_NO, s, strlen (s))
+       writeerr (this_pname);
+       writeerr (": ");
+       writeerr ("installation problem, cannot exec '");
+       writeerr (program);
+       writeerr ("': ");
+       writeerr (xstrerror (errno));
+       writeerr ("\n");
+       _exit (-1);
+       /* NOTREACHED */
+       return NULL;
+ 
+     default:
+       close (out);
+       ret = fdopen (in, "r");
+       if (ret == NULL)
+ 	{
+ 	  *errmsg_fmt = "fdopen";
+ 	  *errmsg_arg = NULL;
+ 	  return NULL;
+ 	}
+       *pidptr = pid;
+       return ret;
+     }
+   /* NOTREACHED */
+ }
+ 
+ int
+ pex_read_close (pid, file, status, flags)
+      int pid;
+      FILE *file;
+      int *status;
+      int flags ATTRIBUTE_UNUSED;
+ {
+   /* ??? Canonicalize STATUS value?  */
+   fclose (file);
+   return waitpid (pid, status, 0);
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]