summaryrefslogtreecommitdiff
path: root/job.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2004-03-22 15:11:48 +0000
committerPaul Smith <psmith@gnu.org>2004-03-22 15:11:48 +0000
commite334942e573ea8a4416eca0afafcaf45c3bba06f (patch)
tree856acdfc21f2aa5cbfca7dff414b193496f0d2c1 /job.c
parentf305a52c02cd17188bb6cc429d56c5912c976229 (diff)
downloadgunmake-e334942e573ea8a4416eca0afafcaf45c3bba06f.tar.gz
Numerous updates and bug fixes.
A number of W32 cleanups from J.Grant. A number of OS/2 cleanups from Andreas Buening. Various random bug fixes.
Diffstat (limited to 'job.c')
-rw-r--r--job.c237
1 files changed, 117 insertions, 120 deletions
diff --git a/job.c b/job.c
index 681fdcf..0153995 100644
--- a/job.c
+++ b/job.c
@@ -469,7 +469,7 @@ reap_children (int block, int err)
&& (block || REAP_MORE))
{
int remote = 0;
- register int pid;
+ pid_t pid;
int exit_code, exit_sig, coredump;
register struct child *lastc, *c;
int child_failed;
@@ -611,29 +611,34 @@ reap_children (int block, int err)
{
HANDLE hPID;
int err;
+ exit_code = 0;
+ exit_sig = 0;
+ coredump = 0;
/* wait for anything to finish */
- if (hPID = process_wait_for_any()) {
+ hPID = process_wait_for_any();
+ if (hPID)
+ {
- /* was an error found on this process? */
- err = process_last_err(hPID);
+ /* was an error found on this process? */
+ err = process_last_err(hPID);
- /* get exit data */
- exit_code = process_exit_code(hPID);
+ /* get exit data */
+ exit_code = process_exit_code(hPID);
- if (err)
- fprintf(stderr, "make (e=%d): %s",
- exit_code, map_windows32_error_to_string(exit_code));
+ if (err)
+ fprintf(stderr, "make (e=%d): %s",
+ exit_code, map_windows32_error_to_string(exit_code));
- /* signal */
- exit_sig = process_signal(hPID);
+ /* signal */
+ exit_sig = process_signal(hPID);
- /* cleanup process */
- process_cleanup(hPID);
+ /* cleanup process */
+ process_cleanup(hPID);
- coredump = 0;
- }
- pid = (int) hPID;
+ coredump = 0;
+ }
+ pid = (pid_t) hPID;
}
#endif /* WINDOWS32 */
}
@@ -2400,11 +2405,22 @@ child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
/* Run the command. */
pid = exec_command (argv, envp);
- /* Restore stdout/stdin of the parent process. */
- if (stdin_fd != 0 && dup2 (save_stdin, 0) != 0)
- fatal (NILF, _("restoring of stdin failed\n"));
- if (stdout_fd != 1 && dup2 (save_stdout, 1) != 1)
- fatal (NILF, _("restoring of stdout failed\n"));
+ /* Restore stdout/stdin of the parent and close temporary FDs. */
+ if (stdin_fd != 0)
+ {
+ if (dup2 (save_stdin, 0) != 0)
+ fatal (NILF, _("Could not restore stdin\n"));
+ else
+ close (save_stdin);
+ }
+
+ if (stdout_fd != 1)
+ {
+ if (dup2 (save_stdout, 1) != 1)
+ fatal (NILF, _("Could not restore stdout\n"));
+ else
+ close (save_stdout);
+ }
return pid;
}
@@ -2482,7 +2498,8 @@ exec_command (char **argv, char **envp)
}
/* wait and reap last child */
- while (hWaitPID = process_wait_for_any())
+ hWaitPID = process_wait_for_any();
+ while (hWaitPID)
{
/* was an error found on this process? */
err = process_last_err(hWaitPID);
@@ -2550,6 +2567,7 @@ exec_command (char **argv, char **envp)
char *shell;
char **new_argv;
int argc;
+ int i=1;
# ifdef __EMX__
/* Do not use $SHELL from the environment */
@@ -2568,12 +2586,27 @@ exec_command (char **argv, char **envp)
while (argv[argc] != 0)
++argc;
+# ifdef __EMX__
+ if (!unixy_shell)
+ ++argc;
+# endif
+
new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *));
new_argv[0] = shell;
- new_argv[1] = argv[0];
+
+# ifdef __EMX__
+ if (!unixy_shell)
+ {
+ new_argv[1] = "/c";
+ ++i;
+ --argc;
+ }
+# endif
+
+ new_argv[i] = argv[0];
while (argc > 0)
{
- new_argv[1 + argc] = argv[argc];
+ new_argv[i + argc] = argv[argc];
--argc;
}
@@ -3010,8 +3043,16 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
{
register int j;
for (j = 0; sh_cmds[j] != 0; ++j)
- if (streq (sh_cmds[j], new_argv[0]))
- goto slow;
+ {
+ if (streq (sh_cmds[j], new_argv[0]))
+ goto slow;
+# ifdef __EMX__
+ /* Non-Unix shells are case insensitive. */
+ if (!unixy_shell
+ && strcasecmp (sh_cmds[j], new_argv[0]) == 0)
+ goto slow;
+# endif
+ }
}
/* Ignore multiple whitespace chars. */
@@ -3247,103 +3288,59 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
new_argv = construct_command_argv_internal (new_line, (char **) NULL,
(char *) 0, (char *) 0,
(char **) 0);
-# ifdef __EMX__
+#ifdef __EMX__
else if (!unixy_shell)
{
- /* new_line is local, must not be freed therefore */
- char *p, *q;
- int quote;
- size_t index;
- size_t len;
-
- /* handle quotes
- We have to remove all double quotes and to split the line
- into distinct arguments because of the strange handling
- of builtin commands by cmd: 'echo "bla"' prints "bla"
- (with quotes) while 'c:\bin\echo.exe "bla"' prints bla
- (without quotes). Some programs like autoconf rely
- on the second behaviour. */
-
- len = strlen (new_line) + 1;
-
- /* More than 1 arg per character is impossible. */
- new_argv = (char **) xmalloc (len * sizeof (char *));
-
- /* All the args can fit in a buffer as big as new_line is. */
- new_argv[0] = (char *) xmalloc (len);
-
- index = 0;
- quote = 0;
- q = new_line;
- p = new_argv[index];
- while(*q != '\0')
- {
- /* searching for closing quote */
- if (quote)
- {
- if (*q == quote)
- {
- /* remove the quote */
- q++;
- quote = 0;
- }
- else /* normal character: copy it */
- *p++ = *q++;
- }
-
- /* searching for opening quote */
- else if (*q == '\"'
-# ifndef NO_CMD_DEFAULT
- || *q == '\''
-# endif
- )
- {
- /* remove opening quote */
- quote = *q;
- q++;
- }
-
- /* spaces outside of a quoted string: remove them
- and start a new argument */
- else if (*q == ' ' || *q == '\t')
- {
- *p++ = '\0'; /* trailing '\0' for last argument */
-
- /* remove all successive spaces */
- do
- {
- q++;
- }
- while(*q == ' ' || *q == '\t');
-
- /* start new argument */
- index++;
- new_argv[index] = p;
- }
+ /* new_line is local, must not be freed therefore
+ We use line here instead of new_line because we run the shell
+ manually. */
+ size_t line_len = strlen (line);
+ memcpy (new_line, line, line_len + 1);
+
+# ifndef NO_CMD_DEFAULT
+ if (strnicmp (new_line, "echo", 4) == 0
+ && (new_line[4] == ' ' || new_line[4] == '\t'))
+ {
+ /* the builtin echo command: handle it separately */
+ size_t echo_len = line_len - 5;
+ char *echo_line = new_line + 5;
+
+ /* special case: echo 'x="y"'
+ cmd works this way: a string is printed as is, i.e., no quotes
+ are removed. But autoconf uses a command like echo 'x="y"' to
+ determine whether make works. autoconf expects the output x="y"
+ so we will do exactly that.
+ Note: if we do not allow cmd to be the default shell
+ we do not need this kind of voodoo */
+ if (echo_line[0] == '\''
+ && echo_line[echo_len - 1] == '\''
+ && strncmp (echo_line + 1, "ac_maketemp=",
+ strlen ("ac_maketemp=")) == 0)
+ {
+ /* remove the enclosing quotes */
+ memmove (echo_line, echo_line + 1, echo_len - 2);
+ echo_line[echo_len - 2] = '\0';
+ }
+ }
+# endif
- /* normal character (no space) outside a quoted string*/
- else
- *p++ = *q++;
- } /* end while() */
-
- *p = '\0'; /* trailing '\0' for the last argument */
- new_argv[index + 1] = NULL;
-
-# ifndef NO_CMD_DEFAULT
- /* special case: echo x="y"
- (e.g. autoconf uses this to determine whether make works)
- this is pure idioty but cmd works this way:
- if 'echo' and 'x="y"' are two different arguments cmd
- will print '"x="y""' but if they are only one argument
- cmd will print 'bla="blurb"' as it should be
- note: if we do not allow cmd to be the default shell
- we do not need this kind of voodoo */
- if (index == 3 && strcasecmp(new_argv[2], "echo") == 0)
- {
- new_argv[2][4] = ' ';
- new_argv[3] = NULL;
- }
-# endif
+ {
+ /* Let the shell decide what to do. Put the command line into the
+ 2nd command line argument and hope for the best ;-) */
+ size_t sh_len = strlen (shell);
+
+ /* exactly 3 arguments + NULL */
+ new_argv = (char **) xmalloc (4 * sizeof (char *));
+ /* Exactly strlen(shell) + strlen("/c") + strlen(line) + 3 times
+ the trailing '\0' */
+ new_argv[0] = (char *) malloc (sh_len + line_len + 5);
+ memcpy (new_argv[0], shell, sh_len + 1);
+ new_argv[1] = new_argv[0] + sh_len + 1;
+ memcpy (new_argv[1], "/c", 3);
+ new_argv[2] = new_argv[1] + 3;
+ memcpy (new_argv[2], new_line, line_len);
+ new_argv[3] = NULL;
+ }
}
#elif defined(__MSDOS__)
else