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