As noted in PR 14316, collect2 doesn't build on Windows due to the use
of vfork.  There have been at least two patches to address this, one
of them from me, one from Zack.

My patch is here:
    http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01445.html
Zack had some comments:
    http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00227.html
    http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00637.html
    http://gcc.gnu.org/ml/gcc-patches/2004-04/msg01044.html
And at that point I kind of ran out of steam.

Anyhow, I've returned to the issue, and I've tried to put together an
interface based on Zack's suggestion which can handle everything we
might want to handle.  I'm not too crazy about it--there are several
different requirements, and so the interface has again gotten kind of
complicated.  It implements what collect2 needs, and I think can also
do most of what gcc.c needs to implement -time, -pipe, and
--save-temps.

At the moment I've implemented a Unix version.  Versions for other
operating systems should not be difficult.

I'd like to hear comments on this interface.  Thanks.

Ian

/* Flags for pex_init.  These are bits to be or'ed together.  */

/* Record subprocess times if possible.  */
#define PEX_RECORD_TIMES   (1)

/* Use files for communication between processes.  Each file will hold
   one process's standard output, and will be used for standard input
   for the next process (if any).  If this flag is set, the TEMPBASE
   argument to pex_init must not be NULL.  The SUFFIX argument to
   pex_run will be appended to TEMPBASE to form the file name.  If the
   SUFFIX argument is NULL, no file will be saved (i.e.,
   PEX_SAVE_TEMPS may be overridden on a program by program basis).
   If PEX_SAVE_TEMPS is not set, communication will use pipes when
   possible, and will otherwise use temporary files which will be
   removed when they are no longer needed.  */
#define PEX_SAVE_TEMPS (2)

/* Prepare to execute one or more programs, with standard output of
   each program fed to standard input of the next.  FLAGS are above,
   PNAME is the name of the program for error messages, TEMPBASE is a
   base name to use for temporary/intermediate files if needed.  PNAME
   and TEMPBASE must be valid at least until the call to pex_free.  If
   PEX_SAVE_TEMPS is not set, TEMPBASE may be NULL to use a random
   file name if one is needed.  Returns NULL on error.  */

extern struct pex_obj *pex_init PARAMS ((int flags, const char *pname,
                                         const char *tempbase));

/* Flags for pex_run.  These are bits to be or'ed together.  */

/* Last program in pipeline.  Standard output of program is standard
   output of caller.  Do not use this if you want to call
   pex_read_output.  */
#define PEX_LAST              (1)

/* Search for program in executable search path.  */
#define PEX_SEARCH            (2)

/* Send program's standard error to standard output.  */
#define PEX_STDERR_TO_STDOUT  (4)

/* Execute one program.  Returns NULL on success.  On error returns an
   error string (typically just the name of a system call) and sets
   *ERR to an errno value or to 0 if there is no relevant errno.  OBJ
   is returned by pex_init, FLAGS are above, EXECUTABLE is the program
   to execute, ARGV is the arguments to pass, SUFFIX is a suffix to
   use for a temporary file if needed.  SUFFIX may be NULL to use a
   random file name if one is needed, and to override the setting of
   PEX_SAVE_TEMPS.  */

extern const char *pex_run PARAMS ((struct pex_obj *obj, int flags,
                                    const char *executable,
                                    char * const *argv,
                                    const char *suffix,
                                    int *err));

/* Read the standard output of the last program to be executed.
   pex_run can not be called after this.  Returns NULL on error.
   Don't fclose the return value; it will be closed by pex_free.  */

extern FILE *pex_read_output PARAMS ((struct pex_obj *));

/* Return exit status of all programs.  The status codes in the vector
   are ordered by the calls to pex_run.  Returns 0 on error, 1 on
   success.  */

extern int pex_get_status PARAMS ((struct pex_obj *, int count, int *vector));

/* Return times of all programs.  This is really just struct timeval,
   but that is not portable to all systems.  Returns 0 on error, 1 on
   success.  */

struct pex_time
{
  unsigned long user_seconds;
  unsigned long user_microseconds;
  unsigned long system_seconds;
  unsigned long system_microseconds;
};

extern int pex_get_times PARAMS ((struct pex_obj *, int count,
                                  struct pex_time *vector));

/* Clean up a pex_obj.  */

extern void pex_free PARAMS ((struct pex_obj *));

/* Just execute one program.  On success, returns NULL and puts the
   exit status in *STATUS.  On failure, returns an error string and
   sets *ERR as for pex_run.  */

extern const char *pex_one PARAMS ((const char *executable,
                                    char * const *argv,
                                    const char *pname,
                                    int *status,
                                    int *err));

Reply via email to