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]

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


This is a ping of a patch I sent in June.

As Aaron has noticed, patch the June was missing new files. It took
awhile for anyone to notice. They are included here.  Also, with the
replacement of system() call with tlink_execute() in tlink.c, the need for
QUOTE_CHAR fudge that was in the earlier patch is gone.

This has been bootstrapped on i686-pc-mingw and regtested with no new
regression,  -frepro testcases now succeed.

The earlier version of the patch was in mingw.orgs 3.4.0 and 3.4.1
distro's.  A backport of this patch (together with the tlink_execute patch)
is in the mingw 3.4.2 distro.  No bug reports have been sent to mingw list

I don't know how the ChangeLog should go. Here are where the bits and
pieces come from:

ChangeLog

        Ian Lance Taylor  <ian@wasabisystems.com>

	PR 14316
        * collect2.c (collect_status): New static function, broken out of
        collect_wait.
        (collect_wait): Call collect_status.
        (do_read_wait): New static function.
        (scan_prog_file): Call pex_read instead of pipe and vfork.
        (scan_libraries): Likewise.

        Mark Mitchell  <mmitchel@gcc.gnu.org>

        * collect2.c  (collect_execute): Pass third argument to open.
        * tlink.c (recompile_files): Do not assume that "rename" can
        overwrite an existing file.  Use "&&" as the command separator
        rather than ";".

        Danny Smith  <dannysmith@users.sourceforge,net>

        * collect2.c: Include pex-read.h.
        [!HAVE_KILL]: Just define kill(p,signo) as raise (signo) if no kill..
        * config.host (i[34567]86-*-mingw*): Host can use collect2.

libiberty/Changelog

        Ian Lance Taylor  <ian@wasabisystems.com>

	PR 14316
        * pexrd-unix.c: New file.
        * pexrd-generic.c: New file.
        * configure.ac: Add either ./pexrd-unix.o or ./pexrd-generic.o to
        pexecute.
        * Makefile.in: Run maint-deps.
        (CFILES): Add pexrd-unix.c and pexrd-generic.c.
        (CONFIGURED_OFILES): Add ./pexrd-unix.o and ./pexrd-generic.o.
        * pexecute.txh: Document pex_read and pex_read_close.

include/ChangeLog

        Danny Smith <dannysmith@users.sourceforge,net>

	PR 14316
        * include/pex-read.h. New file. Declare pex_read, pex_read_close.


Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com
? 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	14 Oct 2004 10:42:10 -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.  */
*************** scan_prog_file (const char *prog_name, e
*** 2030,2038 ****
    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;
--- 2045,2054 ----
    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)
      {
--- 2064,2069 ----
*************** 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");
  
--- 2079,2094 ----
    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
--- 2161,2167 ----
    if (debug)
      fprintf (stderr, "\n");
  
!   do_read_wait (nm_file_name, inf);
  
    signal (SIGINT,  int_handler);
  #ifdef SIGQUIT
*************** scan_libraries (const char *prog_name)
*** 2199,2207 ****
    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)
--- 2185,2194 ----
    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);
--- 2223,2232 ----
    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");
  
--- 2234,2239 ----
*************** 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
--- 2270,2276 ----
    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]