diff options
author | obrien <obrien@FreeBSD.org> | 2000-05-12 23:15:20 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-05-12 23:15:20 +0000 |
commit | 2a9ea95d682586d2b0c31da28d82a73d786c7c0a (patch) | |
tree | 9d4ce42d357c391a11d77254b770908c02ecf672 /contrib/binutils/libiberty/pexecute.c | |
parent | bffe850874e72664f78cf171ab1c4339b9b63cab (diff) | |
download | FreeBSD-src-2a9ea95d682586d2b0c31da28d82a73d786c7c0a.zip FreeBSD-src-2a9ea95d682586d2b0c31da28d82a73d786c7c0a.tar.gz |
Import of Binutils 2.10 snapshot.
Diffstat (limited to 'contrib/binutils/libiberty/pexecute.c')
-rw-r--r-- | contrib/binutils/libiberty/pexecute.c | 186 |
1 files changed, 100 insertions, 86 deletions
diff --git a/contrib/binutils/libiberty/pexecute.c b/contrib/binutils/libiberty/pexecute.c index fbbea40..56ddec7 100644 --- a/contrib/binutils/libiberty/pexecute.c +++ b/contrib/binutils/libiberty/pexecute.c @@ -1,6 +1,6 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996-2000 Free Software Foundation, Inc. This file is part of the libiberty library. Libiberty is free software; you can redistribute it and/or @@ -23,24 +23,37 @@ Boston, MA 02111-1307, USA. */ /* This file lives in at least two places: libiberty and gcc. Don't change one without the other. */ -#ifdef IN_GCC +#ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#define ISSPACE (x) isspace(x) +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif -#ifdef IN_GCC -#include "gansidecl.h" -/* ??? Need to find a suitable header file. */ -#define PEXECUTE_FIRST 1 -#define PEXECUTE_LAST 2 -#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) -#define PEXECUTE_SEARCH 4 -#define PEXECUTE_VERBOSE 8 +#ifdef vfork /* Autoconf may define this to fork for us. */ +# define VFORK_STRING "fork" #else -#include "libiberty.h" +# 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 */ + +#include "libiberty.h" /* stdin file number. */ #define STDIN_FILE_NO 0 @@ -146,6 +159,8 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) FILE *argfile; int i, el = flags & PEXECUTE_SEARCH ? 4 : 0; + if (temp_base == 0) + temp_base = choose_temp_base (); scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el); rf = scmd + strlen(program) + 2 + el; sprintf (scmd, "%s%s @%s.gp", program, @@ -166,7 +181,7 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) char *cp; for (cp = argv[i]; *cp; cp++) { - if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) + if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp)) fputc ('\\', argfile); fputc (*cp, argfile); } @@ -220,53 +235,18 @@ pwait (pid, status, flags) #endif /* MSDOS */ -#if defined (_WIN32) +#if defined (_WIN32) && ! defined (_UWIN) #include <process.h> -#ifdef __CYGWIN32__ +#ifdef __CYGWIN__ #define fix_argv(argvec) (argvec) extern int _spawnv (); extern int _spawnvp (); -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; - char **errmsg_fmt, **errmsg_arg; - int flags; -{ - int pid; - - if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) - abort (); - pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv) - (_P_NOWAIT, program, fix_argv(argv)); - if (pid == -1) - { - *errmsg_fmt = install_error_msg; - *errmsg_arg = program; - return -1; - } - return pid; -} - -int -pwait (pid, status, flags) - int pid; - int *status; - int flags; -{ - /* ??? Here's an opportunity to canonicalize the values in STATUS. - Needed? */ - return cwait (status, pid, WAIT_CHILD); -} - -#else /* ! __CYGWIN32__ */ +#else /* ! __CYGWIN__ */ /* This is a kludge to get around the Microsoft C spawn functions' propensity to remove the outermost set of double quotes from all arguments. */ @@ -302,8 +282,48 @@ fix_argv (argvec) 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; } +#endif /* __CYGWIN__ */ #include <io.h> #include <fcntl.h> @@ -420,6 +440,9 @@ pwait (pid, status, flags) int *status; int flags; { +#ifdef __CYGWIN__ + return wait (status); +#else int termstat; pid = _cwait (&termstat, pid, WAIT_CHILD); @@ -437,11 +460,10 @@ pwait (pid, status, flags) *status = (((termstat) & 0xff) << 8); return pid; +#endif /* __CYGWIN__ */ } -#endif /* ! defined (__CYGWIN32__) */ - -#endif /* _WIN32 */ +#endif /* _WIN32 && ! _UWIN */ #ifdef OS2 @@ -509,7 +531,7 @@ static int first_time = 1; int pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) const char *program; - char **argv; + char * const *argv; const char *this_pname; const char *temp_base; char **errmsg_fmt, **errmsg_arg; @@ -538,14 +560,18 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) fputc (' ', stdout); for (i=1; argv[i]; i++) { - /* We have to quote every arg, so that when the echo is - executed, the quotes are stripped and the original arg - is left. */ fputc ('\'', stdout); + /* See if we have an argument that needs fixing. */ + if (strchr(argv[i], '/')) + { + tmpname = (char *) xmalloc (256); + mpwify_filename (argv[i], tmpname); + argv[i] = tmpname; + } for (cp = argv[i]; *cp; cp++) { - /* Write an Option-d esc char in front of special chars. */ - if (strchr ("\"'+", *cp)) + /* Write an Option-d escape char in front of special chars. */ + if (strchr("'+", *cp)) fputc ('\266', stdout); fputc (*cp, stdout); } @@ -560,15 +586,20 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) for (i=1; argv[i]; i++) { + /* See if we have an argument that needs fixing. */ + if (strchr(argv[i], '/')) + { + tmpname = (char *) xmalloc (256); + mpwify_filename (argv[i], tmpname); + argv[i] = tmpname; + } if (strchr (argv[i], ' ')) fputc ('\'', stdout); for (cp = argv[i]; *cp; cp++) { - /* Write an Option-d esc char in front of special chars. */ - if (strchr ("\"'+", *cp)) - { - fputc ('\266', stdout); - } + /* Write an Option-d escape char in front of special chars. */ + if (strchr("'+", *cp)) + fputc ('\266', stdout); fputc (*cp, stdout); } if (strchr (argv[i], ' ')) @@ -615,16 +646,7 @@ pfinish () /* include for Unix-like environments but not for Dos-like environments */ #if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \ - && ! defined (_WIN32) - -#ifdef VMS -#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ - lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) -#else -#ifdef USG -#define vfork fork -#endif -#endif + && ! (defined (_WIN32) && ! defined (_UWIN)) extern int execv (); extern int execvp (); @@ -634,7 +656,7 @@ 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; + const char *temp_base ATTRIBUTE_UNUSED; char **errmsg_fmt, **errmsg_arg; int flags; { @@ -689,11 +711,7 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) { case -1: { -#ifdef vfork - *errmsg_fmt = "fork"; -#else - *errmsg_fmt = "vfork"; -#endif + *errmsg_fmt = VFORK_STRING; *errmsg_arg = NULL; return -1; } @@ -723,11 +741,7 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) /* Note: Calling fprintf and exit here doesn't seem right for vfork. */ fprintf (stderr, "%s: ", this_pname); fprintf (stderr, install_error_msg, program); -#ifdef IN_GCC - fprintf (stderr, ": %s\n", my_strerror (errno)); -#else fprintf (stderr, ": %s\n", xstrerror (errno)); -#endif exit (-1); /* NOTREACHED */ return 0; @@ -749,7 +763,7 @@ int pwait (pid, status, flags) int pid; int *status; - int flags; + int flags ATTRIBUTE_UNUSED; { /* ??? Here's an opportunity to canonicalize the values in STATUS. Needed? */ @@ -761,4 +775,4 @@ pwait (pid, status, flags) return pid; } -#endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! _WIN32 */ +#endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! (_WIN32 && ! _UWIN) */ |