Mention amiga port
[make.git] / job.c
blob098beeef591a33df9fb667bce5adaafc6ffac6e1
1 /* Job execution and handling for GNU Make.
2 Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96
3 Free Software Foundation, Inc.
4 This file is part of GNU Make.
6 GNU Make is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Make is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Make; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #include "make.h"
21 #include "job.h"
22 #include "filedef.h"
23 #include "commands.h"
24 #include "variable.h"
25 #include <assert.h>
27 /* Default shell to use. */
28 #ifndef _AMIGA
29 char default_shell[] = "/bin/sh";
30 #else
31 char default_shell[] = "";
32 extern int MyExecute (char **);
33 #endif
35 #ifdef __MSDOS__
36 #include <process.h>
37 static int dos_pid = 123;
38 static int dos_status;
39 static char *dos_bname;
40 static char *dos_bename;
41 static int dos_batch_file;
42 #endif /* MSDOS. */
43 #ifdef _AMIGA
44 #include <proto/dos.h>
45 static int amiga_pid = 123;
46 static int amiga_status;
47 static char amiga_bname[32];
48 static int amiga_batch_file;
49 #endif /* Amiga. */
51 #ifdef VMS
52 #include <time.h>
53 #include <processes.h>
54 #include <starlet.h>
55 #include <lib$routines.h>
56 #endif
58 #ifdef HAVE_FCNTL_H
59 #include <fcntl.h>
60 #else
61 #include <sys/file.h>
62 #endif
64 #if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT)
65 #include <sys/wait.h>
66 #endif
68 #ifdef HAVE_WAITPID
69 #define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG)
70 #else /* Don't have waitpid. */
71 #ifdef HAVE_WAIT3
72 #ifndef wait3
73 extern int wait3 ();
74 #endif
75 #define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0)
76 #endif /* Have wait3. */
77 #endif /* Have waitpid. */
79 #if !defined (wait) && !defined (POSIX)
80 extern int wait ();
81 #endif
83 #ifndef HAVE_UNION_WAIT
85 #define WAIT_T int
87 #ifndef WTERMSIG
88 #define WTERMSIG(x) ((x) & 0x7f)
89 #endif
90 #ifndef WCOREDUMP
91 #define WCOREDUMP(x) ((x) & 0x80)
92 #endif
93 #ifndef WEXITSTATUS
94 #define WEXITSTATUS(x) (((x) >> 8) & 0xff)
95 #endif
96 #ifndef WIFSIGNALED
97 #define WIFSIGNALED(x) (WTERMSIG (x) != 0)
98 #endif
99 #ifndef WIFEXITED
100 #define WIFEXITED(x) (WTERMSIG (x) == 0)
101 #endif
103 #else /* Have `union wait'. */
105 #define WAIT_T union wait
106 #ifndef WTERMSIG
107 #define WTERMSIG(x) ((x).w_termsig)
108 #endif
109 #ifndef WCOREDUMP
110 #define WCOREDUMP(x) ((x).w_coredump)
111 #endif
112 #ifndef WEXITSTATUS
113 #define WEXITSTATUS(x) ((x).w_retcode)
114 #endif
115 #ifndef WIFSIGNALED
116 #define WIFSIGNALED(x) (WTERMSIG(x) != 0)
117 #endif
118 #ifndef WIFEXITED
119 #define WIFEXITED(x) (WTERMSIG(x) == 0)
120 #endif
122 #endif /* Don't have `union wait'. */
124 #ifdef VMS
125 static int vms_jobsefnmask=0;
126 #endif /* !VMS */
128 #ifndef HAVE_UNISTD_H
129 extern int dup2 ();
130 extern int execve ();
131 extern void _exit ();
132 #ifndef VMS
133 extern int geteuid ();
134 extern int getegid ();
135 extern int setgid ();
136 extern int getgid ();
137 #endif
138 #endif
140 extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file));
142 extern int getloadavg PARAMS ((double loadavg[], int nelem));
143 extern int start_remote_job PARAMS ((char **argv, char **envp, int stdin_fd,
144 int *is_remote, int *id_ptr, int *used_stdin));
145 extern int start_remote_job_p PARAMS ((void));
146 extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr,
147 int *coredump_ptr, int block));
149 RETSIGTYPE child_handler PARAMS ((int));
150 static void free_child PARAMS ((struct child *));
151 static void start_job_command PARAMS ((struct child *child));
152 static int load_too_high PARAMS ((void));
153 static int job_next_command PARAMS ((struct child *));
154 static int start_waiting_job PARAMS ((struct child *));
155 #ifdef VMS
156 static void vmsWaitForChildren PARAMS ((int *));
157 #endif
159 /* Chain of all live (or recently deceased) children. */
161 struct child *children = 0;
163 /* Number of children currently running. */
165 unsigned int job_slots_used = 0;
167 /* Nonzero if the `good' standard input is in use. */
169 static int good_stdin_used = 0;
171 /* Chain of children waiting to run until the load average goes down. */
173 static struct child *waiting_jobs = 0;
175 /* Write an error message describing the exit status given in
176 EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
177 Append "(ignored)" if IGNORED is nonzero. */
179 static void
180 child_error (target_name, exit_code, exit_sig, coredump, ignored)
181 char *target_name;
182 int exit_code, exit_sig, coredump;
183 int ignored;
185 if (ignored && silent_flag)
186 return;
188 #ifdef VMS
189 if (!(exit_code & 1))
190 error("*** [%s] Error 0x%x%s", target_name, exit_code, ((ignored)? " (ignored)" : ""));
191 #else
192 if (exit_sig == 0)
193 error (ignored ? "[%s] Error %d (ignored)" :
194 "*** [%s] Error %d",
195 target_name, exit_code);
196 else
197 error ("*** [%s] %s%s",
198 target_name, strsignal (exit_sig),
199 coredump ? " (core dumped)" : "");
200 #endif
203 static unsigned int dead_children = 0;
205 #ifdef VMS
206 /* Wait for nchildren children to terminate */
207 static void
208 vmsWaitForChildren(int *status)
210 while (1)
212 if (!vms_jobsefnmask)
214 *status = 0;
215 return;
218 *status = sys$wflor (32, vms_jobsefnmask);
220 return;
222 #endif
225 /* Notice that a child died.
226 reap_children should be called when convenient. */
227 RETSIGTYPE
228 child_handler (sig)
229 int sig;
231 ++dead_children;
233 if (debug_flag)
234 printf ("Got a SIGCHLD; %d unreaped children.\n", dead_children);
237 extern int shell_function_pid, shell_function_completed;
239 /* Reap dead children, storing the returned status and the new command
240 state (`cs_finished') in the `file' member of the `struct child' for the
241 dead child, and removing the child from the chain. If BLOCK nonzero,
242 reap at least one child, waiting for it to die if necessary. If ERR is
243 nonzero, print an error message first. */
245 void
246 reap_children (block, err)
247 int block, err;
249 WAIT_T status;
251 while ((children != 0 || shell_function_pid != 0) &&
252 (block || dead_children > 0))
254 int remote = 0;
255 register int pid;
256 int exit_code, exit_sig, coredump;
257 register struct child *lastc, *c;
258 int child_failed;
259 int any_remote, any_local;
261 if (err && dead_children == 0)
263 /* We might block for a while, so let the user know why. */
264 fflush (stdout);
265 error ("*** Waiting for unfinished jobs....");
268 /* We have one less dead child to reap.
269 The test and decrement are not atomic; if it is compiled into:
270 register = dead_children - 1;
271 dead_children = register;
272 a SIGCHLD could come between the two instructions.
273 child_handler increments dead_children.
274 The second instruction here would lose that increment. But the
275 only effect of dead_children being wrong is that we might wait
276 longer than necessary to reap a child, and lose some parallelism;
277 and we might print the "Waiting for unfinished jobs" message above
278 when not necessary. */
280 if (dead_children > 0)
281 --dead_children;
283 any_remote = 0;
284 any_local = shell_function_pid != -1;
285 for (c = children; c != 0; c = c->next)
287 any_remote |= c->remote;
288 any_local |= ! c->remote;
289 if (debug_flag)
290 printf ("Live child 0x%08lx PID %d%s\n",
291 (unsigned long int) c,
292 c->pid, c->remote ? " (remote)" : "");
293 #ifdef VMS
294 break;
295 #endif
298 /* First, check for remote children. */
299 if (any_remote)
300 pid = remote_status (&exit_code, &exit_sig, &coredump, 0);
301 else
302 pid = 0;
304 if (pid < 0)
306 remote_status_lose:
307 #ifdef EINTR
308 if (errno == EINTR)
309 continue;
310 #endif
311 pfatal_with_name ("remote_status");
313 else if (pid == 0)
315 #if !defined(__MSDOS__) && !defined(_AMIGA)
316 /* No remote children. Check for local children. */
318 if (any_local)
320 #ifdef VMS
321 vmsWaitForChildren (&status);
322 pid = c->pid;
323 #else
324 #ifdef WAIT_NOHANG
325 if (!block)
326 pid = WAIT_NOHANG (&status);
327 else
328 #endif
329 pid = wait (&status);
330 #endif /* !VMS */
332 else
333 pid = 0;
335 if (pid < 0)
337 #ifdef EINTR
338 if (errno == EINTR)
339 continue;
340 #endif
341 pfatal_with_name ("wait");
343 else if (pid == 0)
345 /* No local children. */
346 if (block && any_remote)
348 /* Now try a blocking wait for a remote child. */
349 pid = remote_status (&exit_code, &exit_sig, &coredump, 1);
350 if (pid < 0)
351 goto remote_status_lose;
352 else if (pid == 0)
353 /* No remote children either. Finally give up. */
354 break;
355 else
356 /* We got a remote child. */
357 remote = 1;
359 else
360 break;
362 else
364 /* Chop the status word up. */
365 exit_code = WEXITSTATUS (status);
366 exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
367 coredump = WCOREDUMP (status);
369 #else /* MSDOS. */
370 #ifdef __MSDOS__
371 /* Life is very different on MSDOS. */
372 pid = dos_pid - 1;
373 status = dos_status;
374 exit_code = dos_status;
375 exit_sig = 0;
376 coredump = 0;
377 #else
378 /* Same on Amiga */
379 pid = amiga_pid - 1;
380 status = amiga_status;
381 exit_code = amiga_status;
382 exit_sig = 0;
383 coredump = 0;
384 #endif
385 #endif /* Not MSDOS. */
387 else
388 /* We got a remote child. */
389 remote = 1;
391 /* Check if this is the child of the `shell' function. */
392 if (!remote && pid == shell_function_pid)
394 /* It is. Leave an indicator for the `shell' function. */
395 if (exit_sig == 0 && exit_code == 127)
396 shell_function_completed = -1;
397 else
398 shell_function_completed = 1;
399 break;
402 child_failed = exit_sig != 0 || exit_code != 0;
404 /* Search for a child matching the deceased one. */
405 lastc = 0;
406 for (c = children; c != 0; lastc = c, c = c->next)
407 if (c->remote == remote && c->pid == pid)
408 break;
410 if (c == 0)
412 /* An unknown child died. */
413 char buf[100];
414 sprintf (buf, "Unknown%s job %d", remote ? " remote" : "", pid);
415 if (child_failed)
416 child_error (buf, exit_code, exit_sig, coredump,
417 ignore_errors_flag);
418 else
419 error ("%s finished.", buf);
421 else
423 if (debug_flag)
424 printf ("Reaping %s child 0x%08lx PID %d%s\n",
425 child_failed ? "losing" : "winning",
426 (unsigned long int) c,
427 c->pid, c->remote ? " (remote)" : "");
429 /* If this child had the good stdin, say it is now free. */
430 if (c->good_stdin)
431 good_stdin_used = 0;
433 if (child_failed && !c->noerror && !ignore_errors_flag)
435 /* The commands failed. Write an error message,
436 delete non-precious targets, and abort. */
437 static int delete_on_error = -1;
438 child_error (c->file->name, exit_code, exit_sig, coredump, 0);
439 c->file->update_status = 2;
440 if (delete_on_error == -1)
442 struct file *f = lookup_file (".DELETE_ON_ERROR");
443 delete_on_error = f != 0 && f->is_target;
445 if (exit_sig != 0 || delete_on_error)
446 delete_child_targets (c);
448 else
450 if (child_failed)
452 /* The commands failed, but we don't care. */
453 child_error (c->file->name,
454 exit_code, exit_sig, coredump, 1);
455 child_failed = 0;
458 /* If there are more commands to run, try to start them. */
459 if (job_next_command (c))
461 if (handling_fatal_signal)
463 /* Never start new commands while we are dying.
464 Since there are more commands that wanted to be run,
465 the target was not completely remade. So we treat
466 this as if a command had failed. */
467 c->file->update_status = 2;
469 else
471 /* Check again whether to start remotely.
472 Whether or not we want to changes over time.
473 Also, start_remote_job may need state set up
474 by start_remote_job_p. */
475 c->remote = start_remote_job_p ();
476 start_job_command (c);
477 /* Fatal signals are left blocked in case we were
478 about to put that child on the chain. But it is
479 already there, so it is safe for a fatal signal to
480 arrive now; it will clean up this child's targets. */
481 unblock_sigs ();
482 if (c->file->command_state == cs_running)
483 /* We successfully started the new command.
484 Loop to reap more children. */
485 continue;
488 if (c->file->update_status != 0)
489 /* We failed to start the commands. */
490 delete_child_targets (c);
492 else
493 /* There are no more commands. We got through them all
494 without an unignored error. Now the target has been
495 successfully updated. */
496 c->file->update_status = 0;
499 /* When we get here, all the commands for C->file are finished
500 (or aborted) and C->file->update_status contains 0 or 2. But
501 C->file->command_state is still cs_running if all the commands
502 ran; notice_finish_file looks for cs_running to tell it that
503 it's interesting to check the file's modtime again now. */
505 if (! handling_fatal_signal)
506 /* Notice if the target of the commands has been changed.
507 This also propagates its values for command_state and
508 update_status to its also_make files. */
509 notice_finished_file (c->file);
511 if (debug_flag)
512 printf ("Removing child 0x%08lx PID %d%s from chain.\n",
513 (unsigned long int) c,
514 c->pid, c->remote ? " (remote)" : "");
516 /* Remove the child from the chain and free it. */
517 if (lastc == 0)
518 children = c->next;
519 else
520 lastc->next = c->next;
521 if (! handling_fatal_signal) /* Avoid nonreentrancy. */
522 free_child (c);
524 /* There is now another slot open. */
525 if (job_slots_used > 0)
526 --job_slots_used;
528 /* If the job failed, and the -k flag was not given, die,
529 unless we are already in the process of dying. */
530 if (!err && child_failed && !keep_going_flag)
531 die (2);
534 /* Only block for one child. */
535 block = 0;
537 return;
540 /* Free the storage allocated for CHILD. */
542 static void
543 free_child (child)
544 register struct child *child;
546 if (child->command_lines != 0)
548 register unsigned int i;
549 for (i = 0; i < child->file->cmds->ncommand_lines; ++i)
550 free (child->command_lines[i]);
551 free ((char *) child->command_lines);
554 if (child->environment != 0)
556 register char **ep = child->environment;
557 while (*ep != 0)
558 free (*ep++);
559 free ((char *) child->environment);
562 free ((char *) child);
565 #ifdef POSIX
566 #ifdef __MSDOS__
567 void
568 unblock_sigs ()
570 return;
572 #else
573 extern sigset_t fatal_signal_set;
575 void
576 unblock_sigs ()
578 sigset_t empty;
579 sigemptyset (&empty);
580 sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
582 #endif
583 #endif
585 /* Start a job to run the commands specified in CHILD.
586 CHILD is updated to reflect the commands and ID of the child process.
588 NOTE: On return fatal signals are blocked! The caller is responsible
589 for calling `unblock_sigs', once the new child is safely on the chain so
590 it can be cleaned up in the event of a fatal signal. */
592 static void
593 start_job_command (child)
594 register struct child *child;
596 #ifndef _AMIGA
597 static int bad_stdin = -1;
598 #endif
599 register char *p;
600 int flags;
601 #ifdef VMS
602 char *argv;
603 #else
604 char **argv;
605 #endif
607 /* Combine the flags parsed for the line itself with
608 the flags specified globally for this target. */
609 flags = (child->file->command_flags
610 | child->file->cmds->lines_flags[child->command_line - 1]);
612 p = child->command_ptr;
613 child->noerror = flags & COMMANDS_NOERROR;
615 while (*p != '\0')
617 if (*p == '@')
618 flags |= COMMANDS_SILENT;
619 else if (*p == '+')
620 flags |= COMMANDS_RECURSE;
621 else if (*p == '-')
622 child->noerror = 1;
623 else if (!isblank (*p) && *p != '+')
624 break;
625 ++p;
628 /* If -q was given, just say that updating `failed'. The exit status of
629 1 tells the user that -q is saying `something to do'; the exit status
630 for a random error is 2. */
631 if (question_flag && !(flags & COMMANDS_RECURSE))
633 child->file->update_status = 1;
634 notice_finished_file (child->file);
635 return;
638 /* There may be some preceding whitespace left if there
639 was nothing but a backslash on the first line. */
640 p = next_token (p);
642 /* Figure out an argument list from this command line. */
645 char *end = 0;
646 #ifdef VMS
647 argv = p;
648 #else
649 argv = construct_command_argv (p, &end, child->file);
650 #endif
651 if (end == NULL)
652 child->command_ptr = NULL;
653 else
655 *end++ = '\0';
656 child->command_ptr = end;
660 if (touch_flag && !(flags & COMMANDS_RECURSE))
662 /* Go on to the next command. It might be the recursive one.
663 We construct ARGV only to find the end of the command line. */
664 #ifndef VMS
665 free (argv[0]);
666 free ((char *) argv);
667 #endif
668 argv = 0;
671 if (argv == 0)
673 next_command:
674 /* This line has no commands. Go to the next. */
675 if (job_next_command (child))
676 start_job_command (child);
677 else
679 /* No more commands. All done. */
680 child->file->update_status = 0;
681 notice_finished_file (child->file);
683 return;
686 /* Print out the command. If silent, we call `message' with null so it
687 can log the working directory before the command's own error messages
688 appear. */
690 message (0, (just_print_flag || (!(flags & COMMANDS_SILENT) && !silent_flag))
691 ? "%s" : (char *) 0, p);
693 /* Tell update_goal_chain that a command has been started on behalf of
694 this target. It is important that this happens here and not in
695 reap_children (where we used to do it), because reap_children might be
696 reaping children from a different target. We want this increment to
697 guaranteedly indicate that a command was started for the dependency
698 chain (i.e., update_file recursion chain) we are processing. */
700 ++commands_started;
702 /* If -n was given, recurse to get the next line in the sequence. */
704 if (just_print_flag && !(flags & COMMANDS_RECURSE))
706 #ifndef VMS
707 free (argv[0]);
708 free ((char *) argv);
709 #endif
710 goto next_command;
713 /* Flush the output streams so they won't have things written twice. */
715 fflush (stdout);
716 fflush (stderr);
718 #ifndef VMS
720 /* Set up a bad standard input that reads from a broken pipe. */
722 if (bad_stdin == -1)
724 /* Make a file descriptor that is the read end of a broken pipe.
725 This will be used for some children's standard inputs. */
726 int pd[2];
727 if (pipe (pd) == 0)
729 /* Close the write side. */
730 (void) close (pd[1]);
731 /* Save the read side. */
732 bad_stdin = pd[0];
734 /* Set the descriptor to close on exec, so it does not litter any
735 child's descriptor table. When it is dup2'd onto descriptor 0,
736 that descriptor will not close on exec. */
737 #ifdef FD_SETFD
738 #ifndef FD_CLOEXEC
739 #define FD_CLOEXEC 1
740 #endif
741 (void) fcntl (bad_stdin, F_SETFD, FD_CLOEXEC);
742 #endif
746 /* Decide whether to give this child the `good' standard input
747 (one that points to the terminal or whatever), or the `bad' one
748 that points to the read side of a broken pipe. */
750 child->good_stdin = !good_stdin_used;
751 if (child->good_stdin)
752 good_stdin_used = 1;
754 #endif /* !VMS */
756 child->deleted = 0;
758 #ifndef _AMIGA
759 /* Set up the environment for the child. */
760 if (child->environment == 0)
761 child->environment = target_environment (child->file);
762 #endif
764 #if !defined(__MSDOS__) && !defined(_AMIGA)
766 #ifndef VMS
767 /* start_waiting_job has set CHILD->remote if we can start a remote job. */
768 if (child->remote)
770 int is_remote, id, used_stdin;
771 if (start_remote_job (argv, child->environment,
772 child->good_stdin ? 0 : bad_stdin,
773 &is_remote, &id, &used_stdin))
774 goto error;
775 else
777 if (child->good_stdin && !used_stdin)
779 child->good_stdin = 0;
780 good_stdin_used = 0;
782 child->remote = is_remote;
783 child->pid = id;
786 else
787 #endif /* !VMS */
789 /* Fork the child process. */
791 char **parent_environ;
793 #ifdef POSIX
794 (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0);
795 #else
796 #ifdef HAVE_SIGSETMASK
797 (void) sigblock (fatal_signal_mask);
798 #endif
799 #endif
801 child->remote = 0;
803 #ifdef VMS
805 if (!child_execute_job (argv, child)) {
806 /* Fork failed! */
807 perror_with_name ("vfork", "");
808 goto error;
811 #else
813 parent_environ = environ;
814 child->pid = vfork ();
815 environ = parent_environ; /* Restore value child may have clobbered. */
816 if (child->pid == 0)
818 /* We are the child side. */
819 unblock_sigs ();
820 child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
821 argv, child->environment);
823 else if (child->pid < 0)
825 /* Fork failed! */
826 unblock_sigs ();
827 perror_with_name ("vfork", "");
828 goto error;
830 #endif /* !VMS */
833 #else /* MSDOS or Amiga. */
834 #ifdef __MSDOS__
835 dos_status = spawnvpe (P_WAIT, argv[0], argv, child->environment);
836 ++dead_children;
837 child->pid = dos_pid++;
838 if (dos_batch_file)
840 dos_batch_file = 0;
841 remove (dos_bname); /* Ignore errors. */
842 if (access (dos_bename, 0))
843 dos_status = 1;
844 else
845 dos_status = 0;
846 remove (dos_bename);
848 #else
849 amiga_status = MyExecute (argv);
851 ++dead_children;
852 child->pid = amiga_pid++;
853 if (amiga_batch_file)
855 amiga_batch_file = 0;
856 DeleteFile (amiga_bname); /* Ignore errors. */
858 #endif /* Not Amiga */
859 #endif /* Not MSDOS. */
861 /* We are the parent side. Set the state to
862 say the commands are running and return. */
864 set_command_state (child->file, cs_running);
866 /* Free the storage used by the child's argument list. */
867 #ifndef VMS
868 free (argv[0]);
869 free ((char *) argv);
870 #endif
872 return;
874 error:
875 child->file->update_status = 2;
876 notice_finished_file (child->file);
877 return;
880 /* Try to start a child running.
881 Returns nonzero if the child was started (and maybe finished), or zero if
882 the load was too high and the child was put on the `waiting_jobs' chain. */
884 static int
885 start_waiting_job (c)
886 struct child *c;
888 /* If we can start a job remotely, we always want to, and don't care about
889 the local load average. We record that the job should be started
890 remotely in C->remote for start_job_command to test. */
892 c->remote = start_remote_job_p ();
894 /* If this job is to be started locally, and we are already running
895 some jobs, make this one wait if the load average is too high. */
896 if (!c->remote && job_slots_used > 0 && load_too_high ())
898 /* Put this child on the chain of children waiting
899 for the load average to go down. */
900 set_command_state (c->file, cs_running);
901 c->next = waiting_jobs;
902 waiting_jobs = c;
903 return 0;
906 /* Start the first command; reap_children will run later command lines. */
907 start_job_command (c);
909 switch (c->file->command_state)
911 case cs_running:
912 c->next = children;
913 if (debug_flag)
914 printf ("Putting child 0x%08lx PID %05d%s on the chain.\n",
915 (unsigned long int) c,
916 c->pid, c->remote ? " (remote)" : "");
917 children = c;
918 /* One more job slot is in use. */
919 ++job_slots_used;
920 unblock_sigs ();
921 break;
923 case cs_not_started:
924 /* All the command lines turned out to be empty. */
925 c->file->update_status = 0;
926 /* FALLTHROUGH */
928 case cs_finished:
929 notice_finished_file (c->file);
930 free_child (c);
931 break;
933 default:
934 assert (c->file->command_state == cs_finished);
935 break;
938 return 1;
941 /* Create a `struct child' for FILE and start its commands running. */
943 void
944 new_job (file)
945 register struct file *file;
947 register struct commands *cmds = file->cmds;
948 register struct child *c;
949 char **lines;
950 register unsigned int i;
952 /* Let any previously decided-upon jobs that are waiting
953 for the load to go down start before this new one. */
954 start_waiting_jobs ();
956 /* Reap any children that might have finished recently. */
957 reap_children (0, 0);
959 /* Chop the commands up into lines if they aren't already. */
960 chop_commands (cmds);
962 if (job_slots != 0)
963 /* Wait for a job slot to be freed up. */
964 while (job_slots_used == job_slots)
965 reap_children (1, 0);
967 /* Expand the command lines and store the results in LINES. */
968 lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *));
969 for (i = 0; i < cmds->ncommand_lines; ++i)
971 /* Collapse backslash-newline combinations that are inside variable
972 or function references. These are left alone by the parser so
973 that they will appear in the echoing of commands (where they look
974 nice); and collapsed by construct_command_argv when it tokenizes.
975 But letting them survive inside function invocations loses because
976 we don't want the functions to see them as part of the text. */
978 char *in, *out, *ref;
980 /* IN points to where in the line we are scanning.
981 OUT points to where in the line we are writing.
982 When we collapse a backslash-newline combination,
983 IN gets ahead out OUT. */
985 in = out = cmds->command_lines[i];
986 while ((ref = index (in, '$')) != 0)
988 ++ref; /* Move past the $. */
990 if (out != in)
991 /* Copy the text between the end of the last chunk
992 we processed (where IN points) and the new chunk
993 we are about to process (where REF points). */
994 bcopy (in, out, ref - in);
996 /* Move both pointers past the boring stuff. */
997 out += ref - in;
998 in = ref;
1000 if (*ref == '(' || *ref == '{')
1002 char openparen = *ref;
1003 char closeparen = openparen == '(' ? ')' : '}';
1004 int count;
1005 char *p;
1007 *out++ = *in++; /* Copy OPENPAREN. */
1008 /* IN now points past the opening paren or brace.
1009 Count parens or braces until it is matched. */
1010 count = 0;
1011 while (*in != '\0')
1013 if (*in == closeparen && --count < 0)
1014 break;
1015 else if (*in == '\\' && in[1] == '\n')
1017 /* We have found a backslash-newline inside a
1018 variable or function reference. Eat it and
1019 any following whitespace. */
1021 int quoted = 0;
1022 for (p = in - 1; p > ref && *p == '\\'; --p)
1023 quoted = !quoted;
1025 if (quoted)
1026 /* There were two or more backslashes, so this is
1027 not really a continuation line. We don't collapse
1028 the quoting backslashes here as is done in
1029 collapse_continuations, because the line will
1030 be collapsed again after expansion. */
1031 *out++ = *in++;
1032 else
1034 /* Skip the backslash, newline and
1035 any following whitespace. */
1036 in = next_token (in + 2);
1038 /* Discard any preceding whitespace that has
1039 already been written to the output. */
1040 while (out > ref && isblank (out[-1]))
1041 --out;
1043 /* Replace it all with a single space. */
1044 *out++ = ' ';
1047 else
1049 if (*in == openparen)
1050 ++count;
1052 *out++ = *in++;
1058 /* There are no more references in this line to worry about.
1059 Copy the remaining uninteresting text to the output. */
1060 if (out != in)
1061 strcpy (out, in);
1063 /* Finally, expand the line. */
1064 lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i],
1065 file);
1068 /* Start the command sequence, record it in a new
1069 `struct child', and add that to the chain. */
1071 c = (struct child *) xmalloc (sizeof (struct child));
1072 c->file = file;
1073 c->command_lines = lines;
1074 c->command_line = 0;
1075 c->command_ptr = 0;
1076 c->environment = 0;
1078 /* Fetch the first command line to be run. */
1079 job_next_command (c);
1081 /* The job is now primed. Start it running.
1082 (This will notice if there are in fact no commands.) */
1083 (void)start_waiting_job (c);
1085 if (job_slots == 1)
1086 /* Since there is only one job slot, make things run linearly.
1087 Wait for the child to die, setting the state to `cs_finished'. */
1088 while (file->command_state == cs_running)
1089 reap_children (1, 0);
1091 return;
1094 /* Move CHILD's pointers to the next command for it to execute.
1095 Returns nonzero if there is another command. */
1097 static int
1098 job_next_command (child)
1099 struct child *child;
1101 while (child->command_ptr == 0 || *child->command_ptr == '\0')
1103 /* There are no more lines in the expansion of this line. */
1104 if (child->command_line == child->file->cmds->ncommand_lines)
1106 /* There are no more lines to be expanded. */
1107 child->command_ptr = 0;
1108 return 0;
1110 else
1111 /* Get the next line to run. */
1112 child->command_ptr = child->command_lines[child->command_line++];
1114 return 1;
1117 static int
1118 load_too_high ()
1120 #if defined(__MSDOS__) || defined(VMS)
1121 return 1;
1122 #else
1123 double load;
1125 if (max_load_average < 0)
1126 return 0;
1128 make_access ();
1129 if (getloadavg (&load, 1) != 1)
1131 static int lossage = -1;
1132 /* Complain only once for the same error. */
1133 if (lossage == -1 || errno != lossage)
1135 if (errno == 0)
1136 /* An errno value of zero means getloadavg is just unsupported. */
1137 error ("cannot enforce load limits on this operating system");
1138 else
1139 perror_with_name ("cannot enforce load limit: ", "getloadavg");
1141 lossage = errno;
1142 load = 0;
1144 user_access ();
1146 return load >= max_load_average;
1147 #endif
1150 /* Start jobs that are waiting for the load to be lower. */
1152 void
1153 start_waiting_jobs ()
1155 struct child *job;
1157 if (waiting_jobs == 0)
1158 return;
1162 /* Check for recently deceased descendants. */
1163 reap_children (0, 0);
1165 /* Take a job off the waiting list. */
1166 job = waiting_jobs;
1167 waiting_jobs = job->next;
1169 /* Try to start that job. We break out of the loop as soon
1170 as start_waiting_job puts one back on the waiting list. */
1172 while (start_waiting_job (job) && waiting_jobs != 0);
1174 return;
1177 #ifdef VMS
1178 #include <descrip.h>
1179 #include <clidef.h>
1181 /* This is called as an AST when a child process dies (it won't get
1182 interrupted by anything except a higher level AST).
1184 int vmsHandleChildTerm(struct child *child)
1186 int status;
1187 register struct child *lastc, *c;
1188 int child_failed;
1190 vms_jobsefnmask &= ~(1 << (child->efn - 32));
1192 lib$free_ef(&child->efn);
1194 (void) sigblock (fatal_signal_mask);
1196 child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0));
1198 /* Search for a child matching the deceased one. */
1199 lastc = 0;
1200 #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
1201 for (c = children; c != 0 && c != child; lastc = c, c = c->next);
1202 #else
1203 c = child;
1204 #endif
1206 if (child_failed && !c->noerror && !ignore_errors_flag)
1208 /* The commands failed. Write an error message,
1209 delete non-precious targets, and abort. */
1210 child_error (c->file->name, c->cstatus, 0, 0, 0);
1211 c->file->update_status = 1;
1212 delete_child_targets (c);
1214 else
1216 if (child_failed)
1218 /* The commands failed, but we don't care. */
1219 child_error (c->file->name, c->cstatus, 0, 0, 1);
1220 child_failed = 0;
1223 #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
1224 /* If there are more commands to run, try to start them. */
1225 start_job (c);
1227 switch (c->file->command_state)
1229 case cs_running:
1230 /* Successfully started. */
1231 break;
1233 case cs_finished:
1234 if (c->file->update_status != 0) {
1235 /* We failed to start the commands. */
1236 delete_child_targets (c);
1238 break;
1240 default:
1241 error ("internal error: `%s' command_state \
1242 %d in child_handler", c->file->name);
1243 abort ();
1244 break;
1246 #endif /* RECURSIVEJOBS */
1249 /* Set the state flag to say the commands have finished. */
1250 c->file->command_state = cs_finished;
1251 notice_finished_file (c->file);
1253 #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
1254 /* Remove the child from the chain and free it. */
1255 if (lastc == 0)
1256 children = c->next;
1257 else
1258 lastc->next = c->next;
1259 free_child (c);
1260 #endif /* RECURSIVEJOBS */
1262 /* There is now another slot open. */
1263 if (job_slots_used > 0)
1264 --job_slots_used;
1266 /* If the job failed, and the -k flag was not given, die. */
1267 if (child_failed && !keep_going_flag)
1268 die (EXIT_FAILURE);
1270 (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask));
1272 return 1;
1275 /* VMS:
1276 Spawn a process executing the command in ARGV and return its pid. */
1278 #define MAXCMDLEN 200
1281 child_execute_job (argv, child)
1282 char *argv;
1283 struct child *child;
1285 int i;
1286 static struct dsc$descriptor_s cmddsc;
1287 #ifndef DONTWAITFORCHILD
1288 int spflags = 0;
1289 #else
1290 int spflags = CLI$M_NOWAIT;
1291 #endif
1292 int status;
1293 char cmd[4096],*p,*c;
1294 char comname[50];
1296 /* Remove backslashes */
1297 for (p = argv, c = cmd; *p; p++,c++)
1299 if (*p == '\\') p++;
1300 *c = *p;
1302 *c = *p;
1304 /* check for maximum dcl length and create *.com file if neccesary */
1306 comname[0] = '\0';
1308 if (strlen (cmd) > MAXCMDLEN)
1310 FILE *outfile;
1311 char tmp;
1313 strcpy (comname, "sys$scratch:CMDXXXXXX.COM");
1314 (void) mktemp (comname);
1316 outfile = fopen (comname, "w");
1317 if (outfile == 0)
1318 pfatal_with_name (comname);
1320 fprintf (outfile, "$ ");
1321 c = cmd;
1323 while (c)
1325 p = strchr (c, ',');
1326 if ((p == NULL) || (p-c > MAXCMDLEN))
1327 p = strchr (c, ' ');
1328 if (p != NULL)
1330 p++;
1331 tmp = *p;
1332 *p = '\0';
1334 else
1335 tmp = '\0';
1336 fprintf (outfile, "%s%s\n", c, (tmp == '\0')?"":" -");
1337 if (p != NULL)
1338 *p = tmp;
1339 c = p;
1342 fclose (outfile);
1344 sprintf (cmd, "$ @%s", comname);
1346 if (debug_flag)
1347 printf ("Executing %s instead\n", cmd);
1350 cmddsc.dsc$w_length = strlen(cmd);
1351 cmddsc.dsc$a_pointer = cmd;
1352 cmddsc.dsc$b_dtype = DSC$K_DTYPE_T;
1353 cmddsc.dsc$b_class = DSC$K_CLASS_S;
1355 child->efn = 0;
1356 while (child->efn < 32 || child->efn > 63)
1358 status = lib$get_ef(&child->efn);
1359 if (!(status & 1))
1360 return 0;
1363 sys$clref(child->efn);
1365 vms_jobsefnmask |= (1 << (child->efn - 32));
1367 #ifndef DONTWAITFORCHILD
1368 status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
1369 &child->efn,0,0);
1370 vmsHandleChildTerm(child);
1371 #else
1372 status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
1373 &child->efn,vmsHandleChildTerm,child);
1374 #endif
1376 if (!(status & 1))
1378 printf("Error spawning, %d\n",status);
1379 fflush(stdout);
1382 unlink (comname);
1384 return (status & 1);
1387 #else /* !VMS */
1389 /* UNIX:
1390 Replace the current process with one executing the command in ARGV.
1391 STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
1392 the environment of the new program. This function does not return. */
1394 void
1395 child_execute_job (stdin_fd, stdout_fd, argv, envp)
1396 int stdin_fd, stdout_fd;
1397 char **argv, **envp;
1399 if (stdin_fd != 0)
1400 (void) dup2 (stdin_fd, 0);
1401 if (stdout_fd != 1)
1402 (void) dup2 (stdout_fd, 1);
1403 if (stdin_fd != 0)
1404 (void) close (stdin_fd);
1405 if (stdout_fd != 1)
1406 (void) close (stdout_fd);
1408 /* Run the command. */
1409 exec_command (argv, envp);
1411 #endif /* !VMS */
1413 /* Replace the current process with one running the command in ARGV,
1414 with environment ENVP. This function does not return. */
1416 void
1417 exec_command (argv, envp)
1418 char **argv, **envp;
1420 #ifdef VMS
1421 /* Run the program. */
1422 execve (argv[0], argv, envp);
1423 perror_with_name ("execve: ", argv[0]);
1424 _exit (EXIT_FAILURE);
1425 #else
1426 /* Be the user, permanently. */
1427 child_access ();
1429 /* Run the program. */
1430 environ = envp;
1431 execvp (argv[0], argv);
1433 switch (errno)
1435 case ENOENT:
1436 error ("%s: Command not found", argv[0]);
1437 break;
1438 case ENOEXEC:
1440 /* The file is not executable. Try it as a shell script. */
1441 extern char *getenv ();
1442 char *shell;
1443 char **new_argv;
1444 int argc;
1446 shell = getenv ("SHELL");
1447 if (shell == 0)
1448 shell = default_shell;
1450 argc = 1;
1451 while (argv[argc] != 0)
1452 ++argc;
1454 new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *));
1455 new_argv[0] = shell;
1456 new_argv[1] = argv[0];
1457 while (argc > 0)
1459 new_argv[1 + argc] = argv[argc];
1460 --argc;
1463 execvp (shell, new_argv);
1464 if (errno == ENOENT)
1465 error ("%s: Shell program not found", shell);
1466 else
1467 perror_with_name ("execvp: ", shell);
1468 break;
1471 default:
1472 perror_with_name ("execvp: ", argv[0]);
1473 break;
1476 _exit (127);
1477 #endif /* !VMS */
1480 #ifndef VMS
1481 /* Figure out the argument list necessary to run LINE as a command. Try to
1482 avoid using a shell. This routine handles only ' quoting, and " quoting
1483 when no backslash, $ or ` characters are seen in the quotes. Starting
1484 quotes may be escaped with a backslash. If any of the characters in
1485 sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[]
1486 is the first word of a line, the shell is used.
1488 If RESTP is not NULL, *RESTP is set to point to the first newline in LINE.
1489 If *RESTP is NULL, newlines will be ignored.
1491 SHELL is the shell to use, or nil to use the default shell.
1492 IFS is the value of $IFS, or nil (meaning the default). */
1494 static char **
1495 construct_command_argv_internal (line, restp, shell, ifs)
1496 char *line, **restp;
1497 char *shell, *ifs;
1499 #ifdef __MSDOS__
1500 static char sh_chars[] = "\"|<>";
1501 static char *sh_cmds[] = { "break", "call", "cd", "chcp", "chdir", "cls",
1502 "copy", "ctty", "date", "del", "dir", "echo",
1503 "erase", "exit", "for", "goto", "if", "if", "md",
1504 "mkdir", "path", "pause", "prompt", "rem", "ren",
1505 "rename", "set", "shift", "time", "type",
1506 "ver", "verify", "vol", ":", 0 };
1507 #endif
1508 #ifdef _AMIGA
1509 static char sh_chars[] = "#;\"|<>()?*$`";
1510 static char *sh_cmds[] = { "cd", "eval", "if", "delete", "echo", "copy",
1511 "rename", "set", "setenv", "date", "makedir",
1512 "skip", "else", "endif", "path", "prompt",
1513 "unset", "unsetenv", "version",
1514 0 };
1515 #else
1516 static char sh_chars[] = "#;\"*?[]&|<>(){}$`^";
1517 static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login",
1518 "logout", "set", "umask", "wait", "while", "for",
1519 "case", "if", ":", ".", "break", "continue",
1520 "export", "read", "readonly", "shift", "times",
1521 "trap", "switch", 0 };
1522 #endif
1523 register int i;
1524 register char *p;
1525 register char *ap;
1526 char *end;
1527 int instring, word_has_equals, seen_nonequals;
1528 char **new_argv = 0;
1530 if (restp != NULL)
1531 *restp = NULL;
1533 /* Make sure not to bother processing an empty line. */
1534 while (isblank (*line))
1535 ++line;
1536 if (*line == '\0')
1537 return 0;
1539 /* See if it is safe to parse commands internally. */
1540 if (shell == 0)
1541 shell = default_shell;
1542 else if (strcmp (shell, default_shell))
1543 goto slow;
1545 if (ifs != 0)
1546 for (ap = ifs; *ap != '\0'; ++ap)
1547 if (*ap != ' ' && *ap != '\t' && *ap != '\n')
1548 goto slow;
1550 i = strlen (line) + 1;
1552 /* More than 1 arg per character is impossible. */
1553 new_argv = (char **) xmalloc (i * sizeof (char *));
1555 /* All the args can fit in a buffer as big as LINE is. */
1556 ap = new_argv[0] = (char *) xmalloc (i);
1557 end = ap + i;
1559 /* I is how many complete arguments have been found. */
1560 i = 0;
1561 instring = word_has_equals = seen_nonequals = 0;
1562 for (p = line; *p != '\0'; ++p)
1564 if (ap > end)
1565 abort ();
1567 if (instring)
1569 string_char:
1570 /* Inside a string, just copy any char except a closing quote
1571 or a backslash-newline combination. */
1572 if (*p == instring)
1573 instring = 0;
1574 else if (*p == '\\' && p[1] == '\n')
1575 goto swallow_escaped_newline;
1576 else if (*p == '\n' && restp != NULL)
1578 /* End of the command line. */
1579 *restp = p;
1580 goto end_of_line;
1582 /* Backslash, $, and ` are special inside double quotes.
1583 If we see any of those, punt. */
1584 else if (instring == '"' && index ("\\$`", *p) != 0)
1585 goto slow;
1586 else
1587 *ap++ = *p;
1589 else if (index (sh_chars, *p) != 0)
1590 /* Not inside a string, but it's a special char. */
1591 goto slow;
1592 else
1593 /* Not a special char. */
1594 switch (*p)
1596 case '=':
1597 /* Equals is a special character in leading words before the
1598 first word with no equals sign in it. This is not the case
1599 with sh -k, but we never get here when using nonstandard
1600 shell flags. */
1601 if (! seen_nonequals)
1602 goto slow;
1603 word_has_equals = 1;
1604 *ap++ = '=';
1605 break;
1607 case '\\':
1608 /* Backslash-newline combinations are eaten. */
1609 if (p[1] == '\n')
1611 swallow_escaped_newline:
1613 /* Eat the backslash, the newline, and following whitespace,
1614 replacing it all with a single space. */
1615 p += 2;
1617 /* If there is a tab after a backslash-newline,
1618 remove it from the source line which will be echoed,
1619 since it was most likely used to line
1620 up the continued line with the previous one. */
1621 if (*p == '\t')
1622 strcpy (p, p + 1);
1624 if (instring)
1625 goto string_char;
1626 else
1628 if (ap != new_argv[i])
1629 /* Treat this as a space, ending the arg.
1630 But if it's at the beginning of the arg, it should
1631 just get eaten, rather than becoming an empty arg. */
1632 goto end_of_arg;
1633 else
1634 p = next_token (p) - 1;
1637 else if (p[1] != '\0')
1638 /* Copy and skip the following char. */
1639 *ap++ = *++p;
1640 break;
1642 case '\'':
1643 case '"':
1644 instring = *p;
1645 break;
1647 case '\n':
1648 if (restp != NULL)
1650 /* End of the command line. */
1651 *restp = p;
1652 goto end_of_line;
1654 else
1655 /* Newlines are not special. */
1656 *ap++ = '\n';
1657 break;
1659 case ' ':
1660 case '\t':
1661 end_of_arg:
1662 /* We have the end of an argument.
1663 Terminate the text of the argument. */
1664 *ap++ = '\0';
1665 new_argv[++i] = ap;
1667 /* Update SEEN_NONEQUALS, which tells us if every word
1668 heretofore has contained an `='. */
1669 seen_nonequals |= ! word_has_equals;
1670 if (word_has_equals && ! seen_nonequals)
1671 /* An `=' in a word before the first
1672 word without one is magical. */
1673 goto slow;
1674 word_has_equals = 0; /* Prepare for the next word. */
1676 /* If this argument is the command name,
1677 see if it is a built-in shell command.
1678 If so, have the shell handle it. */
1679 if (i == 1)
1681 register int j;
1682 for (j = 0; sh_cmds[j] != 0; ++j)
1683 if (streq (sh_cmds[j], new_argv[0]))
1684 goto slow;
1687 /* Ignore multiple whitespace chars. */
1688 p = next_token (p);
1689 /* Next iteration should examine the first nonwhite char. */
1690 --p;
1691 break;
1693 default:
1694 *ap++ = *p;
1695 break;
1698 end_of_line:
1700 if (instring)
1701 /* Let the shell deal with an unterminated quote. */
1702 goto slow;
1704 /* Terminate the last argument and the argument list. */
1706 *ap = '\0';
1707 if (new_argv[i][0] != '\0')
1708 ++i;
1709 new_argv[i] = 0;
1711 if (i == 1)
1713 register int j;
1714 for (j = 0; sh_cmds[j] != 0; ++j)
1715 if (streq (sh_cmds[j], new_argv[0]))
1716 goto slow;
1719 if (new_argv[0] == 0)
1720 /* Line was empty. */
1721 return 0;
1722 else
1723 return new_argv;
1725 slow:;
1726 /* We must use the shell. */
1728 if (new_argv != 0)
1730 /* Free the old argument list we were working on. */
1731 free (new_argv[0]);
1732 free ((void *)new_argv);
1735 #ifdef __MSDOS__
1737 FILE *batch;
1738 dos_batch_file = 1;
1739 if (dos_bname == 0)
1741 dos_bname = tempnam (".", "mk");
1742 for (i = 0; dos_bname[i] != '\0'; ++i)
1743 if (dos_bname[i] == '/')
1744 dos_bname[i] = '\\';
1745 dos_bename = (char *) xmalloc (strlen (dos_bname) + 5);
1746 strcpy (dos_bename, dos_bname);
1747 strcat (dos_bname, ".bat");
1748 strcat (dos_bename, ".err");
1750 batch = fopen (dos_bename, "w"); /* Create a file. */
1751 if (batch != NULL)
1752 fclose (batch);
1753 batch = fopen (dos_bname, "w");
1754 fputs ("@echo off\n", batch);
1755 fputs (line, batch);
1756 fprintf (batch, "\nif errorlevel 1 del %s\n", dos_bename);
1757 fclose (batch);
1758 new_argv = (char **) xmalloc(2 * sizeof(char *));
1759 new_argv[0] = strdup (dos_bname);
1760 new_argv[1] = 0;
1762 #endif /* MSDOS. */
1763 #ifdef _AMIGA
1765 char *ptr;
1766 char *buffer;
1767 char *dptr;
1769 buffer = (char *)xmalloc (strlen (line)+1);
1771 ptr = line;
1772 for (dptr=buffer; *ptr; )
1774 if (*ptr == '\\' && ptr[1] == '\n')
1775 ptr += 2;
1776 else if (*ptr == '@') /* Kludge: multiline commands */
1778 ptr += 2;
1779 *dptr++ = '\n';
1781 else
1782 *dptr++ = *ptr++;
1784 *dptr = 0;
1786 new_argv = (char **) xmalloc(2 * sizeof(char *));
1787 new_argv[0] = buffer;
1788 new_argv[1] = 0;
1790 #else /* Not MSDOS or Amiga */
1792 /* SHELL may be a multi-word command. Construct a command line
1793 "SHELL -c LINE", with all special chars in LINE escaped.
1794 Then recurse, expanding this command line to get the final
1795 argument list. */
1797 unsigned int shell_len = strlen (shell);
1798 static char minus_c[] = " -c ";
1799 unsigned int line_len = strlen (line);
1801 char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1)
1802 + (line_len * 2) + 1);
1804 ap = new_line;
1805 bcopy (shell, ap, shell_len);
1806 ap += shell_len;
1807 bcopy (minus_c, ap, sizeof (minus_c) - 1);
1808 ap += sizeof (minus_c) - 1;
1809 for (p = line; *p != '\0'; ++p)
1811 if (restp != NULL && *p == '\n')
1813 *restp = p;
1814 break;
1816 else if (*p == '\\' && p[1] == '\n')
1818 /* Eat the backslash, the newline, and following whitespace,
1819 replacing it all with a single space (which is escaped
1820 from the shell). */
1821 p += 2;
1823 /* If there is a tab after a backslash-newline,
1824 remove it from the source line which will be echoed,
1825 since it was most likely used to line
1826 up the continued line with the previous one. */
1827 if (*p == '\t')
1828 strcpy (p, p + 1);
1830 p = next_token (p);
1831 --p;
1832 *ap++ = '\\';
1833 *ap++ = ' ';
1834 continue;
1837 if (*p == '\\' || *p == '\'' || *p == '"'
1838 || isspace (*p)
1839 || index (sh_chars, *p) != 0)
1840 *ap++ = '\\';
1841 *ap++ = *p;
1843 *ap = '\0';
1845 new_argv = construct_command_argv_internal (new_line, (char **) NULL,
1846 (char *) 0, (char *) 0);
1848 #endif /* Not MSDOS nor Amiga. */
1850 return new_argv;
1853 /* Figure out the argument list necessary to run LINE as a command. Try to
1854 avoid using a shell. This routine handles only ' quoting, and " quoting
1855 when no backslash, $ or ` characters are seen in the quotes. Starting
1856 quotes may be escaped with a backslash. If any of the characters in
1857 sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[]
1858 is the first word of a line, the shell is used.
1860 If RESTP is not NULL, *RESTP is set to point to the first newline in LINE.
1861 If *RESTP is NULL, newlines will be ignored.
1863 FILE is the target whose commands these are. It is used for
1864 variable expansion for $(SHELL) and $(IFS). */
1866 char **
1867 construct_command_argv (line, restp, file)
1868 char *line, **restp;
1869 struct file *file;
1871 char *shell, *ifs;
1872 char **argv;
1875 /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
1876 int save = warn_undefined_variables_flag;
1877 warn_undefined_variables_flag = 0;
1879 shell = allocated_variable_expand_for_file ("$(SHELL)", file);
1880 ifs = allocated_variable_expand_for_file ("$(IFS)", file);
1882 warn_undefined_variables_flag = save;
1885 argv = construct_command_argv_internal (line, restp, shell, ifs);
1887 free (shell);
1888 free (ifs);
1890 return argv;
1892 #endif /* !VMS */
1894 #if !defined(HAVE_DUP2) && !defined(_AMIGA)
1896 dup2 (old, new)
1897 int old, new;
1899 int fd;
1901 (void) close (new);
1902 fd = dup (old);
1903 if (fd != new)
1905 (void) close (fd);
1906 errno = EMFILE;
1907 return -1;
1910 return fd;
1912 #endif /* !HAPE_DUP2 && !_AMIGA */