diff options
author | Nick Clifton <nickc@redhat.com> | 2000-01-07 22:33:48 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2000-01-07 22:33:48 +0000 |
commit | 5a298d2d9c2cf09936f8380963173e6b66249207 (patch) | |
tree | 076dd5b5daaad77f5017c9422212dcd09ee99846 /binutils/resrc.c | |
parent | fa19fce00328512d4e0e86da9fa7ca4487997c7c (diff) | |
download | gdb-5a298d2d9c2cf09936f8380963173e6b66249207.zip gdb-5a298d2d9c2cf09936f8380963173e6b66249207.tar.gz gdb-5a298d2d9c2cf09936f8380963173e6b66249207.tar.bz2 |
Apply Mumit Khan's patch to allow temporary file for process interconnection
Diffstat (limited to 'binutils/resrc.c')
-rw-r--r-- | binutils/resrc.c | 275 |
1 files changed, 255 insertions, 20 deletions
diff --git a/binutils/resrc.c b/binutils/resrc.c index 8ed6a5d..b38c75d 100644 --- a/binutils/resrc.c +++ b/binutils/resrc.c @@ -29,9 +29,50 @@ #include <assert.h> #include <ctype.h> +#include <errno.h> #include <sys/stat.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#else /* ! HAVE_SYS_WAIT_H */ +#if ! defined (_WIN32) || defined (__CYGWIN__) +#ifndef WIFEXITED +#define WIFEXITED(w) (((w)&0377) == 0) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0) +#endif +#ifndef WTERMSIG +#define WTERMSIG(w) ((w) & 0177) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(w) (((w) >> 8) & 0377) +#endif +#else /* defined (_WIN32) && ! defined (__CYGWIN__) */ +#ifndef WIFEXITED +#define WIFEXITED(w) (((w) & 0xff) == 0) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f) +#endif +#ifndef WTERMSIG +#define WTERMSIG(w) ((w) & 0x7f) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(w) (((w) & 0xff00) >> 8) +#endif +#endif /* defined (_WIN32) && ! defined (__CYGWIN__) */ +#endif /* ! HAVE_SYS_WAIT_H */ #if defined (_WIN32) && ! defined (__CYGWIN32__) +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#if defined (_WIN32) && ! defined (__CYGWIN__) #define popen _popen #define pclose _pclose #endif @@ -86,6 +127,15 @@ int rc_lineno; static FILE *cpp_pipe; +/* The temporary file used if we're not using popen, so we can delete it + if we exit. */ + +static char *cpp_temp_file; + +/* Input stream is either a file or a pipe. */ + +static enum {ISTREAM_PIPE, ISTREAM_FILE} istream_type; + /* As we read the rc file, we attach information to this structure. */ static struct res_directory *resources; @@ -112,9 +162,11 @@ static int icons; /* Local functions. */ +static int run_cmd PARAMS ((char *, const char *)); +static FILE *open_input_stream PARAMS ((char *)); static FILE *look_for_default PARAMS ((char *, const char *, int, const char *, const char *)); -static void close_pipe PARAMS ((void)); +static void close_input_stream PARAMS ((void)); static void unexpected_eof PARAMS ((const char *)); static int get_word PARAMS ((FILE *, const char *)); static unsigned long get_long PARAMS ((FILE *, const char *)); @@ -122,6 +174,163 @@ static void get_data PARAMS ((FILE *, unsigned char *, unsigned long, const char *)); static void define_fontdirs PARAMS ((void)); +/* Run `cmd' and redirect the output to `redir'. */ + +static int +run_cmd (cmd, redir) + char *cmd; + const char *redir; +{ + char *s; + int pid, wait_status, retcode; + int i; + const char **argv; + char *errmsg_fmt, *errmsg_arg; + char *temp_base = choose_temp_base (); + int in_quote; + char sep; + int redir_handle = -1; + int stdout_save = -1; + + /* Count the args. */ + i = 0; + + for (s = cmd; *s; s++) + if (*s == ' ') + i++; + + i++; + argv = alloca (sizeof (char *) * (i + 3)); + i = 0; + s = cmd; + + while (1) + { + while (*s == ' ' && *s != 0) + s++; + + if (*s == 0) + break; + + in_quote = (*s == '\'' || *s == '"'); + sep = (in_quote) ? *s++ : ' '; + argv[i++] = s; + + while (*s != sep && *s != 0) + s++; + + if (*s == 0) + break; + + *s++ = 0; + + if (in_quote) + s++; + } + argv[i++] = NULL; + + /* Setup the redirection. We can't use the usual fork/exec and redirect + since we may be running on non-POSIX Windows host. */ + + fflush (stdout); + fflush (stderr); + + /* Open temporary output file. */ + redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (redir_handle == -1) + fatal (_("can't open temporary file `%s': %s"), redir, + strerror (errno)); + + /* Duplicate the stdout file handle so it can be restored later. */ + stdout_save = dup (STDOUT_FILENO); + if (stdout_save == -1) + fatal (_("can't redirect stdout: `%s': %s"), redir, strerror (errno)); + + /* Redirect stdout to our output file. */ + dup2 (redir_handle, STDOUT_FILENO); + + pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, + &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); + + /* Restore stdout to its previous setting. */ + dup2 (stdout_save, STDOUT_FILENO); + + /* Close reponse file. */ + close (redir_handle); + + if (pid == -1) + { + fatal (_("%s %s: %s"), errmsg_fmt, errmsg_arg, strerror (errno)); + return 1; + } + + retcode = 0; + pid = pwait (pid, &wait_status, 0); + + if (pid == -1) + { + fatal (_("wait: %s"), strerror (errno)); + retcode = 1; + } + else if (WIFSIGNALED (wait_status)) + { + fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status)); + retcode = 1; + } + else if (WIFEXITED (wait_status)) + { + if (WEXITSTATUS (wait_status) != 0) + { + fatal (_("%s exited with status %d"), cmd, + WEXITSTATUS (wait_status)); + retcode = 1; + } + } + else + retcode = 1; + + return retcode; +} + +static FILE * +open_input_stream (cmd) + char *cmd; +{ + if (istream_type == ISTREAM_FILE) + { + char *fileprefix; + + fileprefix = choose_temp_base (); + cpp_temp_file = (char *) xmalloc (strlen (fileprefix) + 5); + sprintf (cpp_temp_file, "%s.irc", fileprefix); + free (fileprefix); + + if (run_cmd (cmd, cpp_temp_file)) + fatal (_("can't execute `%s': %s"), cmd, strerror (errno)); + + cpp_pipe = fopen (cpp_temp_file, FOPEN_RT);; + if (cpp_pipe == NULL) + fatal (_("can't open temporary file `%s': %s"), + cpp_temp_file, strerror (errno)); + + if (verbose) + fprintf (stderr, + _("Using temporary file `%s' to read preprocessor output\n"), + cpp_temp_file); + } + else + { + cpp_pipe = popen (cmd, FOPEN_RT); + if (cpp_pipe == NULL) + fatal (_("can't popen `%s': %s"), cmd, strerror (errno)); + if (verbose) + fprintf (stderr, _("Using popen to read preprocessor output\n")); + } + + xatexit (close_input_stream); + return cpp_pipe; +} + /* look for the preprocessor program */ static FILE * @@ -143,7 +352,11 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) if (space) *space = 0; - if (strchr (cmd, '/')) + if ( +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32) + strchr (cmd, '\\') || +#endif + strchr (cmd, '/')) { found = (stat (cmd, &s) == 0 #ifdef HAVE_EXECUTABLE_SUFFIX @@ -154,7 +367,7 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) if (! found) { if (verbose) - fprintf (stderr, "Tried `%s'\n", cmd); + fprintf (stderr, _("Tried `%s'\n"), cmd); return NULL; } } @@ -165,23 +378,26 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) DEFAULT_PREPROCESSOR, preprocargs, filename); if (verbose) - fprintf (stderr, "Using `%s'\n", cmd); + fprintf (stderr, _("Using `%s'\n"), cmd); - cpp_pipe = popen (cmd, FOPEN_RT); + cpp_pipe = open_input_stream (cmd); return cpp_pipe; } /* Read an rc file. */ struct res_directory * -read_rc_file (filename, preprocessor, preprocargs, language) +read_rc_file (filename, preprocessor, preprocargs, language, use_temp_file) const char *filename; const char *preprocessor; const char *preprocargs; int language; + int use_temp_file; { char *cmd; + istream_type = (use_temp_file) ? ISTREAM_FILE : ISTREAM_PIPE; + if (preprocargs == NULL) preprocargs = ""; if (filename == NULL) @@ -195,7 +411,7 @@ read_rc_file (filename, preprocessor, preprocargs, language) + 10); sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename); - cpp_pipe = popen (cmd, FOPEN_RT); + cpp_pipe = open_input_stream (cmd); } else { @@ -219,7 +435,7 @@ read_rc_file (filename, preprocessor, preprocargs, language) if (*cp == '-') dash = cp; if ( -#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32) *cp == ':' || *cp == '\\' || #endif *cp == '/') @@ -257,12 +473,9 @@ read_rc_file (filename, preprocessor, preprocargs, language) } } - if (cpp_pipe == NULL) - fatal (_("can't popen `%s': %s"), cmd, strerror (errno)); + free (cmd); - xatexit (close_pipe); - rc_filename = xstrdup (filename); rc_lineno = 1; if (language != -1) @@ -270,10 +483,8 @@ read_rc_file (filename, preprocessor, preprocargs, language) yyin = cpp_pipe; yyparse (); - if (pclose (cpp_pipe) != 0) - fprintf (stderr, _("%s: warning: preprocessor failed\n"), program_name); - cpp_pipe = NULL; - + close_input_stream (); + if (fontdirs != NULL) define_fontdirs (); @@ -283,13 +494,37 @@ read_rc_file (filename, preprocessor, preprocargs, language) return resources; } -/* Close the pipe if it is open. This is called via xatexit. */ +/* Close the input stream if it is open. */ -void -close_pipe () +static void +close_input_stream () { if (cpp_pipe != NULL) pclose (cpp_pipe); + + if (istream_type == ISTREAM_FILE) + { + if (cpp_pipe != NULL) + fclose (cpp_pipe); + + if (cpp_temp_file != NULL) + { + int errno_save = errno; + + unlink (cpp_temp_file); + errno = errno_save; + free (cpp_temp_file); + } + } + else + { + if (cpp_pipe != NULL) + pclose (cpp_pipe); + } + + /* Since this is also run via xatexit, safeguard. */ + cpp_pipe = NULL; + cpp_temp_file = NULL; } /* Report an error while reading an rc file. */ @@ -307,7 +542,7 @@ void rcparse_warning (msg) const char *msg; { - fprintf (stderr, "%s:%d: %s\n", rc_filename, rc_lineno, msg); + fprintf (stderr, _("%s:%d: %s\n"), rc_filename, rc_lineno, msg); } /* Die if we get an unexpected end of file. */ |