1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)sem.c 5.22 (Berkeley) 11/06/91"; 10 #endif /* not lint */ 11 12 #include <sys/param.h> 13 #include <sys/ioctl.h> 14 #include <sys/stat.h> 15 #include <errno.h> 16 #include <fcntl.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <unistd.h> 20 #if __STDC__ 21 # include <stdarg.h> 22 #else 23 # include <varargs.h> 24 #endif 25 26 #include "csh.h" 27 #include "proc.h" 28 #include "extern.h" 29 30 static void vffree __P((int)); 31 static Char *splicepipe __P((struct command *t, Char *)); 32 static void doio __P((struct command *t, int *, int *)); 33 static void chkclob __P((char *)); 34 35 void 36 execute(t, wanttty, pipein, pipeout) 37 register struct command *t; 38 int wanttty, *pipein, *pipeout; 39 { 40 bool forked = 0; 41 struct biltins *bifunc; 42 int pid = 0; 43 int pv[2]; 44 45 static sigset_t csigmask; 46 47 static sigset_t ocsigmask; 48 static int onosigchld = 0; 49 static int nosigchld = 0; 50 51 if (t == 0) 52 return; 53 54 if (t->t_dflg & F_AMPERSAND) 55 wanttty = 0; 56 switch (t->t_dtyp) { 57 58 case NODE_COMMAND: 59 if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) 60 (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); 61 if ((t->t_dflg & F_REPEAT) == 0) 62 Dfix(t); /* $ " ' \ */ 63 if (t->t_dcom[0] == 0) 64 return; 65 /* fall into... */ 66 67 case NODE_PAREN: 68 if (t->t_dflg & F_PIPEOUT) 69 mypipe(pipeout); 70 /* 71 * Must do << early so parent will know where input pointer should be. 72 * If noexec then this is all we do. 73 */ 74 if (t->t_dflg & F_READ) { 75 (void) close(0); 76 heredoc(t->t_dlef); 77 if (noexec) 78 (void) close(0); 79 } 80 81 set(STRstatus, Strsave(STR0)); 82 83 /* 84 * This mess is the necessary kludge to handle the prefix builtins: 85 * nice, nohup, time. These commands can also be used by themselves, 86 * and this is not handled here. This will also work when loops are 87 * parsed. 88 */ 89 while (t->t_dtyp == NODE_COMMAND) 90 if (eq(t->t_dcom[0], STRnice)) 91 if (t->t_dcom[1]) 92 if (strchr("+-", t->t_dcom[1][0])) 93 if (t->t_dcom[2]) { 94 setname("nice"); 95 t->t_nice = 96 getn(t->t_dcom[1]); 97 lshift(t->t_dcom, 2); 98 t->t_dflg |= F_NICE; 99 } 100 else 101 break; 102 else { 103 t->t_nice = 4; 104 lshift(t->t_dcom, 1); 105 t->t_dflg |= F_NICE; 106 } 107 else 108 break; 109 else if (eq(t->t_dcom[0], STRnohup)) 110 if (t->t_dcom[1]) { 111 t->t_dflg |= F_NOHUP; 112 lshift(t->t_dcom, 1); 113 } 114 else 115 break; 116 else if (eq(t->t_dcom[0], STRtime)) 117 if (t->t_dcom[1]) { 118 t->t_dflg |= F_TIME; 119 lshift(t->t_dcom, 1); 120 } 121 else 122 break; 123 else 124 break; 125 126 /* is it a command */ 127 if (t->t_dtyp == NODE_COMMAND) { 128 /* 129 * Check if we have a builtin function and remember which one. 130 */ 131 bifunc = isbfunc(t); 132 if (noexec) { 133 /* 134 * Continue for builtins that are part of the scripting language 135 */ 136 if (bifunc->bfunct != dobreak && bifunc->bfunct != docontin && 137 bifunc->bfunct != doelse && bifunc->bfunct != doend && 138 bifunc->bfunct != doforeach && bifunc->bfunct != dogoto && 139 bifunc->bfunct != doif && bifunc->bfunct != dorepeat && 140 bifunc->bfunct != doswbrk && bifunc->bfunct != doswitch && 141 bifunc->bfunct != dowhile && bifunc->bfunct != dozip) 142 break; 143 } 144 } 145 else { /* not a command */ 146 bifunc = NULL; 147 if (noexec) 148 break; 149 } 150 151 /* 152 * We fork only if we are timed, or are not the end of a parenthesized 153 * list and not a simple builtin function. Simple meaning one that is 154 * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not 155 * fork in some of these cases. 156 */ 157 /* 158 * Prevent forking cd, pushd, popd, chdir cause this will cause the 159 * shell not to change dir! 160 */ 161 if (bifunc && (bifunc->bfunct == dochngd || 162 bifunc->bfunct == dopushd || 163 bifunc->bfunct == dopopd)) 164 t->t_dflg &= ~(F_NICE); 165 if (((t->t_dflg & F_TIME) || (t->t_dflg & F_NOFORK) == 0 && 166 (!bifunc || t->t_dflg & 167 (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP))) || 168 /* 169 * We have to fork for eval too. 170 */ 171 (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 && 172 bifunc->bfunct == doeval)) 173 if (t->t_dtyp == NODE_PAREN || 174 t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) { 175 forked++; 176 /* 177 * We need to block SIGCHLD here, so that if the process does 178 * not die before we can set the process group 179 */ 180 if (wanttty >= 0 && !nosigchld) { 181 csigmask = sigblock(sigmask(SIGCHLD)); 182 nosigchld = 1; 183 } 184 185 pid = pfork(t, wanttty); 186 if (pid == 0 && nosigchld) { 187 (void) sigsetmask(csigmask); 188 nosigchld = 0; 189 } 190 else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) 191 backpid = pid; 192 193 } 194 else { 195 int ochild, osetintr, ohaderr, odidfds; 196 int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp; 197 sigset_t omask; 198 199 /* 200 * Prepare for the vfork by saving everything that the child 201 * corrupts before it exec's. Note that in some signal 202 * implementations which keep the signal info in user space 203 * (e.g. Sun's) it will also be necessary to save and restore 204 * the current sigvec's for the signals the child touches 205 * before it exec's. 206 */ 207 if (wanttty >= 0 && !nosigchld && !noexec) { 208 csigmask = sigblock(sigmask(SIGCHLD)); 209 nosigchld = 1; 210 } 211 omask = sigblock(sigmask(SIGCHLD) | sigmask(SIGINT)); 212 ochild = child; 213 osetintr = setintr; 214 ohaderr = haderr; 215 odidfds = didfds; 216 oSHIN = SHIN; 217 oSHOUT = SHOUT; 218 oSHERR = SHERR; 219 oOLDSTD = OLDSTD; 220 otpgrp = tpgrp; 221 ocsigmask = csigmask; 222 onosigchld = nosigchld; 223 Vsav = Vdp = 0; 224 Vexpath = 0; 225 Vt = 0; 226 pid = vfork(); 227 228 if (pid < 0) { 229 (void) sigsetmask(omask); 230 stderror(ERR_NOPROC); 231 } 232 forked++; 233 if (pid) { /* parent */ 234 child = ochild; 235 setintr = osetintr; 236 haderr = ohaderr; 237 didfds = odidfds; 238 SHIN = oSHIN; 239 SHOUT = oSHOUT; 240 SHERR = oSHERR; 241 OLDSTD = oOLDSTD; 242 tpgrp = otpgrp; 243 csigmask = ocsigmask; 244 nosigchld = onosigchld; 245 246 xfree((ptr_t) Vsav); 247 Vsav = 0; 248 xfree((ptr_t) Vdp); 249 Vdp = 0; 250 xfree((ptr_t) Vexpath); 251 Vexpath = 0; 252 blkfree((Char **) Vt); 253 Vt = 0; 254 /* this is from pfork() */ 255 palloc(pid, t); 256 (void) sigsetmask(omask); 257 } 258 else { /* child */ 259 /* this is from pfork() */ 260 int pgrp; 261 bool ignint = 0; 262 263 if (nosigchld) { 264 (void) sigsetmask(csigmask); 265 nosigchld = 0; 266 } 267 268 if (setintr) 269 ignint = 270 (tpgrp == -1 && 271 (t->t_dflg & F_NOINTERRUPT)) 272 || gointr && eq(gointr, STRminus); 273 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); 274 child++; 275 if (setintr) { 276 setintr = 0; 277 if (ignint) { 278 (void) signal(SIGINT, SIG_IGN); 279 (void) signal(SIGQUIT, SIG_IGN); 280 } 281 else { 282 (void) signal(SIGINT, vffree); 283 (void) signal(SIGQUIT, SIG_DFL); 284 } 285 286 if (wanttty >= 0) { 287 (void) signal(SIGTSTP, SIG_DFL); 288 (void) signal(SIGTTIN, SIG_DFL); 289 (void) signal(SIGTTOU, SIG_DFL); 290 } 291 292 (void) signal(SIGTERM, parterm); 293 } 294 else if (tpgrp == -1 && 295 (t->t_dflg & F_NOINTERRUPT)) { 296 (void) signal(SIGINT, SIG_IGN); 297 (void) signal(SIGQUIT, SIG_IGN); 298 } 299 300 pgetty(wanttty, pgrp); 301 if (t->t_dflg & F_NOHUP) 302 (void) signal(SIGHUP, SIG_IGN); 303 if (t->t_dflg & F_NICE) 304 (void) setpriority(PRIO_PROCESS, 0, t->t_nice); 305 } 306 307 } 308 if (pid != 0) { 309 /* 310 * It would be better if we could wait for the whole job when we 311 * knew the last process had been started. Pwait, in fact, does 312 * wait for the whole job anyway, but this test doesn't really 313 * express our intentions. 314 */ 315 if (didfds == 0 && t->t_dflg & F_PIPEIN) { 316 (void) close(pipein[0]); 317 (void) close(pipein[1]); 318 } 319 if ((t->t_dflg & F_PIPEOUT) == 0) { 320 if (nosigchld) { 321 (void) sigsetmask(csigmask); 322 nosigchld = 0; 323 } 324 if ((t->t_dflg & F_AMPERSAND) == 0) 325 pwait(); 326 } 327 break; 328 } 329 doio(t, pipein, pipeout); 330 if (t->t_dflg & F_PIPEOUT) { 331 (void) close(pipeout[0]); 332 (void) close(pipeout[1]); 333 } 334 /* 335 * Perform a builtin function. If we are not forked, arrange for 336 * possible stopping 337 */ 338 if (bifunc) { 339 func(t, bifunc); 340 if (forked) 341 exitstat(); 342 break; 343 } 344 if (t->t_dtyp != NODE_PAREN) { 345 doexec(NULL, t); 346 /* NOTREACHED */ 347 } 348 /* 349 * For () commands must put new 0,1,2 in FSH* and recurse 350 */ 351 OLDSTD = dcopy(0, FOLDSTD); 352 SHOUT = dcopy(1, FSHOUT); 353 SHERR = dcopy(2, FSHERR); 354 (void) close(SHIN); 355 SHIN = -1; 356 didfds = 0; 357 wanttty = -1; 358 t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT; 359 execute(t->t_dspr, wanttty, NULL, NULL); 360 exitstat(); 361 362 case NODE_PIPE: 363 t->t_dcar->t_dflg |= F_PIPEOUT | 364 (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT)); 365 execute(t->t_dcar, wanttty, pipein, pv); 366 t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & 367 (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT)); 368 if (wanttty > 0) 369 wanttty = 0; /* got tty already */ 370 execute(t->t_dcdr, wanttty, pv, pipeout); 371 break; 372 373 case NODE_LIST: 374 if (t->t_dcar) { 375 t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; 376 execute(t->t_dcar, wanttty, NULL, NULL); 377 /* 378 * In strange case of A&B make a new job after A 379 */ 380 if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && 381 (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) 382 pendjob(); 383 } 384 if (t->t_dcdr) { 385 t->t_dcdr->t_dflg |= t->t_dflg & 386 (F_NOFORK | F_NOINTERRUPT); 387 execute(t->t_dcdr, wanttty, NULL, NULL); 388 } 389 break; 390 391 case NODE_OR: 392 case NODE_AND: 393 if (t->t_dcar) { 394 t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; 395 execute(t->t_dcar, wanttty, NULL, NULL); 396 if ((getn(value(STRstatus)) == 0) != 397 (t->t_dtyp == NODE_AND)) 398 return; 399 } 400 if (t->t_dcdr) { 401 t->t_dcdr->t_dflg |= t->t_dflg & 402 (F_NOFORK | F_NOINTERRUPT); 403 execute(t->t_dcdr, wanttty, NULL, NULL); 404 } 405 break; 406 } 407 /* 408 * Fall through for all breaks from switch 409 * 410 * If there will be no more executions of this command, flush all file 411 * descriptors. Places that turn on the F_REPEAT bit are responsible for 412 * doing donefds after the last re-execution 413 */ 414 if (didfds && !(t->t_dflg & F_REPEAT)) 415 donefds(); 416 } 417 418 static void 419 vffree(i) 420 int i; 421 { 422 register Char **v; 423 424 if (v = gargv) { 425 gargv = 0; 426 xfree((ptr_t) v); 427 } 428 if (v = pargv) { 429 pargv = 0; 430 xfree((ptr_t) v); 431 } 432 _exit(i); 433 } 434 435 /* 436 * Expand and glob the words after an i/o redirection. 437 * If more than one word is generated, then update the command vector. 438 * 439 * This is done differently in all the shells: 440 * 1. in the bourne shell and ksh globbing is not performed 441 * 2. Bash/csh say ambiguous 442 * 3. zsh does i/o to/from all the files 443 * 4. itcsh concatenates the words. 444 * 445 * I don't know what is best to do. I think that Ambiguous is better 446 * than restructuring the command vector, because the user can get 447 * unexpected results. In any case, the command vector restructuring 448 * code is present and the user can choose it by setting noambiguous 449 */ 450 static Char * 451 splicepipe(t, cp) 452 register struct command *t; 453 Char *cp; /* word after < or > */ 454 { 455 Char *blk[2]; 456 457 if (adrof(STRnoambiguous)) { 458 Char **pv; 459 460 blk[0] = Dfix1(cp); /* expand $ */ 461 blk[1] = NULL; 462 463 gflag = 0, tglob(blk); 464 if (gflag) { 465 pv = globall(blk); 466 if (pv == NULL) { 467 setname(vis_str(blk[0])); 468 xfree((ptr_t) blk[0]); 469 stderror(ERR_NAME | ERR_NOMATCH); 470 } 471 gargv = NULL; 472 if (pv[1] != NULL) { /* we need to fix the command vector */ 473 Char **av = blkspl(t->t_dcom, &pv[1]); 474 xfree((ptr_t) t->t_dcom); 475 t->t_dcom = av; 476 } 477 xfree((ptr_t) blk[0]); 478 blk[0] = pv[0]; 479 xfree((ptr_t) pv); 480 } 481 } 482 else { 483 blk[0] = globone(blk[1] = Dfix1(cp), G_ERROR); 484 xfree((ptr_t) blk[1]); 485 } 486 return(blk[0]); 487 } 488 489 /* 490 * Perform io redirection. 491 * We may or maynot be forked here. 492 */ 493 static void 494 doio(t, pipein, pipeout) 495 register struct command *t; 496 int *pipein, *pipeout; 497 { 498 register int fd; 499 register Char *cp; 500 register int flags = t->t_dflg; 501 502 if (didfds || (flags & F_REPEAT)) 503 return; 504 if ((flags & F_READ) == 0) {/* F_READ already done */ 505 if (t->t_dlef) { 506 char tmp[MAXPATHLEN+1]; 507 508 /* 509 * so < /dev/std{in,out,err} work 510 */ 511 (void) dcopy(SHIN, 0); 512 (void) dcopy(SHOUT, 1); 513 (void) dcopy(SHERR, 2); 514 cp = splicepipe(t, t->t_dlef); 515 (void) strncpy(tmp, short2str(cp), MAXPATHLEN); 516 tmp[MAXPATHLEN] = '\0'; 517 xfree((ptr_t) cp); 518 if ((fd = open(tmp, O_RDONLY)) < 0) 519 stderror(ERR_SYSTEM, tmp, strerror(errno)); 520 (void) dmove(fd, 0); 521 } 522 else if (flags & F_PIPEIN) { 523 (void) close(0); 524 (void) dup(pipein[0]); 525 (void) close(pipein[0]); 526 (void) close(pipein[1]); 527 } 528 else if ((flags & F_NOINTERRUPT) && tpgrp == -1) { 529 (void) close(0); 530 (void) open(_PATH_DEVNULL, O_RDONLY); 531 } 532 else { 533 (void) close(0); 534 (void) dup(OLDSTD); 535 (void) ioctl(0, FIONCLEX, NULL); 536 } 537 } 538 if (t->t_drit) { 539 char tmp[MAXPATHLEN+1]; 540 541 cp = splicepipe(t, t->t_drit); 542 (void) strncpy(tmp, short2str(cp), MAXPATHLEN); 543 tmp[MAXPATHLEN] = '\0'; 544 xfree((ptr_t) cp); 545 /* 546 * so > /dev/std{out,err} work 547 */ 548 (void) dcopy(SHOUT, 1); 549 (void) dcopy(SHERR, 2); 550 if ((flags & F_APPEND) && 551 #ifdef O_APPEND 552 (fd = open(tmp, O_WRONLY | O_APPEND)) >= 0); 553 #else 554 (fd = open(tmp, O_WRONLY)) >= 0) 555 (void) lseek(1, (off_t) 0, L_XTND); 556 #endif 557 else { 558 if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) { 559 if (flags & F_APPEND) 560 stderror(ERR_SYSTEM, tmp, strerror(errno)); 561 chkclob(tmp); 562 } 563 if ((fd = creat(tmp, 0666)) < 0) 564 stderror(ERR_SYSTEM, tmp, strerror(errno)); 565 } 566 (void) dmove(fd, 1); 567 } 568 else if (flags & F_PIPEOUT) { 569 (void) close(1); 570 (void) dup(pipeout[1]); 571 } 572 else { 573 (void) close(1); 574 (void) dup(SHOUT); 575 (void) ioctl(1, FIONCLEX, NULL); 576 } 577 578 (void) close(2); 579 if (flags & F_STDERR) { 580 (void) dup(1); 581 } 582 else { 583 (void) dup(SHERR); 584 (void) ioctl(2, FIONCLEX, NULL); 585 } 586 didfds = 1; 587 } 588 589 void 590 mypipe(pv) 591 register int *pv; 592 { 593 594 if (pipe(pv) < 0) 595 goto oops; 596 pv[0] = dmove(pv[0], -1); 597 pv[1] = dmove(pv[1], -1); 598 if (pv[0] >= 0 && pv[1] >= 0) 599 return; 600 oops: 601 stderror(ERR_PIPE); 602 } 603 604 static void 605 chkclob(cp) 606 register char *cp; 607 { 608 struct stat stb; 609 610 if (stat(cp, &stb) < 0) 611 return; 612 if (S_ISCHR(stb.st_mode)) 613 return; 614 stderror(ERR_EXISTS, cp); 615 } 616