summaryrefslogtreecommitdiff
path: root/vmsjobs.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2013-09-14 01:04:04 -0400
committerPaul Smith <psmith@gnu.org>2013-09-14 01:04:04 -0400
commitc5bfa400448a14f4c8d4fc51dd56ea17176e1f84 (patch)
tree9a46584dec752bdf9a1a50fc7941d9344fece30d /vmsjobs.c
parentdeff9dacc97cc20015d3018992f2c77cb7fab102 (diff)
downloadgunmake-c5bfa400448a14f4c8d4fc51dd56ea17176e1f84.tar.gz
Support the -Orecurse option properly.
In this mode we still collect all the output from a given target and dump it at once. However we don't treat recursive lines any differently from non-recursive lines. Also we don't print enter/leave messages after every dump. However we do ensure that we always print them once to stdout, so the parent make will collect it properly.
Diffstat (limited to 'vmsjobs.c')
-rw-r--r--vmsjobs.c729
1 files changed, 362 insertions, 367 deletions
diff --git a/vmsjobs.c b/vmsjobs.c
index 8d30157..8bacc86 100644
--- a/vmsjobs.c
+++ b/vmsjobs.c
@@ -31,10 +31,10 @@ vmsWaitForChildren(int *status)
while (1)
{
if (!vms_jobsefnmask)
- {
- *status = 0;
- return;
- }
+ {
+ *status = 0;
+ return;
+ }
*status = sys$wflor (32, vms_jobsefnmask);
}
@@ -59,9 +59,9 @@ vms_redirect (struct dsc$descriptor_s *desc, char *fname, char *ibuf)
{
strcpy (fname, vmsify (fptr, 0));
if (strchr (fname, '.') == 0)
- strcat (fname, ".");
+ strcat (fname, ".");
}
- desc->dsc$w_length = strlen(fname);
+ desc->dsc$w_length = strlen (fname);
desc->dsc$a_pointer = fname;
desc->dsc$b_dtype = DSC$K_DTYPE_T;
desc->dsc$b_class = DSC$K_CLASS_S;
@@ -74,7 +74,7 @@ vms_redirect (struct dsc$descriptor_s *desc, char *fname, char *ibuf)
/* found apostrophe at (p-1)
inc p until after closing apostrophe.
- */
+*/
char *
vms_handle_apos (char *p)
@@ -86,25 +86,21 @@ vms_handle_apos (char *p)
alast = 0;
while (*p != 0)
- {
- if (*p == '"')
- {
- if (alast)
- {
- alast = 0;
- p++;
- }
- else
- {
- p++;
- if (strchr (SEPCHARS, *p))
- break;
- alast = 1;
- }
- }
+ if (*p == '"')
+ if (alast)
+ {
+ alast = 0;
+ p++;
+ }
else
- p++;
- }
+ {
+ p++;
+ if (strchr (SEPCHARS, *p))
+ break;
+ alast = 1;
+ }
+ else
+ p++;
return p;
}
@@ -118,100 +114,99 @@ static int ctrlYPressed= 0;
int
vmsHandleChildTerm(struct child *child)
{
- int status;
- register struct child *lastc, *c;
- int child_failed;
+ int status;
+ register struct child *lastc, *c;
+ int child_failed;
- vms_jobsefnmask &= ~(1 << (child->efn - 32));
+ vms_jobsefnmask &= ~(1 << (child->efn - 32));
- lib$free_ef(&child->efn);
- if (child->comname)
- {
- if (!ISDB (DB_JOBS)&&!ctrlYPressed)
- unlink (child->comname);
- free (child->comname);
- }
+ lib$free_ef (&child->efn);
+ if (child->comname)
+ {
+ if (!ISDB (DB_JOBS) && !ctrlYPressed)
+ unlink (child->comname);
+ free (child->comname);
+ }
- (void) sigblock (fatal_signal_mask);
+ (void) sigblock (fatal_signal_mask);
- child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0));
+ child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0));
- /* Search for a child matching the deceased one. */
- lastc = 0;
+ /* Search for a child matching the deceased one. */
+ lastc = 0;
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
- for (c = children; c != 0 && c != child; lastc = c, c = c->next)
- ;
+ for (c = children; c != 0 && c != child; lastc = c, c = c->next)
+ ;
#else
- c = child;
+ c = child;
#endif
- if (child_failed && !c->noerror && !ignore_errors_flag)
- {
- /* The commands failed. Write an error message,
- delete non-precious targets, and abort. */
- child_error (c, c->cstatus, 0, 0, 0);
- c->file->update_status = us_failed;
- delete_child_targets (c);
- }
- else
- {
- if (child_failed)
- {
- /* The commands failed, but we don't care. */
- child_error (c, c->cstatus, 0, 0, 1);
- child_failed = 0;
- }
+ if (child_failed && !c->noerror && !ignore_errors_flag)
+ {
+ /* The commands failed. Write an error message,
+ delete non-precious targets, and abort. */
+ child_error (c, c->cstatus, 0, 0, 0);
+ c->file->update_status = us_failed;
+ delete_child_targets (c);
+ }
+ else
+ {
+ if (child_failed)
+ {
+ /* The commands failed, but we don't care. */
+ child_error (c, c->cstatus, 0, 0, 1);
+ child_failed = 0;
+ }
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
- /* If there are more commands to run, try to start them. */
- start_job (c);
-
- switch (c->file->command_state)
- {
- case cs_running:
- /* Successfully started. */
- break;
-
- case cs_finished:
- if (c->file->update_status != us_success) {
- /* We failed to start the commands. */
- delete_child_targets (c);
- }
- break;
-
- default:
- error (NILF, _("internal error: '%s' command_state"),
- c->file->name);
- abort ();
- break;
- }
+ /* If there are more commands to run, try to start them. */
+ start_job (c);
+
+ switch (c->file->command_state)
+ {
+ case cs_running:
+ /* Successfully started. */
+ break;
+
+ case cs_finished:
+ if (c->file->update_status != us_success)
+ /* We failed to start the commands. */
+ delete_child_targets (c);
+ break;
+
+ default:
+ error (NILF, _("internal error: '%s' command_state"),
+ c->file->name);
+ abort ();
+ break;
+ }
#endif /* RECURSIVEJOBS */
- }
+ }
- /* Set the state flag to say the commands have finished. */
- c->file->command_state = cs_finished;
- notice_finished_file (c->file);
+ /* Set the state flag to say the commands have finished. */
+ c->file->command_state = cs_finished;
+ notice_finished_file (c->file);
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
- /* Remove the child from the chain and free it. */
- if (lastc == 0)
- children = c->next;
- else
- lastc->next = c->next;
- free_child (c);
+ /* Remove the child from the chain and free it. */
+ if (lastc == 0)
+ children = c->next;
+ else
+ lastc->next = c->next;
+ free_child (c);
#endif /* RECURSIVEJOBS */
- /* There is now another slot open. */
- if (job_slots_used > 0)
- --job_slots_used;
+ /* There is now another slot open. */
+ if (job_slots_used > 0)
+ --job_slots_used;
- /* If the job failed, and the -k flag was not given, die. */
- if (child_failed && !keep_going_flag)
- die (EXIT_FAILURE);
+ /* If the job failed, and the -k flag was not given, die. */
+ if (child_failed && !keep_going_flag)
+ die (EXIT_FAILURE);
- (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask));
+ (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask));
- return 1;
+ return 1;
}
/* VMS:
@@ -232,67 +227,71 @@ static unsigned short int chan= 0;
static void
reEnableAst(void)
{
- lib$enable_ctrl (&oldCtrlMask,0);
+ lib$enable_ctrl (&oldCtrlMask,0);
}
static int
astYHandler (void)
{
- struct child *c;
- for (c = children; c != 0; c = c->next)
- sys$delprc (&c->pid, 0, 0);
- ctrlYPressed= 1;
- kill (getpid(),SIGQUIT);
- return SS$_NORMAL;
+ struct child *c;
+ for (c = children; c != 0; c = c->next)
+ sys$delprc (&c->pid, 0, 0);
+ ctrlYPressed= 1;
+ kill (getpid(),SIGQUIT);
+ return SS$_NORMAL;
}
static void
tryToSetupYAst(void)
{
- $DESCRIPTOR(inputDsc,"SYS$COMMAND");
- int status;
- struct {
- short int status, count;
- int dvi;
- } iosb;
- unsigned short int loc_chan;
-
- setupYAstTried++;
-
- if (chan)
- loc_chan= chan;
- else {
- status= sys$assign(&inputDsc,&loc_chan,0,0);
- if (!(status&SS$_NORMAL)) {
- lib$signal(status);
- return;
- }
- }
- status= sys$qiow (0, loc_chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
- astYHandler,0,0,0,0,0);
- if (status==SS$_NORMAL)
- status= iosb.status;
- if (status!=SS$_NORMAL) {
- if (!chan)
- sys$dassgn(loc_chan);
- if (status!=SS$_ILLIOFUNC && status!=SS$_NOPRIV)
- lib$signal(status);
- return;
- }
-
- /* called from AST handler ? */
- if (setupYAstTried>1)
- return;
- if (atexit(reEnableAst))
- fprintf (stderr,
- _("-warning, you may have to re-enable CTRL-Y handling from DCL.\n"));
- status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask);
- if (!(status&SS$_NORMAL)) {
- lib$signal(status);
- return;
- }
- if (!chan)
- chan = loc_chan;
+ $DESCRIPTOR(inputDsc,"SYS$COMMAND");
+ int status;
+ struct {
+ short int status, count;
+ int dvi;
+ } iosb;
+ unsigned short int loc_chan;
+
+ setupYAstTried++;
+
+ if (chan)
+ loc_chan= chan;
+ else
+ {
+ status= sys$assign(&inputDsc,&loc_chan,0,0);
+ if (!(status&SS$_NORMAL))
+ {
+ lib$signal(status);
+ return;
+ }
+ }
+ status= sys$qiow (0, loc_chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
+ astYHandler,0,0,0,0,0);
+ if (status==SS$_NORMAL)
+ status= iosb.status;
+ if (status!=SS$_NORMAL)
+ {
+ if (!chan)
+ sys$dassgn(loc_chan);
+ if (status!=SS$_ILLIOFUNC && status!=SS$_NOPRIV)
+ lib$signal(status);
+ return;
+ }
+
+ /* called from AST handler ? */
+ if (setupYAstTried>1)
+ return;
+ if (atexit(reEnableAst))
+ fprintf (stderr,
+ _("-warning, you may have to re-enable CTRL-Y handling from DCL.\n"));
+ status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask);
+ if (!(status&SS$_NORMAL))
+ {
+ lib$signal(status);
+ return;
+ }
+ if (!chan)
+ chan = loc_chan;
}
int
@@ -349,63 +348,61 @@ child_execute_job (char *argv, struct child *child)
continue;
}
switch (*p)
- {
- case '#':
- *p-- = 0;
- *q-- = 0;
- break;
- case '\\':
- p++;
- if (*p == '\n')
- p++;
- if (isspace ((unsigned char)*p))
- {
- do { p++; } while (isspace ((unsigned char)*p));
- p--;
- }
- *q = *p;
- break;
- case '<':
- p = vms_redirect (&ifiledsc, ifile, p);
- *q = ' ';
- have_redirection = 1;
- break;
- case '>':
- have_redirection = 1;
- if (*(p-1) == '2')
- {
- q--;
- if (strncmp (p, ">&1", 3) == 0)
- {
- p += 3;
- strcpy (efile, "sys$output");
- efiledsc.dsc$w_length = strlen(efile);
- efiledsc.dsc$a_pointer = efile;
- efiledsc.dsc$b_dtype = DSC$K_DTYPE_T;
- efiledsc.dsc$b_class = DSC$K_CLASS_S;
- }
- else
- {
- p = vms_redirect (&efiledsc, efile, p);
- }
- }
- else
- {
- if (*(p+1) == '>')
- {
- have_append = 1;
- p += 1;
- }
- p = vms_redirect (&ofiledsc, ofile, p);
- }
- *q = ' ';
- break;
- case '\n':
- have_newline = 1;
- default:
- *q = *p;
- break;
- }
+ {
+ case '#':
+ *p-- = 0;
+ *q-- = 0;
+ break;
+ case '\\':
+ p++;
+ if (*p == '\n')
+ p++;
+ if (isspace ((unsigned char)*p))
+ {
+ do { p++; } while (isspace ((unsigned char)*p));
+ p--;
+ }
+ *q = *p;
+ break;
+ case '<':
+ p = vms_redirect (&ifiledsc, ifile, p);
+ *q = ' ';
+ have_redirection = 1;
+ break;
+ case '>':
+ have_redirection = 1;
+ if (*(p-1) == '2')
+ {
+ q--;
+ if (strncmp (p, ">&1", 3) == 0)
+ {
+ p += 3;
+ strcpy (efile, "sys$output");
+ efiledsc.dsc$w_length = strlen(efile);
+ efiledsc.dsc$a_pointer = efile;
+ efiledsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ efiledsc.dsc$b_class = DSC$K_CLASS_S;
+ }
+ else
+ p = vms_redirect (&efiledsc, efile, p);
+ }
+ else
+ {
+ if (*(p+1) == '>')
+ {
+ have_append = 1;
+ p += 1;
+ }
+ p = vms_redirect (&ofiledsc, ofile, p);
+ }
+ *q = ' ';
+ break;
+ case '\n':
+ have_newline = 1;
+ default:
+ *q = *p;
+ break;
+ }
}
*q = *p;
while (isspace ((unsigned char)*--q))
@@ -422,55 +419,55 @@ child_execute_job (char *argv, struct child *child)
p = cmd + 8;
if ((*(p) == 'c')
- && (*(p+1) == 'd')
- && ((*(p+2) == ' ') || (*(p+2) == '\t')))
- {
- p += 3;
- while ((*p == ' ') || (*p == '\t'))
- p++;
- DB (DB_JOBS, (_("BUILTIN CD %s\n"), p));
- if (chdir (p))
- return 0;
- else
- return 1;
- }
+ && (*(p+1) == 'd')
+ && ((*(p+2) == ' ') || (*(p+2) == '\t')))
+ {
+ p += 3;
+ while ((*p == ' ') || (*p == '\t'))
+ p++;
+ DB (DB_JOBS, (_("BUILTIN CD %s\n"), p));
+ if (chdir (p))
+ return 0;
+ else
+ return 1;
+ }
else if ((*(p) == 'r')
- && (*(p+1) == 'm')
- && ((*(p+2) == ' ') || (*(p+2) == '\t')))
- {
- int in_arg;
-
- /* rm */
- p += 3;
- while ((*p == ' ') || (*p == '\t'))
- p++;
- in_arg = 1;
-
- DB (DB_JOBS, (_("BUILTIN RM %s\n"), p));
- while (*p)
- {
- switch (*p)
- {
- case ' ':
- case '\t':
- if (in_arg)
- {
- *p++ = ';';
- in_arg = 0;
- }
- break;
- default:
- break;
- }
- p++;
- }
- }
+ && (*(p+1) == 'm')
+ && ((*(p+2) == ' ') || (*(p+2) == '\t')))
+ {
+ int in_arg;
+
+ /* rm */
+ p += 3;
+ while ((*p == ' ') || (*p == '\t'))
+ p++;
+ in_arg = 1;
+
+ DB (DB_JOBS, (_("BUILTIN RM %s\n"), p));
+ while (*p)
+ {
+ switch (*p)
+ {
+ case ' ':
+ case '\t':
+ if (in_arg)
+ {
+ *p++ = ';';
+ in_arg = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ p++;
+ }
+ }
else
- {
- printf(_("Unknown builtin command '%s'\n"), cmd);
- fflush(stdout);
- return 0;
- }
+ {
+ printf (_("Unknown builtin command '%s'\n"), cmd);
+ fflush (stdout);
+ return 0;
+ }
}
/* Create a *.com file if either the command is too long for
@@ -485,56 +482,54 @@ child_execute_job (char *argv, struct child *child)
FILE *outfile;
char c;
char *sep;
- int alevel = 0; /* apostrophe level */
+ int alevel = 0; /* apostrophe level */
if (strlen (cmd) == 0)
- {
- printf (_("Error, empty command\n"));
- fflush (stdout);
- return 0;
- }
+ {
+ printf (_("Error, empty command\n"));
+ fflush (stdout);
+ return 0;
+ }
- outfile = open_tmpfile (&child->comname, "sys$scratch:CMDXXXXXX.COM");
+ outfile = output_tmpfile (&child->comname, "sys$scratch:CMDXXXXXX.COM");
if (outfile == 0)
- pfatal_with_name (_("fopen (temporary file)"));
+ pfatal_with_name (_("fopen (temporary file)"));
comnamelen = strlen (child->comname);
if (ifile[0])
- {
- fprintf (outfile, "$ assign/user %s sys$input\n", ifile);
+ {
+ fprintf (outfile, "$ assign/user %s sys$input\n", ifile);
DB (DB_JOBS, (_("Redirected input from %s\n"), ifile));
- ifiledsc.dsc$w_length = 0;
- }
+ ifiledsc.dsc$w_length = 0;
+ }
if (efile[0])
- {
- fprintf (outfile, "$ define sys$error %s\n", efile);
+ {
+ fprintf (outfile, "$ define sys$error %s\n", efile);
DB (DB_JOBS, (_("Redirected error to %s\n"), efile));
- efiledsc.dsc$w_length = 0;
- }
+ efiledsc.dsc$w_length = 0;
+ }
if (ofile[0])
- {
- if (have_append)
- {
- fprintf (outfile, "$ set noon\n");
- fprintf (outfile, "$ define sys$output %.*s\n", comnamelen-3, child->comname);
- DB (DB_JOBS, (_("Append output to %s\n"), ofile));
- ofiledsc.dsc$w_length = 0;
- }
- else
- {
- fprintf (outfile, "$ define sys$output %s\n", ofile);
- DB (DB_JOBS, (_("Redirected output to %s\n"), ofile));
- ofiledsc.dsc$w_length = 0;
- }
- }
+ if (have_append)
+ {
+ fprintf (outfile, "$ set noon\n");
+ fprintf (outfile, "$ define sys$output %.*s\n", comnamelen-3, child->comname);
+ DB (DB_JOBS, (_("Append output to %s\n"), ofile));
+ ofiledsc.dsc$w_length = 0;
+ }
+ else
+ {
+ fprintf (outfile, "$ define sys$output %s\n", ofile);
+ DB (DB_JOBS, (_("Redirected output to %s\n"), ofile));
+ ofiledsc.dsc$w_length = 0;
+ }
p = sep = q = cmd;
for (c = '\n'; c; c = *q++)
- {
- switch (c)
- {
+ {
+ switch (c)
+ {
case '\n':
/* At a newline, skip any whitespace around a leading $
from the command and issue exactly one $ into the DCL. */
@@ -551,8 +546,8 @@ child_execute_job (char *argv, struct child *child)
p = sep = q;
break;
- /* Nice places for line breaks are after strings, after
- comma or space and before slash. */
+ /* Nice places for line breaks are after strings, after
+ comma or space and before slash. */
case '"':
q = vms_handle_apos (q);
sep = q;
@@ -567,25 +562,25 @@ child_execute_job (char *argv, struct child *child)
break;
default:
break;
- }
- if (sep - p > 78)
- {
- /* Enough stuff for a line. */
- fwrite (p, 1, sep - p, outfile);
- p = sep;
- if (*sep)
- {
- /* The command continues. */
- fputc ('-', outfile);
- }
- fputc ('\n', outfile);
- }
- }
+ }
+ if (sep - p > 78)
+ {
+ /* Enough stuff for a line. */
+ fwrite (p, 1, sep - p, outfile);
+ p = sep;
+ if (*sep)
+ {
+ /* The command continues. */
+ fputc ('-', outfile);
+ }
+ fputc ('\n', outfile);
+ }
+ }
if (*p)
{
fwrite (p, 1, --q - p, outfile);
- fputc ('\n', outfile);
+ fputc ('\n', outfile);
}
if (have_append)
@@ -630,66 +625,66 @@ child_execute_job (char *argv, struct child *child)
vms_jobsefnmask |= (1 << (child->efn - 32));
-/*
- LIB$SPAWN [command-string]
- [,input-file]
- [,output-file]
- [,flags]
- [,process-name]
- [,process-id] [,completion-status-address] [,byte-integer-event-flag-num]
- [,AST-address] [,varying-AST-argument]
- [,prompt-string] [,cli] [,table]
-*/
+ /*
+ LIB$SPAWN [command-string]
+ [,input-file]
+ [,output-file]
+ [,flags]
+ [,process-name]
+ [,process-id] [,completion-status-address] [,byte-integer-event-flag-num]
+ [,AST-address] [,varying-AST-argument]
+ [,prompt-string] [,cli] [,table]
+ */
#ifndef DONTWAITFORCHILD
-/*
- * Code to make ctrl+c and ctrl+y working.
- * The problem starts with the synchronous case where after lib$spawn is
- * called any input will go to the child. But with input re-directed,
- * both control characters won't make it to any of the programs, neither
- * the spawning nor to the spawned one. Hence the caller needs to spawn
- * with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr
- * has to follow to simulate the wanted synchronous behaviour.
- * The next problem is ctrl+y which isn't caught by the crtl and
- * therefore isn't converted to SIGQUIT (for a signal handler which is
- * already established). The only way to catch ctrl+y, is an AST
- * assigned to the input channel. But ctrl+y handling of DCL needs to be
- * disabled, otherwise it will handle it. Not to mention the previous
- * ctrl+y handling of DCL needs to be re-established before make exits.
- * One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will
- * make it to the signal handler after the child "normally" terminates.
- * This isn't enough. It seems reasonable for simple command lines like
- * a 'cc foobar.c' spawned in a subprocess but it is unacceptable for
- * spawning make. Therefore we need to abort the process in the AST.
- *
- * Prior to the spawn it is checked if an AST is already set up for
- * ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general
- * this will work except if make is run in a batch environment, but there
- * nobody can press ctrl+y. During the setup the DCL handling of ctrl+y
- * is disabled and an exit handler is established to re-enable it.
- * If the user interrupts with ctrl+y, the assigned AST will fire, force
- * an abort to the subprocess and signal SIGQUIT, which will be caught by
- * the already established handler and will bring us back to common code.
- * After the spawn (now /nowait) a sys$waitfr simulates the /wait and
- * enables the ctrl+y be delivered to this code. And the ctrl+c too,
- * which the crtl converts to SIGINT and which is caught by the common
- * signal handler. Because signals were blocked before entering this code
- * sys$waitfr will always complete and the SIGQUIT will be processed after
- * it (after termination of the current block, somewhere in common code).
- * And SIGINT too will be delayed. That is ctrl+c can only abort when the
- * current command completes. Anyway it's better than nothing :-)
- */
+ /*
+ * Code to make ctrl+c and ctrl+y working.
+ * The problem starts with the synchronous case where after lib$spawn is
+ * called any input will go to the child. But with input re-directed,
+ * both control characters won't make it to any of the programs, neither
+ * the spawning nor to the spawned one. Hence the caller needs to spawn
+ * with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr
+ * has to follow to simulate the wanted synchronous behaviour.
+ * The next problem is ctrl+y which isn't caught by the crtl and
+ * therefore isn't converted to SIGQUIT (for a signal handler which is
+ * already established). The only way to catch ctrl+y, is an AST
+ * assigned to the input channel. But ctrl+y handling of DCL needs to be
+ * disabled, otherwise it will handle it. Not to mention the previous
+ * ctrl+y handling of DCL needs to be re-established before make exits.
+ * One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will
+ * make it to the signal handler after the child "normally" terminates.
+ * This isn't enough. It seems reasonable for simple command lines like
+ * a 'cc foobar.c' spawned in a subprocess but it is unacceptable for
+ * spawning make. Therefore we need to abort the process in the AST.
+ *
+ * Prior to the spawn it is checked if an AST is already set up for
+ * ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general
+ * this will work except if make is run in a batch environment, but there
+ * nobody can press ctrl+y. During the setup the DCL handling of ctrl+y
+ * is disabled and an exit handler is established to re-enable it.
+ * If the user interrupts with ctrl+y, the assigned AST will fire, force
+ * an abort to the subprocess and signal SIGQUIT, which will be caught by
+ * the already established handler and will bring us back to common code.
+ * After the spawn (now /nowait) a sys$waitfr simulates the /wait and
+ * enables the ctrl+y be delivered to this code. And the ctrl+c too,
+ * which the crtl converts to SIGINT and which is caught by the common
+ * signal handler. Because signals were blocked before entering this code
+ * sys$waitfr will always complete and the SIGQUIT will be processed after
+ * it (after termination of the current block, somewhere in common code).
+ * And SIGINT too will be delayed. That is ctrl+c can only abort when the
+ * current command completes. Anyway it's better than nothing :-)
+ */
if (!setupYAstTried)
tryToSetupYAst();
- status = lib$spawn (&cmddsc, /* cmd-string */
- (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */
- (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */
- &spflags, /* flags */
- &pnamedsc, /* proc name */
- &child->pid, &child->cstatus, &child->efn,
- 0, 0,
- 0, 0, 0);
+ status = lib$spawn (&cmddsc, /* cmd-string */
+ (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */
+ (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */
+ &spflags, /* flags */
+ &pnamedsc, /* proc name */
+ &child->pid, &child->cstatus, &child->efn,
+ 0, 0,
+ 0, 0, 0);
if (status & 1)
{
status= sys$waitfr (child->efn);
@@ -697,13 +692,13 @@ child_execute_job (char *argv, struct child *child)
}
#else
status = lib$spawn (&cmddsc,
- (ifiledsc.dsc$w_length == 0)?0:&ifiledsc,
- (ofiledsc.dsc$w_length == 0)?0:&ofiledsc,
- &spflags,
- &pnamedsc,
- &child->pid, &child->cstatus, &child->efn,
- vmsHandleChildTerm, child,
- 0, 0, 0);
+ (ifiledsc.dsc$w_length == 0)?0:&ifiledsc,
+ (ofiledsc.dsc$w_length == 0)?0:&ofiledsc,
+ &spflags,
+ &pnamedsc,
+ &child->pid, &child->cstatus, &child->efn,
+ vmsHandleChildTerm, child,
+ 0, 0, 0);
#endif
if (!(status & 1))