diff options
author | Paul Smith <psmith@gnu.org> | 2013-05-17 02:29:46 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2013-05-17 02:29:46 -0400 |
commit | 96cf67bd29957cfde6c5f15cfec7e370c6dbabe2 (patch) | |
tree | d59d8a6fd1a43f4e985654466a9bd7bd5df8cf46 /job.c | |
parent | 5370238316ee4284fe058a9c298a5734d2686678 (diff) | |
download | gunmake-96cf67bd29957cfde6c5f15cfec7e370c6dbabe2.tar.gz |
Update source file format: remove TABs, use GNU coding styles.
Diffstat (limited to 'job.c')
-rw-r--r-- | job.c | 1603 |
1 files changed, 809 insertions, 794 deletions
@@ -118,13 +118,13 @@ static void vmsWaitForChildren (int *); #endif #ifdef HAVE_WAITPID -# define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG) -#else /* Don't have waitpid. */ +# define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG) +#else /* Don't have waitpid. */ # ifdef HAVE_WAIT3 # ifndef wait3 extern int wait3 (); # endif -# define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0) +# define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0) # endif /* Have wait3. */ #endif /* Have waitpid. */ @@ -132,7 +132,7 @@ extern int wait3 (); int wait (); #endif -#ifndef HAVE_UNION_WAIT +#ifndef HAVE_UNION_WAIT # define WAIT_T int @@ -152,7 +152,7 @@ int wait (); # define WIFEXITED(x) (WTERMSIG (x) == 0) # endif -#else /* Have 'union wait'. */ +#else /* Have 'union wait'. */ # define WAIT_T union wait # ifndef WTERMSIG @@ -171,7 +171,7 @@ int wait (); # define WIFEXITED(x) (WTERMSIG(x) == 0) # endif -#endif /* Don't have 'union wait'. */ +#endif /* Don't have 'union wait'. */ #if !defined(HAVE_UNISTD_H) && !defined(WINDOWS32) int dup2 (); @@ -261,9 +261,9 @@ static int combined_output = 0; * The macro which references this function is defined in makeint.h. */ int -w32_kill(pid_t pid, int sig) +w32_kill (pid_t pid, int sig) { - return ((process_kill((HANDLE)pid, sig) == TRUE) ? 0 : -1); + return ((process_kill ((HANDLE)pid, sig) == TRUE) ? 0 : -1); } /* This function creates a temporary file name with an extension specified @@ -276,7 +276,7 @@ create_batch_file (char const *base, int unixy, int *fd) const char *const ext = unixy ? "sh" : "bat"; const char *error_string = NULL; char temp_path[MAXPATHLEN]; /* need to know its length */ - unsigned path_size = GetTempPath(sizeof temp_path, temp_path); + unsigned path_size = GetTempPath (sizeof temp_path, temp_path); int path_is_dot = 0; /* The following variable is static so we won't try to reuse a name that was generated a little while ago, because that file might @@ -300,9 +300,9 @@ create_batch_file (char const *base, int unixy, int *fd) if (uniq >= 0x10000 && !second_loop) { /* If we already had 64K batch files in this - process, make a second loop through the numbers, - looking for free slots, i.e. files that were - deleted in the meantime. */ + process, make a second loop through the numbers, + looking for free slots, i.e. files that were + deleted in the meantime. */ second_loop = 1; uniq = 1; } @@ -325,17 +325,17 @@ create_batch_file (char const *base, int unixy, int *fd) if (h == INVALID_HANDLE_VALUE) { - const DWORD er = GetLastError(); + const DWORD er = GetLastError (); if (er == ERROR_FILE_EXISTS || er == ERROR_ALREADY_EXISTS) - { - ++uniq; - if (uniq == 0x10000 && !second_loop) - { - second_loop = 1; - uniq = 1; - } - } + { + ++uniq; + if (uniq == 0x10000 && !second_loop) + { + second_loop = 1; + uniq = 1; + } + } /* the temporary path is not guaranteed to exist */ else if (path_is_dot == 0) @@ -411,11 +411,12 @@ _is_unixy_shell (const char *path) if (*name == '/' || *name == '\\') name++; i = 0; - while (known_os2shells[i] != NULL) { - if (strcasecmp (name, known_os2shells[i]) == 0) - return 0; /* not a unix shell */ - i++; - } + while (known_os2shells[i] != NULL) + { + if (strcasecmp (name, known_os2shells[i]) == 0) + return 0; /* not a unix shell */ + i++; + } /* in doubt assume a unix like shell */ return 1; @@ -453,17 +454,18 @@ is_bourne_compatible_shell (const char *path) if (*name == '/' || *name == '\\') name++; /* this should be able to deal with extensions on Windows-like systems */ - for (i = 0; unix_shells[i] != NULL; i++) { - len = strlen(unix_shells[i]); + for (i = 0; unix_shells[i] != NULL; i++) + { + len = strlen (unix_shells[i]); #if defined(WINDOWS32) || defined(__MSDOS__) - if ((strncasecmp (name, unix_shells[i], len) == 0) && - (strlen(name) >= len && (name[len] == '\0' || name[len] == '.'))) + if ((strncasecmp (name, unix_shells[i], len) == 0) && + (strlen (name) >= len && (name[len] == '\0' || name[len] == '.'))) #else - if ((strncmp (name, unix_shells[i], len) == 0) && - (strlen(name) >= len && name[len] == '\0')) + if ((strncmp (name, unix_shells[i], len) == 0) && + (strlen (name) >= len && name[len] == '\0')) #endif - return 1; /* a known unix-style shell */ - } + return 1; /* a known unix-style shell */ + } /* if not on the list, assume it's not a Bourne-like shell */ return 0; @@ -700,7 +702,7 @@ pump_from_tmp (int from, FILE *to) /* from_fd is opened by open_tmpfd, which does it in binary mode, so we need the mode of to_fd to match that. */ - prev_mode = _setmode (fileno(to), _O_BINARY); + prev_mode = _setmode (fileno (to), _O_BINARY); #endif if (lseek (from, 0, SEEK_SET) == -1) @@ -791,14 +793,14 @@ sync_output (struct child *c) if (c->outfd >= 0) { int e; - lseek(c->outfd, 0, SEEK_SET); - EINTRLOOP (e, ftruncate(c->outfd, 0)); + lseek (c->outfd, 0, SEEK_SET); + EINTRLOOP (e, ftruncate (c->outfd, 0)); } if (c->errfd >= 0 && c->errfd != c->outfd) { int e; - lseek(c->errfd, 0, SEEK_SET); - EINTRLOOP (e, ftruncate(c->errfd, 0)); + lseek (c->errfd, 0, SEEK_SET); + EINTRLOOP (e, ftruncate (c->errfd, 0)); } } } @@ -848,109 +850,109 @@ reap_children (int block, int err) int dontcare; if (err && block) - { + { static int printed = 0; - /* We might block for a while, so let the user know why. + /* We might block for a while, so let the user know why. Only print this message once no matter how many jobs are left. */ - fflush (stdout); + fflush (stdout); if (!printed) error (NILF, _("*** Waiting for unfinished jobs....")); printed = 1; - } + } /* We have one less dead child to reap. As noted in - child_handler() above, this count is completely unimportant for - all modern, POSIX-y systems that support wait3() or waitpid(). - The rest of this comment below applies only to early, broken - pre-POSIX systems. We keep the count only because... it's there... - - The test and decrement are not atomic; if it is compiled into: - register = dead_children - 1; - dead_children = register; - a SIGCHLD could come between the two instructions. - child_handler increments dead_children. - The second instruction here would lose that increment. But the - only effect of dead_children being wrong is that we might wait - longer than necessary to reap a child, and lose some parallelism; - and we might print the "Waiting for unfinished jobs" message above - when not necessary. */ + child_handler() above, this count is completely unimportant for + all modern, POSIX-y systems that support wait3() or waitpid(). + The rest of this comment below applies only to early, broken + pre-POSIX systems. We keep the count only because... it's there... + + The test and decrement are not atomic; if it is compiled into: + register = dead_children - 1; + dead_children = register; + a SIGCHLD could come between the two instructions. + child_handler increments dead_children. + The second instruction here would lose that increment. But the + only effect of dead_children being wrong is that we might wait + longer than necessary to reap a child, and lose some parallelism; + and we might print the "Waiting for unfinished jobs" message above + when not necessary. */ if (dead_children > 0) - --dead_children; + --dead_children; any_remote = 0; any_local = shell_function_pid != 0; for (c = children; c != 0; c = c->next) - { - any_remote |= c->remote; - any_local |= ! c->remote; - DB (DB_JOBS, (_("Live child %p (%s) PID %s %s\n"), + { + any_remote |= c->remote; + any_local |= ! c->remote; + DB (DB_JOBS, (_("Live child %p (%s) PID %s %s\n"), c, c->file->name, pid2str (c->pid), c->remote ? _(" (remote)") : "")); #ifdef VMS - break; + break; #endif - } + } /* First, check for remote children. */ if (any_remote) - pid = remote_status (&exit_code, &exit_sig, &coredump, 0); + pid = remote_status (&exit_code, &exit_sig, &coredump, 0); else - pid = 0; + pid = 0; if (pid > 0) - /* We got a remote child. */ - remote = 1; + /* We got a remote child. */ + remote = 1; else if (pid < 0) - { + { /* A remote status command failed miserably. Punt. */ - remote_status_lose: - pfatal_with_name ("remote_status"); - } + remote_status_lose: + pfatal_with_name ("remote_status"); + } else - { - /* No remote children. Check for local children. */ + { + /* No remote children. Check for local children. */ #if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) - if (any_local) - { + if (any_local) + { #ifdef VMS - vmsWaitForChildren (&status); - pid = c->pid; + vmsWaitForChildren (&status); + pid = c->pid; #else #ifdef WAIT_NOHANG - if (!block) - pid = WAIT_NOHANG (&status); - else + if (!block) + pid = WAIT_NOHANG (&status); + else #endif - EINTRLOOP(pid, wait (&status)); + EINTRLOOP(pid, wait (&status)); #endif /* !VMS */ - } - else - pid = 0; + } + else + pid = 0; - if (pid < 0) - { + if (pid < 0) + { /* The wait*() failed miserably. Punt. */ - pfatal_with_name ("wait"); - } - else if (pid > 0) - { - /* We got a child exit; chop the status word up. */ - exit_code = WEXITSTATUS (status); - exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; - coredump = WCOREDUMP (status); + pfatal_with_name ("wait"); + } + else if (pid > 0) + { + /* We got a child exit; chop the status word up. */ + exit_code = WEXITSTATUS (status); + exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; + coredump = WCOREDUMP (status); /* If we have started jobs in this second, remove one. */ if (job_counter) --job_counter; - } - else - { - /* No local children are dead. */ + } + else + { + /* No local children are dead. */ reap_more = 0; - if (!block || !any_remote) + if (!block || !any_remote) break; /* Now try a blocking wait for a remote child. */ @@ -963,26 +965,26 @@ reap_children (int block, int err) /* We got a remote child. */ remote = 1; - } + } #endif /* !__MSDOS__, !Amiga, !WINDOWS32. */ #ifdef __MSDOS__ - /* Life is very different on MSDOS. */ - pid = dos_pid - 1; - status = dos_status; - exit_code = WEXITSTATUS (status); - if (exit_code == 0xff) - exit_code = -1; - exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; - coredump = 0; + /* Life is very different on MSDOS. */ + pid = dos_pid - 1; + status = dos_status; + exit_code = WEXITSTATUS (status); + if (exit_code == 0xff) + exit_code = -1; + exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; + coredump = 0; #endif /* __MSDOS__ */ #ifdef _AMIGA - /* Same on Amiga */ - pid = amiga_pid - 1; - status = amiga_status; - exit_code = amiga_status; - exit_sig = 0; - coredump = 0; + /* Same on Amiga */ + pid = amiga_pid - 1; + status = amiga_status; + exit_code = amiga_status; + exit_sig = 0; + coredump = 0; #endif /* _AMIGA */ #ifdef WINDOWS32 { @@ -1006,32 +1008,32 @@ reap_children (int block, int err) DWORD e = GetLastError (); fprintf (stderr, "Determine main thread ID (Error %ld: %s)\n", - e, map_windows32_error_to_string(e)); + e, map_windows32_error_to_string (e)); } else DB (DB_VERBOSE, ("Main thread handle = %p\n", main_thread)); } /* wait for anything to finish */ - hPID = process_wait_for_any(block, &dwWaitStatus); + hPID = process_wait_for_any (block, &dwWaitStatus); if (hPID) { /* was an error found on this process? */ - werr = process_last_err(hPID); + werr = process_last_err (hPID); /* get exit data */ - exit_code = process_exit_code(hPID); + exit_code = process_exit_code (hPID); if (werr) - fprintf(stderr, "make (e=%d): %s", - exit_code, map_windows32_error_to_string(exit_code)); + fprintf (stderr, "make (e=%d): %s", exit_code, + map_windows32_error_to_string (exit_code)); /* signal */ - exit_sig = process_signal(hPID); + exit_sig = process_signal (hPID); /* cleanup process */ - process_cleanup(hPID); + process_cleanup (hPID); coredump = 0; } @@ -1050,26 +1052,26 @@ reap_children (int block, int err) pid = (pid_t) hPID; } #endif /* WINDOWS32 */ - } + } /* Check if this is the child of the 'shell' function. */ if (!remote && pid == shell_function_pid) - { - /* It is. Leave an indicator for the 'shell' function. */ - if (exit_sig == 0 && exit_code == 127) - shell_function_completed = -1; - else - shell_function_completed = 1; - break; - } + { + /* It is. Leave an indicator for the 'shell' function. */ + if (exit_sig == 0 && exit_code == 127) + shell_function_completed = -1; + else + shell_function_completed = 1; + break; + } child_failed = exit_sig != 0 || exit_code != 0; /* Search for a child matching the deceased one. */ lastc = 0; for (c = children; c != 0; lastc = c, c = c->next) - if (c->pid == pid && c->remote == remote) - break; + if (c->pid == pid && c->remote == remote) + break; if (c == 0) /* An unknown child died. @@ -1081,22 +1083,23 @@ reap_children (int block, int err) : _("Reaping winning child %p PID %s %s\n"), c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); - if (c->sh_batch_file) { - int rm_status; + if (c->sh_batch_file) + { + int rm_status; - DB (DB_JOBS, (_("Cleaning up temp batch file %s\n"), - c->sh_batch_file)); + DB (DB_JOBS, (_("Cleaning up temp batch file %s\n"), + c->sh_batch_file)); - errno = 0; - rm_status = remove (c->sh_batch_file); - if (rm_status) - DB (DB_JOBS, (_("Cleaning up temp batch file %s failed (%d)\n"), - c->sh_batch_file, errno)); + errno = 0; + rm_status = remove (c->sh_batch_file); + if (rm_status) + DB (DB_JOBS, (_("Cleaning up temp batch file %s failed (%d)\n"), + c->sh_batch_file, errno)); - /* all done with memory */ - free (c->sh_batch_file); - c->sh_batch_file = NULL; - } + /* all done with memory */ + free (c->sh_batch_file); + c->sh_batch_file = NULL; + } /* If this child had the good stdin, say it is now free. */ if (c->good_stdin) @@ -1252,13 +1255,13 @@ free_child (struct child *child) job, put a token back into the pipe for it. */ #ifdef WINDOWS32 - if (has_jobserver_semaphore() && jobserver_tokens > 1) + if (has_jobserver_semaphore () && jobserver_tokens > 1) { - if (! release_jobserver_semaphore()) + if (! release_jobserver_semaphore ()) { - DWORD err = GetLastError(); + DWORD err = GetLastError (); fatal (NILF, _("release jobserver semaphore: (Error %ld: %s)"), - err, map_windows32_error_to_string(err)); + err, map_windows32_error_to_string (err)); } DB (DB_JOBS, (_("Released token for child %p (%s).\n"), child, child->file->name)); @@ -1273,7 +1276,7 @@ free_child (struct child *child) EINTRLOOP (r, write (job_fds[1], &token, 1)); if (r != 1) - pfatal_with_name (_("write jobserver")); + pfatal_with_name (_("write jobserver")); DB (DB_JOBS, (_("Released token for child %p (%s).\n"), child, child->file->name)); @@ -1289,7 +1292,7 @@ free_child (struct child *child) { register unsigned int i; for (i = 0; i < child->file->cmds->ncommand_lines; ++i) - free (child->command_lines[i]); + free (child->command_lines[i]); free (child->command_lines); } @@ -1297,7 +1300,7 @@ free_child (struct child *child) { register char **ep = child->environment; while (*ep != 0) - free (*ep++); + free (*ep++); free (child->environment); } @@ -1401,7 +1404,7 @@ start_job_command (struct child *child) /* Combine the flags parsed for the line itself with the flags specified globally for this target. */ flags = (child->file->command_flags - | child->file->cmds->lines_flags[child->command_line - 1]); + | child->file->cmds->lines_flags[child->command_line - 1]); p = child->command_ptr; child->noerror = ((flags & COMMANDS_NOERROR) != 0); @@ -1409,13 +1412,13 @@ start_job_command (struct child *child) while (*p != '\0') { if (*p == '@') - flags |= COMMANDS_SILENT; + flags |= COMMANDS_SILENT; else if (*p == '+') - flags |= COMMANDS_RECURSE; + flags |= COMMANDS_RECURSE; else if (*p == '-') - child->noerror = 1; + child->noerror = 1; else if (!isblank ((unsigned char)*p)) - break; + break; ++p; } @@ -1451,15 +1454,15 @@ start_job_command (struct child *child) argv = p; #else argv = construct_command_argv (p, &end, child->file, - child->file->cmds->lines_flags[child->command_line - 1], + child->file->cmds->lines_flags[child->command_line - 1], &child->sh_batch_file); #endif if (end == NULL) child->command_ptr = NULL; else { - *end++ = '\0'; - child->command_ptr = end; + *end++ = '\0'; + child->command_ptr = end; } } @@ -1481,7 +1484,7 @@ start_job_command (struct child *child) if (touch_flag && !(flags & COMMANDS_RECURSE)) { /* Go on to the next command. It might be the recursive one. - We construct ARGV only to find the end of the command line. */ + We construct ARGV only to find the end of the command line. */ #ifndef VMS if (argv) { @@ -1500,15 +1503,15 @@ start_job_command (struct child *child) #endif /* This line has no commands. Go to the next. */ if (job_next_command (child)) - start_job_command (child); + start_job_command (child); else - { - /* No more commands. Make sure we're "running"; we might not be if + { + /* No more commands. Make sure we're "running"; we might not be if (e.g.) all commands were skipped due to -n. */ set_command_state (child->file, cs_running); - child->file->update_status = 0; - notice_finished_file (child->file); - } + child->file->update_status = 0; + notice_finished_file (child->file); + } return; } @@ -1517,7 +1520,7 @@ start_job_command (struct child *child) #ifdef OUTPUT_SYNC if (output_sync && sync_handle == -1) - sync_init(); + sync_init (); #endif /* Are we going to synchronize this command's output? Do so if either we're @@ -1565,15 +1568,15 @@ start_job_command (struct child *child) #if !defined(VMS) && !defined(_AMIGA) if ( #if defined __MSDOS__ || defined (__EMX__) - unixy_shell /* the test is complicated and we already did it */ + unixy_shell /* the test is complicated and we already did it */ #else - (argv[0] && is_bourne_compatible_shell(argv[0])) + (argv[0] && is_bourne_compatible_shell (argv[0])) #endif && (argv[1] && argv[1][0] == '-' - && - ((argv[1][1] == 'c' && argv[1][2] == '\0') - || - (argv[1][1] == 'e' && argv[1][2] == 'c' && argv[1][3] == '\0'))) + && + ((argv[1][1] == 'c' && argv[1][2] == '\0') + || + (argv[1][1] == 'e' && argv[1][2] == 'c' && argv[1][3] == '\0'))) && (argv[2] && argv[2][0] == ':' && argv[2][1] == '\0') && argv[3] == NULL) { @@ -1607,20 +1610,20 @@ start_job_command (struct child *child) if (bad_stdin == -1) { /* Make a file descriptor that is the read end of a broken pipe. - This will be used for some children's standard inputs. */ + This will be used for some children's standard inputs. */ int pd[2]; if (pipe (pd) == 0) - { - /* Close the write side. */ - (void) close (pd[1]); - /* Save the read side. */ - bad_stdin = pd[0]; - - /* Set the descriptor to close on exec, so it does not litter any - child's descriptor table. When it is dup2'd onto descriptor 0, - that descriptor will not close on exec. */ - CLOSE_ON_EXEC (bad_stdin); - } + { + /* Close the write side. */ + (void) close (pd[1]); + /* Save the read side. */ + bad_stdin = pd[0]; + + /* Set the descriptor to close on exec, so it does not litter any + child's descriptor table. When it is dup2'd onto descriptor 0, + that descriptor will not close on exec. */ + CLOSE_ON_EXEC (bad_stdin); + } } #endif /* !WINDOWS32 && !_AMIGA && !__MSDOS__ */ @@ -1651,21 +1654,21 @@ start_job_command (struct child *child) { int is_remote, id, used_stdin; if (start_remote_job (argv, child->environment, - child->good_stdin ? 0 : bad_stdin, - &is_remote, &id, &used_stdin)) + child->good_stdin ? 0 : bad_stdin, + &is_remote, &id, &used_stdin)) /* Don't give up; remote execution may fail for various reasons. If so, simply run the job locally. */ - goto run_local; + goto run_local; else - { - if (child->good_stdin && !used_stdin) - { - child->good_stdin = 0; - good_stdin_used = 0; - } - child->remote = is_remote; - child->pid = id; - } + { + if (child->good_stdin && !used_stdin) + { + child->good_stdin = 0; + good_stdin_used = 0; + } + child->remote = is_remote; + child->pid = id; + } } else #endif /* !VMS */ @@ -1680,11 +1683,12 @@ start_job_command (struct child *child) child->remote = 0; #ifdef VMS - if (!child_execute_job (argv, child)) { - /* Fork failed! */ - perror_with_name ("fork", ""); - goto error; - } + if (!child_execute_job (argv, child)) + { + /* Fork failed! */ + perror_with_name ("fork", ""); + goto error; + } #else @@ -1694,41 +1698,41 @@ start_job_command (struct child *child) /* If we aren't running a recursive command and we have a jobserver pipe, close it before exec'ing. */ if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0) - { - CLOSE_ON_EXEC (job_fds[0]); - CLOSE_ON_EXEC (job_fds[1]); - } + { + CLOSE_ON_EXEC (job_fds[0]); + CLOSE_ON_EXEC (job_fds[1]); + } if (job_rfd >= 0) - CLOSE_ON_EXEC (job_rfd); + CLOSE_ON_EXEC (job_rfd); /* Never use fork()/exec() here! Use spawn() instead in exec_command() */ child->pid = child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, argv, child->environment); if (child->pid < 0) - { - /* spawn failed! */ - unblock_sigs (); - perror_with_name ("spawn", ""); - goto error; - } + { + /* spawn failed! */ + unblock_sigs (); + perror_with_name ("spawn", ""); + goto error; + } /* undo CLOSE_ON_EXEC() after the child process has been started */ if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0) - { - fcntl (job_fds[0], F_SETFD, 0); - fcntl (job_fds[1], F_SETFD, 0); - } + { + fcntl (job_fds[0], F_SETFD, 0); + fcntl (job_fds[1], F_SETFD, 0); + } if (job_rfd >= 0) - fcntl (job_rfd, F_SETFD, 0); + fcntl (job_rfd, F_SETFD, 0); #else /* !__EMX__ */ child->pid = fork (); - environ = parent_environ; /* Restore value child may have clobbered. */ + environ = parent_environ; /* Restore value child may have clobbered. */ if (child->pid == 0) - { - /* We are the child side. */ - unblock_sigs (); + { + /* We are the child side. */ + unblock_sigs (); /* If we aren't running a recursive command and we have a jobserver pipe, close it before exec'ing. */ @@ -1762,21 +1766,21 @@ start_job_command (struct child *child) } #endif /* OUTPUT_SYNC */ - child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, + child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, argv, child->environment); - } + } else if (child->pid < 0) - { - /* Fork failed! */ - unblock_sigs (); - perror_with_name ("fork", ""); - goto error; - } + { + /* Fork failed! */ + unblock_sigs (); + perror_with_name ("fork", ""); + goto error; + } # endif /* !__EMX__ */ #endif /* !VMS */ } -#else /* __MSDOS__ or Amiga or WINDOWS32 */ +#else /* __MSDOS__ or Amiga or WINDOWS32 */ #ifdef __MSDOS__ { int proc_return; @@ -1790,31 +1794,31 @@ start_job_command (struct child *child) call COMMAND.COM when its internal commands are used. */ if (execute_by_shell) { - char *cmdline = argv[0]; - /* We don't have a way to pass environment to 'system', - so we need to save and restore ours, sigh... */ - char **parent_environ = environ; - - environ = child->environment; - - /* If we have a *real* shell, tell 'system' to call - it to do everything for us. */ - if (unixy_shell) - { - /* A *real* shell on MSDOS may not support long - command lines the DJGPP way, so we must use 'system'. */ - cmdline = argv[2]; /* get past "shell -c" */ - } - - dos_command_running = 1; - proc_return = system (cmdline); - environ = parent_environ; - execute_by_shell = 0; /* for the next time */ + char *cmdline = argv[0]; + /* We don't have a way to pass environment to 'system', + so we need to save and restore ours, sigh... */ + char **parent_environ = environ; + + environ = child->environment; + + /* If we have a *real* shell, tell 'system' to call + it to do everything for us. */ + if (unixy_shell) + { + /* A *real* shell on MSDOS may not support long + command lines the DJGPP way, so we must use 'system'. */ + cmdline = argv[2]; /* get past "shell -c" */ + } + + dos_command_running = 1; + proc_return = system (cmdline); + environ = parent_environ; + execute_by_shell = 0; /* for the next time */ } else { - dos_command_running = 1; - proc_return = spawnvpe (P_WAIT, argv[0], argv, child->environment); + dos_command_running = 1; + proc_return = spawnvpe (P_WAIT, argv[0], argv, child->environment); } /* Need to unblock signals before turning off @@ -1843,7 +1847,7 @@ start_job_command (struct child *child) amiga_batch_file = 0; DeleteFile (amiga_bname); /* Ignore errors. */ } -#endif /* Amiga */ +#endif /* Amiga */ #ifdef WINDOWS32 { HANDLE hPID; @@ -1857,34 +1861,35 @@ start_job_command (struct child *child) *arg0 = '\\'; /* make sure CreateProcess() has Path it needs */ - sync_Path_environment(); + sync_Path_environment (); #ifdef OUTPUT_SYNC /* Divert child output if output_sync in use. Don't capture recursive make output unless we are synchronizing "make" mode. */ if (output_sync && sync_cmd) - hPID = process_easy(argv, child->environment, - child->outfd, child->errfd); - else + hPID = process_easy (argv, child->environment, + child->outfd, child->errfd); + else #endif - hPID = process_easy(argv, child->environment, -1, -1); + hPID = process_easy (argv, child->environment, -1, -1); if (hPID != INVALID_HANDLE_VALUE) child->pid = (pid_t) hPID; - else { - int i; - unblock_sigs(); - fprintf(stderr, - _("process_easy() failed to launch process (e=%ld)\n"), - process_last_err(hPID)); - for (i = 0; argv[i]; i++) - fprintf(stderr, "%s ", argv[i]); - fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); - goto error; - } + else + { + int i; + unblock_sigs (); + fprintf (stderr, + _("process_easy() failed to launch process (e=%ld)\n"), + process_last_err (hPID)); + for (i = 0; argv[i]; i++) + fprintf (stderr, "%s ", argv[i]); + fprintf (stderr, _("\nCounted %d args in failed launch\n"), i); + goto error; + } } #endif /* WINDOWS32 */ -#endif /* __MSDOS__ or Amiga or WINDOWS32 */ +#endif /* __MSDOS__ or Amiga or WINDOWS32 */ /* Bump the number of jobs started in this second. */ ++job_counter; @@ -1928,9 +1933,9 @@ start_waiting_job (struct child *c) if (!c->remote && ((job_slots_used > 0 && load_too_high ()) #ifdef WINDOWS32 - || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS) + || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS) #endif - )) + )) { /* Put this child on the chain of children waiting for the load average to go down. */ @@ -1999,101 +2004,101 @@ new_job (struct file *file) for (i = 0; i < cmds->ncommand_lines; ++i) { /* Collapse backslash-newline combinations that are inside variable - or function references. These are left alone by the parser so - that they will appear in the echoing of commands (where they look - nice); and collapsed by construct_command_argv when it tokenizes. - But letting them survive inside function invocations loses because - we don't want the functions to see them as part of the text. */ + or function references. These are left alone by the parser so + that they will appear in the echoing of commands (where they look + nice); and collapsed by construct_command_argv when it tokenizes. + But letting them survive inside function invocations loses because + we don't want the functions to see them as part of the text. */ char *in, *out, *ref; /* IN points to where in the line we are scanning. - OUT points to where in the line we are writing. - When we collapse a backslash-newline combination, - IN gets ahead of OUT. */ + OUT points to where in the line we are writing. + When we collapse a backslash-newline combination, + IN gets ahead of OUT. */ in = out = cmds->command_lines[i]; while ((ref = strchr (in, '$')) != 0) - { - ++ref; /* Move past the $. */ - - if (out != in) - /* Copy the text between the end of the last chunk - we processed (where IN points) and the new chunk - we are about to process (where REF points). */ - memmove (out, in, ref - in); - - /* Move both pointers past the boring stuff. */ - out += ref - in; - in = ref; - - if (*ref == '(' || *ref == '{') - { - char openparen = *ref; - char closeparen = openparen == '(' ? ')' : '}'; - int count; - char *p; - - *out++ = *in++; /* Copy OPENPAREN. */ - /* IN now points past the opening paren or brace. - Count parens or braces until it is matched. */ - count = 0; - while (*in != '\0') - { - if (*in == closeparen && --count < 0) - break; - else if (*in == '\\' && in[1] == '\n') - { - /* We have found a backslash-newline inside a - variable or function reference. Eat it and - any following whitespace. */ - - int quoted = 0; - for (p = in - 1; p > ref && *p == '\\'; --p) - quoted = !quoted; - - if (quoted) - /* There were two or more backslashes, so this is - not really a continuation line. We don't collapse - the quoting backslashes here as is done in - collapse_continuations, because the line will - be collapsed again after expansion. */ - *out++ = *in++; - else - { - /* Skip the backslash, newline and - any following whitespace. */ - in = next_token (in + 2); - - /* Discard any preceding whitespace that has - already been written to the output. */ - while (out > ref - && isblank ((unsigned char)out[-1])) - --out; - - /* Replace it all with a single space. */ - *out++ = ' '; - } - } - else - { - if (*in == openparen) - ++count; - - *out++ = *in++; - } - } - } - } + { + ++ref; /* Move past the $. */ + + if (out != in) + /* Copy the text between the end of the last chunk + we processed (where IN points) and the new chunk + we are about to process (where REF points). */ + memmove (out, in, ref - in); + + /* Move both pointers past the boring stuff. */ + out += ref - in; + in = ref; + + if (*ref == '(' || *ref == '{') + { + char openparen = *ref; + char closeparen = openparen == '(' ? ')' : '}'; + int count; + char *p; + + *out++ = *in++; /* Copy OPENPAREN. */ + /* IN now points past the opening paren or brace. + Count parens or braces until it is matched. */ + count = 0; + while (*in != '\0') + { + if (*in == closeparen && --count < 0) + break; + else if (*in == '\\' && in[1] == '\n') + { + /* We have found a backslash-newline inside a + variable or function reference. Eat it and + any following whitespace. */ + + int quoted = 0; + for (p = in - 1; p > ref && *p == '\\'; --p) + quoted = !quoted; + + if (quoted) + /* There were two or more backslashes, so this is + not really a continuation line. We don't collapse + the quoting backslashes here as is done in + collapse_continuations, because the line will + be collapsed again after expansion. */ + *out++ = *in++; + else + { + /* Skip the backslash, newline and + any following whitespace. */ + in = next_token (in + 2); + + /* Discard any preceding whitespace that has + already been written to the output. */ + while (out > ref + && isblank ((unsigned char)out[-1])) + --out; + + /* Replace it all with a single space. */ + *out++ = ' '; + } + } + else + { + if (*in == openparen) + ++count; + + *out++ = *in++; + } + } + } + } /* There are no more references in this line to worry about. - Copy the remaining uninteresting text to the output. */ + Copy the remaining uninteresting text to the output. */ if (out != in) - memmove (out, in, strlen (in) + 1); + memmove (out, in, strlen (in) + 1); /* Finally, expand the line. */ lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i], - file); + file); } /* Start the command sequence, record it in a new @@ -2133,16 +2138,16 @@ new_job (struct file *file) this is where the old parallel job code waits, so... */ #ifdef WINDOWS32 - else if (has_jobserver_semaphore()) + else if (has_jobserver_semaphore ()) #else else if (job_fds[0] >= 0) #endif while (1) { - int got_token; + int got_token; #ifndef WINDOWS32 char token; - int saved_errno; + int saved_errno; #endif DB (DB_JOBS, ("Need a job token; we %shave children\n", @@ -2204,23 +2209,23 @@ new_job (struct file *file) /* On Windows we simply wait for the jobserver semaphore to become * signalled or one of our child processes to terminate. */ - got_token = wait_for_semaphore_or_child_process(); + got_token = wait_for_semaphore_or_child_process (); if (got_token < 0) { - DWORD err = GetLastError(); + DWORD err = GetLastError (); fatal (NILF, _("semaphore or child process wait: (Error %ld: %s)"), - err, map_windows32_error_to_string(err)); + err, map_windows32_error_to_string (err)); } #else /* Set interruptible system calls, and read() for a job token. */ - set_child_handler_action_flags (1, waiting_jobs != NULL); - got_token = read (job_rfd, &token, 1); - saved_errno = errno; - set_child_handler_action_flags (0, waiting_jobs != NULL); + set_child_handler_action_flags (1, waiting_jobs != NULL); + got_token = read (job_rfd, &token, 1); + saved_errno = errno; + set_child_handler_action_flags (0, waiting_jobs != NULL); #endif /* If we got one, we're done here. */ - if (got_token == 1) + if (got_token == 1) { DB (DB_JOBS, (_("Obtained token for child %p (%s).\n"), c, c->file->name)); @@ -2230,7 +2235,7 @@ new_job (struct file *file) #ifndef WINDOWS32 /* If the error _wasn't_ expected (EINTR or EBADF), punt. Otherwise, go back and reap_children(), and try again. */ - errno = saved_errno; + errno = saved_errno; if (errno != EINTR && errno != EBADF) pfatal_with_name (_("read jobs pipe")); if (errno == EBADF) @@ -2290,14 +2295,14 @@ job_next_command (struct child *child) { /* There are no more lines in the expansion of this line. */ if (child->command_line == child->file->cmds->ncommand_lines) - { - /* There are no more lines to be expanded. */ - child->command_ptr = 0; - return 0; - } + { + /* There are no more lines to be expanded. */ + child->command_ptr = 0; + return 0; + } else - /* Get the next line to run. */ - child->command_ptr = child->command_lines[child->command_line++]; + /* Get the next line to run. */ + child->command_ptr = child->command_lines[child->command_line++]; } return 1; } @@ -2369,14 +2374,14 @@ load_too_high (void) static int lossage = -1; /* Complain only once for the same error. */ if (lossage == -1 || errno != lossage) - { - if (errno == 0) - /* An errno value of zero means getloadavg is just unsupported. */ - error (NILF, + { + if (errno == 0) + /* An errno value of zero means getloadavg is just unsupported. */ + error (NILF, _("cannot enforce load limits on this operating system")); - else - perror_with_name (_("cannot enforce load limit: "), "getloadavg"); - } + else + perror_with_name (_("cannot enforce load limit: "), "getloadavg"); + } lossage = errno; load = 0; } @@ -2426,7 +2431,7 @@ start_waiting_jobs (void) waiting_jobs = job->next; /* Try to start that job. We break out of the loop as soon - as start_waiting_job puts one back on the waiting list. */ + as start_waiting_job puts one back on the waiting list. */ } while (start_waiting_job (job) && waiting_jobs != 0); @@ -2547,57 +2552,56 @@ exec_command (char **argv, char **envp) int exit_code = EXIT_FAILURE; /* make sure CreateProcess() has Path it needs */ - sync_Path_environment(); + sync_Path_environment (); /* launch command */ - hPID = process_easy(argv, envp, -1, -1); + hPID = process_easy (argv, envp, -1, -1); /* make sure launch ok */ if (hPID == INVALID_HANDLE_VALUE) { int i; - fprintf(stderr, - _("process_easy() failed to launch process (e=%ld)\n"), - process_last_err(hPID)); + fprintf (stderr, _("process_easy() failed to launch process (e=%ld)\n"), + process_last_err (hPID)); for (i = 0; argv[i]; i++) - fprintf(stderr, "%s ", argv[i]); - fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); - exit(EXIT_FAILURE); + fprintf (stderr, "%s ", argv[i]); + fprintf (stderr, _("\nCounted %d args in failed launch\n"), i); + exit (EXIT_FAILURE); } /* wait and reap last child */ - hWaitPID = process_wait_for_any(1, 0); + hWaitPID = process_wait_for_any (1, 0); while (hWaitPID) { /* was an error found on this process? */ - err = process_last_err(hWaitPID); + err = process_last_err (hWaitPID); /* get exit data */ - exit_code = process_exit_code(hWaitPID); + exit_code = process_exit_code (hWaitPID); if (err) - fprintf(stderr, "make (e=%d, rc=%d): %s", - err, exit_code, map_windows32_error_to_string(err)); + fprintf (stderr, "make (e=%d, rc=%d): %s", + err, exit_code, map_windows32_error_to_string (err)); /* cleanup process */ - process_cleanup(hWaitPID); + process_cleanup (hWaitPID); /* expect to find only last pid, warn about other pids reaped */ if (hWaitPID == hPID) break; else - { - char *pidstr = xstrdup (pid2str ((pid_t)hWaitPID)); - - fprintf(stderr, - _("make reaped child pid %s, still waiting for pid %s\n"), - pidstr, pid2str ((pid_t)hPID)); - free (pidstr); - } + { + char *pidstr = xstrdup (pid2str ((pid_t)hWaitPID)); + + fprintf (stderr, + _("make reaped child pid %s, still waiting for pid %s\n"), + pidstr, pid2str ((pid_t)hPID)); + free (pidstr); + } } /* return child's exit code as our exit code */ - exit(exit_code); + exit (exit_code); #else /* !WINDOWS32 */ @@ -2635,37 +2639,37 @@ exec_command (char **argv, char **envp) break; case ENOEXEC: { - /* The file is not executable. Try it as a shell script. */ - extern char *getenv (); - char *shell; - char **new_argv; - int argc; + /* The file is not executable. Try it as a shell script. */ + extern char *getenv (); + char *shell; + char **new_argv; + int argc; int i=1; # ifdef __EMX__ /* Do not use $SHELL from the environment */ - struct variable *p = lookup_variable ("SHELL", 5); - if (p) - shell = p->value; + struct variable *p = lookup_variable ("SHELL", 5); + if (p) + shell = p->value; else shell = 0; # else - shell = getenv ("SHELL"); + shell = getenv ("SHELL"); # endif - if (shell == 0) - shell = default_shell; + if (shell == 0) + shell = default_shell; - argc = 1; - while (argv[argc] != 0) - ++argc; + argc = 1; + while (argv[argc] != 0) + ++argc; # ifdef __EMX__ if (!unixy_shell) ++argc; # endif - new_argv = alloca ((1 + argc + 1) * sizeof (char *)); - new_argv[0] = shell; + new_argv = alloca ((1 + argc + 1) * sizeof (char *)); + new_argv[0] = shell; # ifdef __EMX__ if (!unixy_shell) @@ -2677,24 +2681,24 @@ exec_command (char **argv, char **envp) # endif new_argv[i] = argv[0]; - while (argc > 0) - { - new_argv[i + argc] = argv[argc]; - --argc; - } + while (argc > 0) + { + new_argv[i + argc] = argv[argc]; + --argc; + } # ifdef __EMX__ - pid = spawnvpe (P_NOWAIT, shell, new_argv, envp); - if (pid >= 0) + pid = spawnvpe (P_NOWAIT, shell, new_argv, envp); + if (pid >= 0) break; # else - execvp (shell, new_argv); + execvp (shell, new_argv); # endif - if (errno == ENOENT) - error (NILF, _("%s: Shell program not found"), shell); - else - perror_with_name ("execvp: ", shell); - break; + if (errno == ENOENT) + error (NILF, _("%s: Shell program not found"), shell); + else + perror_with_name ("execvp: ", shell); + break; } # ifdef __EMX__ @@ -2779,19 +2783,19 @@ construct_command_argv_internal (char *line, char **restp, char *shell, commands and special characters. */ static char sh_chars_dos[] = "*?[];|<>%^&()"; static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", - "copy", "ctty", "date", "del", "dir", "echo", - "erase", "exit", "for", "goto", "if", "md", - "mkdir", "path", "pause", "prompt", "rd", - "rmdir", "rem", "ren", "rename", "set", - "shift", "time", "type", "ver", "verify", - "vol", ":", 0 }; + "copy", "ctty", "date", "del", "dir", "echo", + "erase", "exit", "for", "goto", "if", "md", + "mkdir", "path", "pause", "prompt", "rd", + "rmdir", "rem", "ren", "rename", "set", + "shift", "time", "type", "ver", "verify", + "vol", ":", 0 }; static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; static char *sh_cmds_sh[] = { "cd", "echo", "eval", "exec", "exit", "login", - "logout", "set", "umask", "wait", "while", - "for", "case", "if", ":", ".", "break", - "continue", "export", "read", "readonly", - "shift", "times", "trap", "switch", "unset", + "logout", "set", "umask", "wait", "while", + "for", "case", "if", ":", ".", "break", + "continue", "export", "read", "readonly", + "shift", "times", "trap", "switch", "unset", "ulimit", 0 }; char *sh_chars; @@ -2799,28 +2803,28 @@ construct_command_argv_internal (char *line, char **restp, char *shell, #elif defined (__EMX__) static char sh_chars_dos[] = "*?[];|<>%^&()"; static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", - "copy", "ctty", "date", "del", "dir", "echo", - "erase", "exit", "for", "goto", "if", "md", - "mkdir", "path", "pause", "prompt", "rd", - "rmdir", "rem", "ren", "rename", "set", - "shift", "time", "type", "ver", "verify", - "vol", ":", 0 }; + "copy", "ctty", "date", "del", "dir", "echo", + "erase", "exit", "for", "goto", "if", "md", + "mkdir", "path", "pause", "prompt", "rd", + "rmdir", "rem", "ren", "rename", "set", + "shift", "time", "type", "ver", "verify", + "vol", ":", 0 }; static char sh_chars_os2[] = "*?[];|<>%^()\"'&"; static char *sh_cmds_os2[] = { "call", "cd", "chcp", "chdir", "cls", "copy", - "date", "del", "detach", "dir", "echo", - "endlocal", "erase", "exit", "for", "goto", "if", - "keys", "md", "mkdir", "move", "path", "pause", - "prompt", "rd", "rem", "ren", "rename", "rmdir", - "set", "setlocal", "shift", "start", "time", + "date", "del", "detach", "dir", "echo", + "endlocal", "erase", "exit", "for", "goto", "if", + "keys", "md", "mkdir", "move", "path", "pause", + "prompt", "rd", "rem", "ren", "rename", "rmdir", + "set", "setlocal", "shift", "start", "time", "type", "ver", "verify", "vol", ":", 0 }; static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^~'"; static char *sh_cmds_sh[] = { "echo", "cd", "eval", "exec", "exit", "login", - "logout", "set", "umask", "wait", "while", - "for", "case", "if", ":", ".", "break", - "continue", "export", "read", "readonly", - "shift", "times", "trap", "switch", "unset", + "logout", "set", "umask", "wait", "while", + "for", "case", "if", ":", ".", "break", + "continue", "export", "read", "readonly", + "shift", "times", "trap", "switch", "unset", 0 }; char *sh_chars; char **sh_cmds; @@ -2828,10 +2832,10 @@ construct_command_argv_internal (char *line, char **restp, char *shell, #elif defined (_AMIGA) static char sh_chars[] = "#;\"|<>()?*$`"; static char *sh_cmds[] = { "cd", "eval", "if", "delete", "echo", "copy", - "rename", "set", "setenv", "date", "makedir", - "skip", "else", "endif", "path", "prompt", - "unset", "unsetenv", "version", - 0 }; + "rename", "set", "setenv", "date", "makedir", + "skip", "else", "endif", "path", "prompt", + "unset", "unsetenv", "version", + 0 }; #elif defined (WINDOWS32) /* We used to have a double quote (") in sh_chars_dos[] below, but that caused any command line with quoted file names be run @@ -2842,20 +2846,20 @@ construct_command_argv_internal (char *line, char **restp, char *shell, file names is commonplace on MS-Windows. */ static char sh_chars_dos[] = "|&<>"; static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp", - "chdir", "cls", "color", "copy", "ctty", - "date", "del", "dir", "echo", "echo.", - "endlocal", "erase", "exit", "for", "ftype", - "goto", "if", "if", "md", "mkdir", "path", - "pause", "prompt", "rd", "rem", "ren", - "rename", "rmdir", "set", "setlocal", - "shift", "time", "title", "type", "ver", - "verify", "vol", ":", 0 }; + "chdir", "cls", "color", "copy", "ctty", + "date", "del", "dir", "echo", "echo.", + "endlocal", "erase", "exit", "for", "ftype", + "goto", "if", "if", "md", "mkdir", "path", + "pause", "prompt", "rd", "rem", "ren", + "rename", "rmdir", "set", "setlocal", + "shift", "time", "title", "type", "ver", + "verify", "vol", ":", 0 }; static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; static char *sh_cmds_sh[] = { "cd", "eval", "exec", "exit", "login", - "logout", "set", "umask", "wait", "while", "for", - "case", "if", ":", ".", "break", "continue", - "export", "read", "readonly", "shift", "times", - "trap", "switch", "test", + "logout", "set", "umask", "wait", "while", "for", + "case", "if", ":", ".", "break", "continue", + "export", "read", "readonly", "shift", "times", + "trap", "switch", "test", #ifdef BATCH_MODE_ONLY_SHELL "echo", #endif @@ -2877,7 +2881,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, WINDOWS32) are compiled with HAVE_DOS_PATHS defined, which uses sh_chars_sh[] directly (see below). */ static char *sh_chars_sh = sh_chars; -# endif /* HAVE_DOS_PATHS */ +# endif /* HAVE_DOS_PATHS */ #endif int i; char *p; @@ -2889,13 +2893,16 @@ construct_command_argv_internal (char *line, char **restp, char *shell, #ifdef WINDOWS32 int slow_flag = 0; - if (!unixy_shell) { - sh_cmds = sh_cmds_dos; - sh_chars = sh_chars_dos; - } else { - sh_cmds = sh_cmds_sh; - sh_chars = sh_chars_sh; - } + if (!unixy_shell) + { + sh_cmds = sh_cmds_dos; + sh_chars = sh_chars_dos; + } + else + { + sh_cmds = sh_cmds_sh; + sh_chars = sh_chars_sh; + } #endif /* WINDOWS32 */ if (restp != NULL) @@ -2967,7 +2974,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, if (ifs != 0) for (ap = ifs; *ap != '\0'; ++ap) if (*ap != ' ' && *ap != '\t' && *ap != '\n') - goto slow; + goto slow; if (shellflags != 0) if (shellflags[0] != '-' @@ -2992,16 +2999,16 @@ construct_command_argv_internal (char *line, char **restp, char *shell, assert (ap <= end); if (instring) - { - /* Inside a string, just copy any char except a closing quote - or a backslash-newline combination. */ - if (*p == instring) - { - instring = 0; - if (ap == new_argv[0] || *(ap-1) == '\0') - last_argument_was_empty = 1; - } - else if (*p == '\\' && p[1] == '\n') + { + /* Inside a string, just copy any char except a closing quote + or a backslash-newline combination. */ + if (*p == instring) + { + instring = 0; + if (ap == new_argv[0] || *(ap-1) == '\0') + last_argument_was_empty = 1; + } + else if (*p == '\\' && p[1] == '\n') { /* Backslash-newline is handled differently depending on what kind of string we're in: inside single-quoted strings you @@ -3010,9 +3017,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell, pre-POSIX behavior of removing the backslash-newline. */ if (instring == '"' #if defined (__MSDOS__) || defined (__EMX__) || defined (WINDOWS32) - || !unixy_shell + || !unixy_shell #endif - ) + ) ++p; else { @@ -3020,74 +3027,74 @@ construct_command_argv_internal (char *line, char **restp, char *shell, *(ap++) = *p; } } - else if (*p == '\n' && restp != NULL) - { - /* End of the command line. */ - *restp = p; - goto end_of_line; - } - /* Backslash, $, and ` are special inside double quotes. - If we see any of those, punt. - But on MSDOS, if we use COMMAND.COM, double and single - quotes have the same effect. */ - else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell) - goto slow; + else if (*p == '\n' && restp != NULL) + { + /* End of the command line. */ + *restp = p; + goto end_of_line; + } + /* Backslash, $, and ` are special inside double quotes. + If we see any of those, punt. + But on MSDOS, if we use COMMAND.COM, double and single + quotes have the same effect. */ + else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell) + goto slow; #ifdef WINDOWS32 - else if (instring == '"' && strncmp (p, "\\\"", 2) == 0) - *ap++ = *++p; + else if (instring == '"' && strncmp (p, "\\\"", 2) == 0) + *ap++ = *++p; #endif - else - *ap++ = *p; - } + else + *ap++ = *p; + } else if (strchr (sh_chars, *p) != 0) - /* Not inside a string, but it's a special char. */ - goto slow; + /* Not inside a string, but it's a special char. */ + goto slow; else if (one_shell && *p == '\n') - /* In .ONESHELL mode \n is a separator like ; or && */ - goto slow; + /* In .ONESHELL mode \n is a separator like ; or && */ + goto slow; #ifdef __MSDOS__ else if (*p == '.' && p[1] == '.' && p[2] == '.' && p[3] != '.') - /* '...' is a wildcard in DJGPP. */ - goto slow; + /* '...' is a wildcard in DJGPP. */ + goto slow; #endif else - /* Not a special char. */ - switch (*p) - { - case '=': - /* Equals is a special character in leading words before the - first word with no equals sign in it. This is not the case - with sh -k, but we never get here when using nonstandard - shell flags. */ - if (! seen_nonequals && unixy_shell) - goto slow; - word_has_equals = 1; - *ap++ = '='; - break; - - case '\\': - /* Backslash-newline has special case handling, ref POSIX. + /* Not a special char. */ + switch (*p) + { + case '=': + /* Equals is a special character in leading words before the + first word with no equals sign in it. This is not the case + with sh -k, but we never get here when using nonstandard + shell flags. */ + if (! seen_nonequals && unixy_shell) + goto slow; + word_has_equals = 1; + *ap++ = '='; + break; + + case '\\': + /* Backslash-newline has special case handling, ref POSIX. We're in the fastpath, so emulate what the shell would do. */ - if (p[1] == '\n') - { - /* Throw out the backslash and newline. */ + if (p[1] == '\n') + { + /* Throw out the backslash and newline. */ ++p; /* If there's nothing in this argument yet, skip any whitespace before the start of the next word. */ if (ap == new_argv[i]) p = next_token (p + 1) - 1; - } + } #ifdef WINDOWS32 - /* Backslash before whitespace is not special if our shell - is not Unixy. */ - else if (isspace (p[1]) && !unixy_shell) - { - *ap++ = *p; - break; - } -#endif - else if (p[1] != '\0') + /* Backslash before whitespace is not special if our shell + is not Unixy. */ + else if (isspace (p[1]) && !unixy_shell) + { + *ap++ = *p; + break; + } +#endif + else if (p[1] != '\0') { #ifdef HAVE_DOS_PATHS /* Only remove backslashes before characters special to Unixy @@ -3117,49 +3124,49 @@ construct_command_argv_internal (char *line, char **restp, char *shell, /* Copy and skip the following char. */ *ap++ = *++p; } - break; - - case '\'': - case '"': - instring = *p; - break; - - case '\n': - if (restp != NULL) - { - /* End of the command line. */ - *restp = p; - goto end_of_line; - } - else - /* Newlines are not special. */ - *ap++ = '\n'; - break; - - case ' ': - case '\t': - /* We have the end of an argument. - Terminate the text of the argument. */ - *ap++ = '\0'; - new_argv[++i] = ap; - last_argument_was_empty = 0; - - /* Update SEEN_NONEQUALS, which tells us if every word - heretofore has contained an '='. */ - seen_nonequals |= ! word_has_equals; - if (word_has_equals && ! seen_nonequals) - /* An '=' in a word before the first - word without one is magical. */ - goto slow; - word_has_equals = 0; /* Prepare for the next word. */ - - /* If this argument is the command name, - see if it is a built-in shell command. - If so, have the shell handle it. */ - if (i == 1) - { - register int j; - for (j = 0; sh_cmds[j] != 0; ++j) + break; + + case '\'': + case '"': + instring = *p; + break; + + case '\n': + if (restp != NULL) + { + /* End of the command line. */ + *restp = p; + goto end_of_line; + } + else + /* Newlines are not special. */ + *ap++ = '\n'; + break; + + case ' ': + case '\t': + /* We have the end of an argument. + Terminate the text of the argument. */ + *ap++ = '\0'; + new_argv[++i] = ap; + last_argument_was_empty = 0; + + /* Update SEEN_NONEQUALS, which tells us if every word + heretofore has contained an '='. */ + seen_nonequals |= ! word_has_equals; + if (word_has_equals && ! seen_nonequals) + /* An '=' in a word before the first + word without one is magical. */ + goto slow; + word_has_equals = 0; /* Prepare for the next word. */ + + /* If this argument is the command name, + see if it is a built-in shell command. + If so, have the shell handle it. */ + if (i == 1) + { + register int j; + for (j = 0; sh_cmds[j] != 0; ++j) { if (streq (sh_cmds[j], new_argv[0])) goto slow; @@ -3170,16 +3177,16 @@ construct_command_argv_internal (char *line, char **restp, char *shell, goto slow; # endif } - } + } - /* Ignore multiple whitespace chars. */ - p = next_token (p) - 1; - break; + /* Ignore multiple whitespace chars. */ + p = next_token (p) - 1; + break; - default: - *ap++ = *p; - break; - } + default: + *ap++ = *p; + break; + } } end_of_line: @@ -3198,8 +3205,8 @@ 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; } if (new_argv[0] == 0) @@ -3223,7 +3230,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, } #ifdef __MSDOS__ - execute_by_shell = 1; /* actually, call 'system' if shell isn't unixy */ + execute_by_shell = 1; /* actually, call 'system' if shell isn't unixy */ #endif #ifdef _AMIGA @@ -3238,14 +3245,14 @@ construct_command_argv_internal (char *line, char **restp, char *shell, for (dptr=buffer; *ptr; ) { if (*ptr == '\\' && ptr[1] == '\n') - ptr += 2; + ptr += 2; else if (*ptr == '@') /* Kludge: multiline commands */ { - ptr += 2; - *dptr++ = '\n'; + ptr += 2; + *dptr++ = '\n'; } else - *dptr++ = *ptr++; + *dptr++ = *ptr++; } *dptr = 0; @@ -3253,7 +3260,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, new_argv[0] = buffer; new_argv[1] = 0; } -#else /* Not Amiga */ +#else /* Not Amiga */ #ifdef WINDOWS32 /* * Not eating this whitespace caused things like @@ -3290,30 +3297,30 @@ construct_command_argv_internal (char *line, char **restp, char *shell, # endif /* In .ONESHELL mode we are allowed to throw the entire current - recipe string at a single shell and trust that the user - has configured the shell and shell flags, and formatted - the string, appropriately. */ + recipe string at a single shell and trust that the user + has configured the shell and shell flags, and formatted + the string, appropriately. */ if (one_shell) { - /* If the shell is Bourne compatible, we must remove and ignore - interior special chars [@+-] because they're meaningless to - the shell itself. If, however, we're in .ONESHELL mode and - have changed SHELL to something non-standard, we should - leave those alone because they could be part of the - script. In this case we must also leave in place - any leading [@+-] for the same reason. */ - - /* Remove and ignore interior prefix chars [@+-] because they're - meaningless given a single shell. */ + /* If the shell is Bourne compatible, we must remove and ignore + interior special chars [@+-] because they're meaningless to + the shell itself. If, however, we're in .ONESHELL mode and + have changed SHELL to something non-standard, we should + leave those alone because they could be part of the + script. In this case we must also leave in place + any leading [@+-] for the same reason. */ + + /* Remove and ignore interior prefix chars [@+-] because they're + meaningless given a single shell. */ #if defined __MSDOS__ || defined (__EMX__) - if (unixy_shell) /* the test is complicated and we already did it */ + if (unixy_shell) /* the test is complicated and we already did it */ #else - if (is_bourne_compatible_shell(shell) + if (is_bourne_compatible_shell (shell) #ifdef WINDOWS32 - /* If we didn't find any sh.exe, don't behave is if we did! */ - && !no_default_sh_exe + /* If we didn't find any sh.exe, don't behave is if we did! */ + && !no_default_sh_exe #endif - ) + ) #endif { const char *f = line; @@ -3350,28 +3357,28 @@ construct_command_argv_internal (char *line, char **restp, char *shell, *t = '\0'; } #ifdef WINDOWS32 - else /* non-Posix shell (cmd.exe etc.) */ - { + else /* non-Posix shell (cmd.exe etc.) */ + { const char *f = line; char *t = line; - char *tstart = t; - int temp_fd; - FILE* batch = NULL; - int id = GetCurrentProcessId(); - PATH_VAR(fbuf); - - /* Generate a file name for the temporary batch file. */ - sprintf(fbuf, "make%d", id); - *batch_filename = create_batch_file (fbuf, 0, &temp_fd); - DB (DB_JOBS, (_("Creating temporary batch file %s\n"), - *batch_filename)); - - /* Create a FILE object for the batch file, and write to it the - commands to be executed. Put the batch file in TEXT mode. */ - _setmode (temp_fd, _O_TEXT); - batch = _fdopen (temp_fd, "wt"); - fputs ("@echo off\n", batch); - DB (DB_JOBS, (_("Batch file contents:\n\t@echo off\n"))); + char *tstart = t; + int temp_fd; + FILE* batch = NULL; + int id = GetCurrentProcessId (); + PATH_VAR(fbuf); + + /* Generate a file name for the temporary batch file. */ + sprintf (fbuf, "make%d", id); + *batch_filename = create_batch_file (fbuf, 0, &temp_fd); + DB (DB_JOBS, (_("Creating temporary batch file %s\n"), + *batch_filename)); + + /* Create a FILE object for the batch file, and write to it the + commands to be executed. Put the batch file in TEXT mode. */ + _setmode (temp_fd, _O_TEXT); + batch = _fdopen (temp_fd, "wt"); + fputs ("@echo off\n", batch); + DB (DB_JOBS, (_("Batch file contents:\n\t@echo off\n"))); /* Copy the recipe, removing and ignoring interior prefix chars [@+-]: they're meaningless in .ONESHELL mode. */ @@ -3385,42 +3392,42 @@ construct_command_argv_internal (char *line, char **restp, char *shell, /* Copy until we get to the next logical recipe line. */ while (*f != '\0') { - /* Remove the escaped newlines in the command, and - the whitespace that follows them. Windows - shells cannot handle escaped newlines. */ - if (*f == '\\' && f[1] == '\n') - { - f += 2; - while (isblank (*f)) - ++f; - } + /* Remove the escaped newlines in the command, and + the whitespace that follows them. Windows + shells cannot handle escaped newlines. */ + if (*f == '\\' && f[1] == '\n') + { + f += 2; + while (isblank (*f)) + ++f; + } *(t++) = *(f++); - /* On an unescaped newline, we're done with this - line. */ - if (f[-1] == '\n') - break; + /* On an unescaped newline, we're done with this + line. */ + if (f[-1] == '\n') + break; } - /* Write another line into the batch file. */ - if (t > tstart) - { - int c = *t; - *t = '\0'; - fputs (tstart, batch); - DB (DB_JOBS, ("\t%s", tstart)); - tstart = t; - *t = c; - } - } - DB (DB_JOBS, ("\n")); - fclose (batch); - - /* Create an argv list for the shell command line that - will run the batch file. */ - new_argv = xmalloc (2 * sizeof (char *)); - new_argv[0] = xstrdup (*batch_filename); - new_argv[1] = NULL; - return new_argv; - } + /* Write another line into the batch file. */ + if (t > tstart) + { + int c = *t; + *t = '\0'; + fputs (tstart, batch); + DB (DB_JOBS, ("\t%s", tstart)); + tstart = t; + *t = c; + } + } + DB (DB_JOBS, ("\n")); + fclose (batch); + + /* Create an argv list for the shell command line that + will run the batch file. */ + new_argv = xmalloc (2 * sizeof (char *)); + new_argv[0] = xstrdup (*batch_filename); + new_argv[1] = NULL; + return new_argv; + } #endif /* WINDOWS32 */ /* Create an argv list for the shell command line. */ { @@ -3457,9 +3464,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell, whichever happens first. */ for (p = shell; *p != '\0'; ++p) { - if (strchr (sh_chars, *p) != 0) - *(ap++) = '\\'; - *(ap++) = *p; + if (strchr (sh_chars, *p) != 0) + *(ap++) = '\\'; + *(ap++) = *p; } *(ap++) = ' '; if (shellflags) @@ -3469,14 +3476,14 @@ construct_command_argv_internal (char *line, char **restp, char *shell, command_ptr = ap; for (p = line; *p != '\0'; ++p) { - if (restp != NULL && *p == '\n') - { - *restp = p; - break; - } - else if (*p == '\\' && p[1] == '\n') - { - /* POSIX says we keep the backslash-newline. If we don't have a + if (restp != NULL && *p == '\n') + { + *restp = p; + break; + } + else if (*p == '\\' && p[1] == '\n') + { + /* POSIX says we keep the backslash-newline. If we don't have a POSIX shell on DOS/Windows/OS2, mimic the pre-POSIX behavior and remove the backslash/newline. */ #if defined (__MSDOS__) || defined (__EMX__) || defined (WINDOWS32) @@ -3484,26 +3491,26 @@ construct_command_argv_internal (char *line, char **restp, char *shell, #else # define PRESERVE_BSNL 1 #endif - if (PRESERVE_BSNL) - { - *(ap++) = '\\'; - /* Only non-batch execution needs another backslash, - because it will be passed through a recursive - invocation of this function. */ - if (!batch_mode_shell) - *(ap++) = '\\'; - *(ap++) = '\n'; - } - ++p; - continue; - } + if (PRESERVE_BSNL) + { + *(ap++) = '\\'; + /* Only non-batch execution needs another backslash, + because it will be passed through a recursive + invocation of this function. */ + if (!batch_mode_shell) + *(ap++) = '\\'; + *(ap++) = '\n'; + } + ++p; + continue; + } /* DOS shells don't know about backslash-escaping. */ - if (unixy_shell && !batch_mode_shell && + if (unixy_shell && !batch_mode_shell && (*p == '\\' || *p == '\'' || *p == '"' || isspace ((unsigned char)*p) || strchr (sh_chars, *p) != 0)) - *ap++ = '\\'; + *ap++ = '\\'; #ifdef __MSDOS__ else if (unixy_shell && strneq (p, "...", 3)) { @@ -3513,7 +3520,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, p += 2; } #endif - *ap++ = *p; + *ap++ = *p; } if (ap == new_line + shell_len + sflags_len + 2) { @@ -3527,48 +3534,55 @@ construct_command_argv_internal (char *line, char **restp, char *shell, /* Some shells do not work well when invoked as 'sh -c xxx' to run a command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems). In these cases, run commands via a script file. */ - if (just_print_flag && !(flags & COMMANDS_RECURSE)) { - /* Need to allocate new_argv, although it's unused, because - start_job_command will want to free it and its 0'th element. */ - new_argv = xmalloc(2 * sizeof (char *)); - new_argv[0] = xstrdup (""); - new_argv[1] = NULL; - } else if ((no_default_sh_exe || batch_mode_shell) && batch_filename) { - int temp_fd; - FILE* batch = NULL; - int id = GetCurrentProcessId(); - PATH_VAR(fbuf); - - /* create a file name */ - sprintf(fbuf, "make%d", id); - *batch_filename = create_batch_file (fbuf, unixy_shell, &temp_fd); - - DB (DB_JOBS, (_("Creating temporary batch file %s\n"), - *batch_filename)); - - /* Create a FILE object for the batch file, and write to it the - commands to be executed. Put the batch file in TEXT mode. */ - _setmode (temp_fd, _O_TEXT); - batch = _fdopen (temp_fd, "wt"); - if (!unixy_shell) - fputs ("@echo off\n", batch); - fputs (command_ptr, batch); - fputc ('\n', batch); - fclose (batch); - DB (DB_JOBS, (_("Batch file contents:%s\n\t%s\n"), - !unixy_shell ? "\n\t@echo off" : "", command_ptr)); - - /* create argv */ - new_argv = xmalloc(3 * sizeof (char *)); - if (unixy_shell) { - new_argv[0] = xstrdup (shell); - new_argv[1] = *batch_filename; /* only argv[0] gets freed later */ - } else { - new_argv[0] = xstrdup (*batch_filename); + if (just_print_flag && !(flags & COMMANDS_RECURSE)) + { + /* Need to allocate new_argv, although it's unused, because + start_job_command will want to free it and its 0'th element. */ + new_argv = xmalloc (2 * sizeof (char *)); + new_argv[0] = xstrdup (""); new_argv[1] = NULL; } - new_argv[2] = NULL; - } else + else if ((no_default_sh_exe || batch_mode_shell) && batch_filename) + { + int temp_fd; + FILE* batch = NULL; + int id = GetCurrentProcessId (); + PATH_VAR (fbuf); + + /* create a file name */ + sprintf (fbuf, "make%d", id); + *batch_filename = create_batch_file (fbuf, unixy_shell, &temp_fd); + + DB (DB_JOBS, (_("Creating temporary batch file %s\n"), + *batch_filename)); + + /* Create a FILE object for the batch file, and write to it the + commands to be executed. Put the batch file in TEXT mode. */ + _setmode (temp_fd, _O_TEXT); + batch = _fdopen (temp_fd, "wt"); + if (!unixy_shell) + fputs ("@echo off\n", batch); + fputs (command_ptr, batch); + fputc ('\n', batch); + fclose (batch); + DB (DB_JOBS, (_("Batch file contents:%s\n\t%s\n"), + !unixy_shell ? "\n\t@echo off" : "", command_ptr)); + + /* create argv */ + new_argv = xmalloc (3 * sizeof (char *)); + if (unixy_shell) + { + new_argv[0] = xstrdup (shell); + new_argv[1] = *batch_filename; /* only argv[0] gets freed later */ + } + else + { + new_argv[0] = xstrdup (*batch_filename); + new_argv[1] = NULL; + } + new_argv[2] = NULL; + } + else #endif /* WINDOWS32 */ if (unixy_shell) @@ -3578,7 +3592,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, #ifdef __EMX__ else if (!unixy_shell) { - /* new_line is local, must not be freed therefore + /* 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); @@ -3664,7 +3678,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell, free (new_line); } -#endif /* ! AMIGA */ +#endif /* ! AMIGA */ return new_argv; } @@ -3699,13 +3713,13 @@ construct_command_argv (char *line, char **restp, struct file *file, for (;;) { while ((*cptr != 0) - && (isspace ((unsigned char)*cptr))) - cptr++; + && (isspace ((unsigned char)*cptr))) + cptr++; if (*cptr == 0) - break; + break; while ((*cptr != 0) - && (!isspace((unsigned char)*cptr))) - cptr++; + && (!isspace ((unsigned char)*cptr))) + cptr++; argc++; } @@ -3718,17 +3732,17 @@ construct_command_argv (char *line, char **restp, struct file *file, for (;;) { while ((*cptr != 0) - && (isspace ((unsigned char)*cptr))) - cptr++; + && (isspace ((unsigned char)*cptr))) + cptr++; if (*cptr == 0) - break; + break; DB (DB_JOBS, ("argv[%d] = [%s]\n", argc, cptr)); argv[argc++] = cptr; while ((*cptr != 0) - && (!isspace((unsigned char)*cptr))) - cptr++; + && (!isspace ((unsigned char)*cptr))) + cptr++; if (*cptr != 0) - *cptr++ = 0; + *cptr++ = 0; } #else { @@ -3742,10 +3756,11 @@ construct_command_argv (char *line, char **restp, struct file *file, * Convert to forward slashes so that construct_command_argv_internal() * is not confused. */ - if (shell) { - char *p = w32ify (shell, 0); - strcpy (shell, p); - } + if (shell) + { + char *p = w32ify (shell, 0); + strcpy (shell, p); + } #endif #ifdef __EMX__ { @@ -3753,12 +3768,12 @@ construct_command_argv (char *line, char **restp, struct file *file, static const char *last_shell = ""; static int init = 0; if (init == 0) - { - unixroot = getenv ("UNIXROOT"); - /* unixroot must be NULL or not empty */ - if (unixroot && unixroot[0] == '\0') unixroot = NULL; - init = 1; - } + { + unixroot = getenv ("UNIXROOT"); + /* unixroot must be NULL or not empty */ + if (unixroot && unixroot[0] == '\0') unixroot = NULL; + init = 1; + } /* if we have an unixroot drive and if shell is not default_shell (which means it's either cmd.exe or the test has already been @@ -3766,29 +3781,29 @@ construct_command_argv (char *line, char **restp, struct file *file, try whether it exists e.g.: if "/bin/sh" does not exist use "$UNIXROOT/bin/sh" instead. */ if (unixroot && shell && strcmp (shell, last_shell) != 0 - && (shell[0] == '/' || shell[0] == '\\')) - { - /* trying a new shell, check whether it exists */ - size_t size = strlen (shell); - char *buf = xmalloc (size + 7); - memcpy (buf, shell, size); - memcpy (buf + size, ".exe", 5); /* including the trailing '\0' */ + && (shell[0] == '/' || shell[0] == '\\')) + { + /* trying a new shell, check whether it exists */ + size_t size = strlen (shell); + char *buf = xmalloc (size + 7); + memcpy (buf, shell, size); + memcpy (buf + size, ".exe", 5); /* including the trailing '\0' */ if (access (shell, F_OK) != 0 && access (buf, F_OK) != 0) - { - /* try the same for the unixroot drive */ - memmove (buf + 2, buf, size + 5); - buf[0] = unixroot[0]; - buf[1] = unixroot[1]; - if (access (buf, F_OK) == 0) - /* we have found a shell! */ - /* free(shell); */ - shell = buf; - else - free (buf); - } - else + { + /* try the same for the unixroot drive */ + memmove (buf + 2, buf, size + 5); + buf[0] = unixroot[0]; + buf[1] = unixroot[1]; + if (access (buf, F_OK) == 0) + /* we have found a shell! */ + /* free(shell); */ + shell = buf; + else + free (buf); + } + else free (buf); - } + } } #endif /* __EMX__ */ |