1a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* --------------- Moved here from job.c --------------- 2a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner This file must be #included in job.c, as it accesses static functions. 3a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 4a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerCopyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 5a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner2006 Free Software Foundation, Inc. 6a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerThis file is part of GNU Make. 7a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 8a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is free software; you can redistribute it and/or modify it under the 9a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerterms of the GNU General Public License as published by the Free Software 10a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation; either version 2, or (at your option) any later version. 11a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 12a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is distributed in the hope that it will be useful, but WITHOUT ANY 13a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 14a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerA PARTICULAR PURPOSE. See the GNU General Public License for more details. 15a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 16a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerYou should have received a copy of the GNU General Public License along with 17a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make; see the file COPYING. If not, write to the Free Software 18a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ 19a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 20a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <string.h> 21a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <descrip.h> 22a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <clidef.h> 23a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 24a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerextern char *vmsify PARAMS ((char *name, int type)); 25a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 26a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int vms_jobsefnmask = 0; 27a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 28a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Wait for nchildren children to terminate */ 29a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 30a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnervmsWaitForChildren(int *status) 31a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 32a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (1) 33a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 34a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!vms_jobsefnmask) 35a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 36a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *status = 0; 37a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 38a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 39a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 40a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *status = sys$wflor (32, vms_jobsefnmask); 41a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 42a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 43a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 44a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 45a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Set up IO redirection. */ 46a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 47a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerchar * 48a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervms_redirect (struct dsc$descriptor_s *desc, char *fname, char *ibuf) 49a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 50a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *fptr; 51a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 52a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ibuf++; 53a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (isspace ((unsigned char)*ibuf)) 54a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ibuf++; 55a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fptr = ibuf; 56a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*ibuf && !isspace ((unsigned char)*ibuf)) 57a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ibuf++; 58a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *ibuf = 0; 59a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strcmp (fptr, "/dev/null") != 0) 60a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 61a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strcpy (fname, vmsify (fptr, 0)); 62a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strchr (fname, '.') == 0) 63a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strcat (fname, "."); 64a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 65a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner desc->dsc$w_length = strlen(fname); 66a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner desc->dsc$a_pointer = fname; 67a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner desc->dsc$b_dtype = DSC$K_DTYPE_T; 68a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner desc->dsc$b_class = DSC$K_CLASS_S; 69a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 70a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*fname == 0) 71a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("Warning: Empty redirection\n")); 72a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return ibuf; 73a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 74a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 75a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 76a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* found apostrophe at (p-1) 77a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner inc p until after closing apostrophe. 78a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 79a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 80a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerchar * 81a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervms_handle_apos (char *p) 82a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 83a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int alast; 84a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 85a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define SEPCHARS ",/()= " 86a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 87a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner alast = 0; 88a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 89a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*p != 0) 90a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 91a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '"') 92a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 93a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (alast) 94a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 95a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner alast = 0; 96a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 97a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 98a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 99a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 100a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 101a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strchr (SEPCHARS, *p)) 102a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 103a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner alast = 1; 104a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 105a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 106a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 107a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 108a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 109a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 110a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return p; 111a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 112a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 113a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* This is called as an AST when a child process dies (it won't get 114a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner interrupted by anything except a higher level AST). 115a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner*/ 116a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint 117a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnervmsHandleChildTerm(struct child *child) 118a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 119a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int status; 120a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct child *lastc, *c; 121a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int child_failed; 122a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 123a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vms_jobsefnmask &= ~(1 << (child->efn - 32)); 124a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 125a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$free_ef(&child->efn); 126a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 127a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) sigblock (fatal_signal_mask); 128a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 129a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0)); 130a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 131a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Search for a child matching the deceased one. */ 132a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lastc = 0; 133a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ 134a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (c = children; c != 0 && c != child; lastc = c, c = c->next) 135a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ; 136a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 137a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c = child; 138a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 139a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 140a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (child_failed && !c->noerror && !ignore_errors_flag) 141a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 142a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The commands failed. Write an error message, 143a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner delete non-precious targets, and abort. */ 144a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child_error (c->file->name, c->cstatus, 0, 0, 0); 145a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c->file->update_status = 1; 146a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner delete_child_targets (c); 147a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 148a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 149a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 150a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (child_failed) 151a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 152a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The commands failed, but we don't care. */ 153a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child_error (c->file->name, c->cstatus, 0, 0, 1); 154a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child_failed = 0; 155a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 156a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 157a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ 158a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If there are more commands to run, try to start them. */ 159a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner start_job (c); 160a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 161a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (c->file->command_state) 162a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 163a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case cs_running: 164a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Successfully started. */ 165a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 166a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 167a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case cs_finished: 168a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (c->file->update_status != 0) { 169a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We failed to start the commands. */ 170a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner delete_child_targets (c); 171a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 172a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 173a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 174a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 175a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner error (NILF, _("internal error: `%s' command_state"), 176a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c->file->name); 177a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner abort (); 178a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 179a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 180a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* RECURSIVEJOBS */ 181a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 182a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 183a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Set the state flag to say the commands have finished. */ 184a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c->file->command_state = cs_finished; 185a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner notice_finished_file (c->file); 186a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 187a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ 188a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Remove the child from the chain and free it. */ 189a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (lastc == 0) 190a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner children = c->next; 191a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 192a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lastc->next = c->next; 193a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free_child (c); 194a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* RECURSIVEJOBS */ 195a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 196a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* There is now another slot open. */ 197a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (job_slots_used > 0) 198a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner --job_slots_used; 199a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 200a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If the job failed, and the -k flag was not given, die. */ 201a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (child_failed && !keep_going_flag) 202a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner die (EXIT_FAILURE); 203a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 204a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask)); 205a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 206a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 1; 207a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 208a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 209a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* VMS: 210a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Spawn a process executing the command in ARGV and return its pid. */ 211a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 212a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define MAXCMDLEN 200 213a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 214a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* local helpers to make ctrl+c and ctrl+y working, see below */ 215a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <iodef.h> 216a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <libclidef.h> 217a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <ssdef.h> 218a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 219a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int ctrlMask= LIB$M_CLI_CTRLY; 220a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int oldCtrlMask; 221a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int setupYAstTried= 0; 222a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int pidToAbort= 0; 223a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int chan= 0; 224a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 225a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 226a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerreEnableAst(void) 227a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 228a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$enable_ctrl (&oldCtrlMask,0); 229a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 230a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 231a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 232a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerastHandler (void) 233a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 234a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (pidToAbort) { 235a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sys$forcex (&pidToAbort, 0, SS$_ABORT); 236a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pidToAbort= 0; 237a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 238a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner kill (getpid(),SIGQUIT); 239a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 240a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 241a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 242a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnertryToSetupYAst(void) 243a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 244a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner $DESCRIPTOR(inputDsc,"SYS$COMMAND"); 245a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int status; 246a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct { 247a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner short int status, count; 248a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int dvi; 249a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } iosb; 250a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 251a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setupYAstTried++; 252a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 253a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!chan) { 254a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status= sys$assign(&inputDsc,&chan,0,0); 255a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!(status&SS$_NORMAL)) { 256a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$signal(status); 257a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 258a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 259a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 260a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0, 261a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner astHandler,0,0,0,0,0); 262a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (status==SS$_NORMAL) 263a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status= iosb.status; 264a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (status==SS$_ILLIOFUNC || status==SS$_NOPRIV) { 265a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sys$dassgn(chan); 266a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef CTRLY_ENABLED_ANYWAY 267a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fprintf (stderr, 268a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner _("-warning, CTRL-Y will leave sub-process(es) around.\n")); 269a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 270a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 271a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 272a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 273a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (!(status&SS$_NORMAL)) { 274a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sys$dassgn(chan); 275a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$signal(status); 276a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 277a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 278a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 279a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* called from AST handler ? */ 280a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (setupYAstTried>1) 281a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 282a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (atexit(reEnableAst)) 283a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fprintf (stderr, 284a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner _("-warning, you may have to re-enable CTRL-Y handling from DCL.\n")); 285a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask); 286a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!(status&SS$_NORMAL)) { 287a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$signal(status); 288a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 289a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 290a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 291a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 292a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint 293a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerchild_execute_job (char *argv, struct child *child) 294a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 295a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int i; 296a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static struct dsc$descriptor_s cmddsc; 297a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static struct dsc$descriptor_s pnamedsc; 298a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static struct dsc$descriptor_s ifiledsc; 299a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static struct dsc$descriptor_s ofiledsc; 300a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static struct dsc$descriptor_s efiledsc; 301a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int have_redirection = 0; 302a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int have_newline = 0; 303a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 304a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int spflags = CLI$M_NOWAIT; 305a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int status; 306a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *cmd = alloca (strlen (argv) + 512), *p, *q; 307a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char ifile[256], ofile[256], efile[256]; 308a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *comname = 0; 309a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char procname[100]; 310a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int in_string; 311a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 312a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Parse IO redirection. */ 313a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 314a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ifile[0] = 0; 315a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ofile[0] = 0; 316a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efile[0] = 0; 317a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 318a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, ("child_execute_job (%s)\n", argv)); 319a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 320a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (isspace ((unsigned char)*argv)) 321a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner argv++; 322a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 323a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*argv == 0) 324a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 325a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 326a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff); 327a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pnamedsc.dsc$w_length = strlen(procname); 328a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pnamedsc.dsc$a_pointer = procname; 329a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pnamedsc.dsc$b_dtype = DSC$K_DTYPE_T; 330a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pnamedsc.dsc$b_class = DSC$K_CLASS_S; 331a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 332a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner in_string = 0; 333a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Handle comments and redirection. */ 334a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = argv, q = cmd; *p; p++, q++) 335a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 336a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '"') 337a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner in_string = !in_string; 338a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (in_string) 339a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 340a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = *p; 341a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 342a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 343a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (*p) 344a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 345a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '#': 346a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *p-- = 0; 347a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q-- = 0; 348a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 349a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '\\': 350a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 351a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '\n') 352a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 353a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (isspace ((unsigned char)*p)) 354a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 355a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner do { p++; } while (isspace ((unsigned char)*p)); 356a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p--; 357a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 358a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = *p; 359a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 360a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '<': 361a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = vms_redirect (&ifiledsc, ifile, p); 362a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = ' '; 363a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner have_redirection = 1; 364a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 365a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '>': 366a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner have_redirection = 1; 367a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*(p-1) == '2') 368a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 369a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner q--; 370a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strncmp (p, ">&1", 3) == 0) 371a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 372a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p += 3; 373a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strcpy (efile, "sys$output"); 374a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efiledsc.dsc$w_length = strlen(efile); 375a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efiledsc.dsc$a_pointer = efile; 376a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efiledsc.dsc$b_dtype = DSC$K_DTYPE_T; 377a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efiledsc.dsc$b_class = DSC$K_CLASS_S; 378a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 379a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 380a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 381a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = vms_redirect (&efiledsc, efile, p); 382a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 383a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 384a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 385a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 386a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = vms_redirect (&ofiledsc, ofile, p); 387a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 388a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = ' '; 389a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 390a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '\n': 391a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner have_newline = 1; 392a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 393a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = *p; 394a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 395a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 396a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 397a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = *p; 398a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (isspace ((unsigned char)*--q)) 399a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *q = '\0'; 400a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 401a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strncmp (cmd, "builtin_", 8) == 0) 402a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 403a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child->pid = 270163; 404a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child->efn = 0; 405a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child->cstatus = 1; 406a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 407a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("BUILTIN [%s][%s]\n"), cmd, cmd+8)); 408a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 409a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = cmd + 8; 410a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 411a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((*(p) == 'c') 412a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && (*(p+1) == 'd') 413a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && ((*(p+2) == ' ') || (*(p+2) == '\t'))) 414a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 415a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p += 3; 416a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while ((*p == ' ') || (*p == '\t')) 417a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 418a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("BUILTIN CD %s\n"), p)); 419a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (chdir (p)) 420a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 421a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 422a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 1; 423a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 424a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if ((*(p) == 'r') 425a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && (*(p+1) == 'm') 426a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && ((*(p+2) == ' ') || (*(p+2) == '\t'))) 427a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 428a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int in_arg; 429a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 430a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* rm */ 431a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p += 3; 432a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while ((*p == ' ') || (*p == '\t')) 433a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 434a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner in_arg = 1; 435a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 436a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("BUILTIN RM %s\n"), p)); 437a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*p) 438a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 439a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (*p) 440a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 441a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case ' ': 442a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '\t': 443a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (in_arg) 444a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 445a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *p++ = ';'; 446a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner in_arg = 0; 447a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 448a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 449a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 450a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 451a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 452a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 453a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 454a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 455a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 456a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 457a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf(_("Unknown builtin command '%s'\n"), cmd); 458a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fflush(stdout); 459a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 460a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 461a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 462a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 463a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Create a *.com file if either the command is too long for 464a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner lib$spawn, or the command contains a newline, or if redirection 465a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner is desired. Forcing commands with newlines into DCLs allows to 466a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner store search lists on user mode logicals. */ 467a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 468a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strlen (cmd) > MAXCMDLEN 469a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner || (have_redirection != 0) 470a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner || (have_newline != 0)) 471a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 472a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner FILE *outfile; 473a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char c; 474a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *sep; 475a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int alevel = 0; /* apostrophe level */ 476a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 477a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strlen (cmd) == 0) 478a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 479a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("Error, empty command\n")); 480a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fflush (stdout); 481a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 482a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 483a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 484a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner outfile = open_tmpfile (&comname, "sys$scratch:CMDXXXXXX.COM"); 485a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (outfile == 0) 486a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pfatal_with_name (_("fopen (temporary file)")); 487a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 488a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (ifile[0]) 489a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 490a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fprintf (outfile, "$ assign/user %s sys$input\n", ifile); 491a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("Redirected input from %s\n"), ifile)); 492a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ifiledsc.dsc$w_length = 0; 493a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 494a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 495a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (efile[0]) 496a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 497a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fprintf (outfile, "$ define sys$error %s\n", efile); 498a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("Redirected error to %s\n"), efile)); 499a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner efiledsc.dsc$w_length = 0; 500a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 501a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 502a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (ofile[0]) 503a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 504a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fprintf (outfile, "$ define sys$output %s\n", ofile); 505a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("Redirected output to %s\n"), ofile)); 506a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ofiledsc.dsc$w_length = 0; 507a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 508a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 509a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = sep = q = cmd; 510a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (c = '\n'; c; c = *q++) 511a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 512a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (c) 513a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 514a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '\n': 515a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* At a newline, skip any whitespace around a leading $ 516a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner from the command and issue exactly one $ into the DCL. */ 517a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (isspace ((unsigned char)*p)) 518a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 519a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '$') 520a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 521a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (isspace ((unsigned char)*p)) 522a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p++; 523a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fwrite (p, 1, q - p, outfile); 524a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputc ('$', outfile); 525a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputc (' ', outfile); 526a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Reset variables. */ 527a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = sep = q; 528a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 529a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 530a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Nice places for line breaks are after strings, after 531a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner comma or space and before slash. */ 532a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '"': 533a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner q = vms_handle_apos (q); 534a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sep = q; 535a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 536a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case ',': 537a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case ' ': 538a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sep = q; 539a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 540a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '/': 541a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case '\0': 542a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sep = q - 1; 543a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 544a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 545a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 546a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 547a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (sep - p > 78) 548a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 549a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Enough stuff for a line. */ 550a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fwrite (p, 1, sep - p, outfile); 551a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = sep; 552a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*sep) 553a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 554a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The command continues. */ 555a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputc ('-', outfile); 556a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 557a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputc ('\n', outfile); 558a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 559a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 560a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 561a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fwrite (p, 1, q - p, outfile); 562a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputc ('\n', outfile); 563a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 564a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fclose (outfile); 565a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 566a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sprintf (cmd, "$ @%s", comname); 567a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 568a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DB (DB_JOBS, (_("Executing %s instead\n"), cmd)); 569a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 570a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 571a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner cmddsc.dsc$w_length = strlen(cmd); 572a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner cmddsc.dsc$a_pointer = cmd; 573a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner cmddsc.dsc$b_dtype = DSC$K_DTYPE_T; 574a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner cmddsc.dsc$b_class = DSC$K_CLASS_S; 575a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 576a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner child->efn = 0; 577a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (child->efn < 32 || child->efn > 63) 578a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 579a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status = lib$get_ef ((unsigned long *)&child->efn); 580a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!(status & 1)) 581a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 582a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 583a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 584a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sys$clref (child->efn); 585a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 586a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vms_jobsefnmask |= (1 << (child->efn - 32)); 587a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 588a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* 589a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner LIB$SPAWN [command-string] 590a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,input-file] 591a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,output-file] 592a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,flags] 593a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,process-name] 594a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,process-id] [,completion-status-address] [,byte-integer-event-flag-num] 595a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,AST-address] [,varying-AST-argument] 596a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner [,prompt-string] [,cli] [,table] 597a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner*/ 598a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 599a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef DONTWAITFORCHILD 600a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* 601a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Code to make ctrl+c and ctrl+y working. 602a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * The problem starts with the synchronous case where after lib$spawn is 603a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * called any input will go to the child. But with input re-directed, 604a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * both control characters won't make it to any of the programs, neither 605a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * the spawning nor to the spawned one. Hence the caller needs to spawn 606a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr 607a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * has to follow to simulate the wanted synchronous behaviour. 608a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * The next problem is ctrl+y which isn't caught by the crtl and 609a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * therefore isn't converted to SIGQUIT (for a signal handler which is 610a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * already established). The only way to catch ctrl+y, is an AST 611a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * assigned to the input channel. But ctrl+y handling of DCL needs to be 612a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * disabled, otherwise it will handle it. Not to mention the previous 613a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * ctrl+y handling of DCL needs to be re-established before make exits. 614a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will 615a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * make it to the signal handler after the child "normally" terminates. 616a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * This isn't enough. It seems reasonable for simple command lines like 617a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * a 'cc foobar.c' spawned in a subprocess but it is unacceptable for 618a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * spawning make. Therefore we need to abort the process in the AST. 619a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * 620a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Prior to the spawn it is checked if an AST is already set up for 621a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general 622a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * this will work except if make is run in a batch environment, but there 623a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * nobody can press ctrl+y. During the setup the DCL handling of ctrl+y 624a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * is disabled and an exit handler is established to re-enable it. 625a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * If the user interrupts with ctrl+y, the assigned AST will fire, force 626a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * an abort to the subprocess and signal SIGQUIT, which will be caught by 627a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * the already established handler and will bring us back to common code. 628a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * After the spawn (now /nowait) a sys$waitfr simulates the /wait and 629a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * enables the ctrl+y be delivered to this code. And the ctrl+c too, 630a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * which the crtl converts to SIGINT and which is caught by the common 631a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * signal handler. Because signals were blocked before entering this code 632a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * sys$waitfr will always complete and the SIGQUIT will be processed after 633a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * it (after termination of the current block, somewhere in common code). 634a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * And SIGINT too will be delayed. That is ctrl+c can only abort when the 635a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * current command completes. Anyway it's better than nothing :-) 636a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 637a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 638a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!setupYAstTried) 639a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner tryToSetupYAst(); 640a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status = lib$spawn (&cmddsc, /* cmd-string */ 641a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */ 642a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */ 643a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &spflags, /* flags */ 644a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &pnamedsc, /* proc name */ 645a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &child->pid, &child->cstatus, &child->efn, 646a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 0, 0, 647a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 0, 0, 0); 648a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (status & 1) 649a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 650a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pidToAbort= child->pid; 651a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status= sys$waitfr (child->efn); 652a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pidToAbort= 0; 653a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vmsHandleChildTerm(child); 654a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 655a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 656a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner status = lib$spawn (&cmddsc, 657a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, 658a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, 659a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &spflags, 660a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &pnamedsc, 661a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &child->pid, &child->cstatus, &child->efn, 662a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vmsHandleChildTerm, child, 663a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 0, 0, 0); 664a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 665a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 666a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!(status & 1)) 667a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 668a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("Error spawning, %d\n") ,status); 669a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fflush (stdout); 670a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (status) 671a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 672a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case 0x1c: 673a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner errno = EPROCLIM; 674a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 675a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 676a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner errno = EFAIL; 677a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 678a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 679a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 680a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (comname && !ISDB (DB_JOBS)) 681a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unlink (comname); 682a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 683a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return (status & 1); 684a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 685