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