1 /* $Header: /src/pub/tcsh/sh.sem.c,v 3.53 2001/08/06 23:52:03 christos Exp $ */ 2 /* 3 * sh.sem.c: I/O redirections and job forking. A touchy issue! 4 * Most stuff with builtins is incorrect 5 */ 6 /*- 7 * Copyright (c) 1980, 1991 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 #include "sh.h" 39 40 RCSID("$Id: sh.sem.c,v 3.53 2001/08/06 23:52:03 christos Exp $") 41 42 #include "tc.h" 43 #include "tw.h" 44 #ifdef WINNT_NATIVE 45 #include "nt.const.h" 46 #endif /*WINNT_NATIVE*/ 47 48 #ifdef CLOSE_ON_EXEC 49 # ifndef SUNOS4 50 # ifndef CLEX_DUPS 51 # define CLEX_DUPS 52 # endif /* CLEX_DUPS */ 53 # endif /* !SUNOS4 */ 54 #endif /* CLOSE_ON_EXEC */ 55 56 #if defined(__sparc__) || defined(sparc) 57 # if !defined(MACH) && SYSVREL == 0 && !defined(Lynx) && !defined(BSD4_4) && !defined(linux) 58 # include <vfork.h> 59 # endif /* !MACH && SYSVREL == 0 && !Lynx && !BSD4_4 && !linux */ 60 #endif /* __sparc__ || sparc */ 61 62 #ifdef VFORK 63 static sigret_t vffree __P((int)); 64 #endif 65 static Char *splicepipe __P((struct command *, Char *)); 66 static void doio __P((struct command *, int *, int *)); 67 static void chkclob __P((char *)); 68 69 /* 70 * C shell 71 */ 72 73 /* 74 * For SVR4, there are problems with pipelines having the first process as 75 * the group leader. The problem occurs when the first process exits before 76 * the others have a chance to setpgid(). This is because in SVR4 you can't 77 * have a zombie as a group leader. The solution I have used is to reverse 78 * the order in which pipelines are started, making the last process the 79 * group leader. (Note I am not using 'pipeline' in the generic sense -- I 80 * mean processes connected by '|'.) I don't know yet if this causes other 81 * problems. 82 * 83 * All the changes for this are in execute(), and are enclosed in 84 * '#ifdef BACKPIPE' 85 * 86 * David Dawes (dawes@physics.su.oz.au) Oct 1991 87 */ 88 89 /*VARARGS 1*/ 90 void 91 execute(t, wanttty, pipein, pipeout) 92 register struct command *t; 93 int wanttty; 94 int *pipein, *pipeout; 95 { 96 #ifdef VFORK 97 extern bool use_fork; /* use fork() instead of vfork()? */ 98 #endif 99 100 bool forked = 0; 101 struct biltins *bifunc; 102 int pid = 0; 103 int pv[2]; 104 #ifdef BSDSIGS 105 static sigmask_t csigmask; 106 #endif /* BSDSIGS */ 107 #ifdef VFORK 108 static int onosigchld = 0; 109 #endif /* VFORK */ 110 static int nosigchld = 0; 111 112 (void) &wanttty; 113 (void) &forked; 114 (void) &bifunc; 115 116 if (t == 0) 117 return; 118 119 #ifdef WINNT_NATIVE 120 { 121 if ((varval(STRNTslowexec) == STRNULL) && 122 !t->t_dcdr && !t->t_dcar && !t->t_dflg && !didfds && 123 (intty || intact) && (t->t_dtyp == NODE_COMMAND) && 124 !isbfunc(t)) { 125 if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) 126 (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); 127 Dfix(t); 128 if (nt_try_fast_exec(t) == 0) 129 return; 130 } 131 } 132 #endif /* WINNT_NATIVE */ 133 134 /* 135 * Ed hutchins@sgi.com & Dominic dbg@sgi.com 136 * Sat Feb 25 03:13:11 PST 1995 137 * try implicit cd if we have a 1 word command 138 */ 139 if (implicit_cd && (intty || intact) && t->t_dcom && t->t_dcom[0] && 140 t->t_dcom[0][0] && (blklen(t->t_dcom) == 1) && !noexec) { 141 Char sCName[MAXPATHLEN]; 142 Char *pCN; 143 struct stat stbuf; 144 char *pathname; 145 146 dollar(sCName, t->t_dcom[0]); 147 pCN = sCName; 148 if (pCN[0] == '~') { 149 Char sCPath[MAXPATHLEN]; 150 Char *pCP = sCPath; 151 152 ++pCN; 153 while (*pCN && *pCN != '/') 154 *pCP++ = *pCN++; 155 *pCP = 0; 156 if (sCPath[0]) 157 gethdir(sCPath); 158 else 159 (void) Strcpy(sCPath, varval(STRhome)); 160 catn(sCPath, pCN, MAXPATHLEN); 161 (void) Strcpy(sCName, sCPath); 162 } 163 164 pathname = short2str(sCName); 165 /* if this is a dir, tack a "cd" on as the first arg */ 166 if ((stat(pathname, &stbuf) != -1 && S_ISDIR(stbuf.st_mode)) 167 #ifdef WINNT_NATIVE 168 || (pathname[0] && pathname[1] == ':' && pathname[2] == '\0') 169 #endif /* WINNT_NATIVE */ 170 ) { 171 Char *vCD[2]; 172 Char **ot_dcom = t->t_dcom; 173 174 vCD[0] = Strsave(STRcd); 175 vCD[1] = NULL; 176 t->t_dcom = blkspl(vCD, ot_dcom); 177 if (implicit_cd > 1) { 178 blkpr(t->t_dcom); 179 xputchar( '\n' ); 180 } 181 xfree((ptr_t) ot_dcom); 182 } 183 } 184 185 /* 186 * From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de> 187 * Don't check for wantty > 0... 188 */ 189 if (t->t_dflg & F_AMPERSAND) 190 wanttty = 0; 191 switch (t->t_dtyp) { 192 193 case NODE_COMMAND: 194 if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) 195 (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); 196 if ((t->t_dflg & F_REPEAT) == 0) 197 Dfix(t); /* $ " ' \ */ 198 if (t->t_dcom[0] == 0) { 199 return; 200 } 201 /*FALLTHROUGH*/ 202 203 case NODE_PAREN: 204 #ifdef BACKPIPE 205 if (t->t_dflg & F_PIPEIN) 206 mypipe(pipein); 207 #else /* !BACKPIPE */ 208 if (t->t_dflg & F_PIPEOUT) 209 mypipe(pipeout); 210 #endif /* BACKPIPE */ 211 /* 212 * Must do << early so parent will know where input pointer should be. 213 * If noexec then this is all we do. 214 */ 215 if (t->t_dflg & F_READ) { 216 (void) close(0); 217 heredoc(t->t_dlef); 218 if (noexec) 219 (void) close(0); 220 } 221 222 set(STRstatus, Strsave(STR0), VAR_READWRITE); 223 224 /* 225 * This mess is the necessary kludge to handle the prefix builtins: 226 * nice, nohup, time. These commands can also be used by themselves, 227 * and this is not handled here. This will also work when loops are 228 * parsed. 229 */ 230 while (t->t_dtyp == NODE_COMMAND) 231 if (eq(t->t_dcom[0], STRnice)) { 232 if (t->t_dcom[1]) { 233 if (strchr("+-", t->t_dcom[1][0])) { 234 if (t->t_dcom[2]) { 235 setname("nice"); 236 t->t_nice = 237 getn(t->t_dcom[1]); 238 lshift(t->t_dcom, 2); 239 t->t_dflg |= F_NICE; 240 } 241 else 242 break; 243 } 244 else { 245 t->t_nice = 4; 246 lshift(t->t_dcom, 1); 247 t->t_dflg |= F_NICE; 248 } 249 } 250 else 251 break; 252 } 253 else if (eq(t->t_dcom[0], STRnohup)) { 254 if (t->t_dcom[1]) { 255 t->t_dflg |= F_NOHUP; 256 lshift(t->t_dcom, 1); 257 } 258 else 259 break; 260 } 261 else if (eq(t->t_dcom[0], STRhup)) { 262 if (t->t_dcom[1]) { 263 t->t_dflg |= F_HUP; 264 lshift(t->t_dcom, 1); 265 } 266 else 267 break; 268 } 269 else if (eq(t->t_dcom[0], STRtime)) { 270 if (t->t_dcom[1]) { 271 t->t_dflg |= F_TIME; 272 lshift(t->t_dcom, 1); 273 } 274 else 275 break; 276 } 277 #ifdef F_VER 278 else if (eq(t->t_dcom[0], STRver)) 279 if (t->t_dcom[1] && t->t_dcom[2]) { 280 setname("ver"); 281 t->t_systype = getv(t->t_dcom[1]); 282 lshift(t->t_dcom, 2); 283 t->t_dflg |= F_VER; 284 } 285 else 286 break; 287 #endif /* F_VER */ 288 else 289 break; 290 291 /* is it a command */ 292 if (t->t_dtyp == NODE_COMMAND) { 293 /* 294 * Check if we have a builtin function and remember which one. 295 */ 296 bifunc = isbfunc(t); 297 if (noexec && bifunc) { 298 /* 299 * Continue for builtins that are part of the scripting language 300 */ 301 if (bifunc->bfunct != (bfunc_t)dobreak && 302 bifunc->bfunct != (bfunc_t)docontin && 303 bifunc->bfunct != (bfunc_t)doelse && 304 bifunc->bfunct != (bfunc_t)doend && 305 bifunc->bfunct != (bfunc_t)doforeach&& 306 bifunc->bfunct != (bfunc_t)dogoto && 307 bifunc->bfunct != (bfunc_t)doif && 308 bifunc->bfunct != (bfunc_t)dorepeat && 309 bifunc->bfunct != (bfunc_t)doswbrk && 310 bifunc->bfunct != (bfunc_t)doswitch && 311 bifunc->bfunct != (bfunc_t)dowhile && 312 bifunc->bfunct != (bfunc_t)dozip) 313 break; 314 } 315 } 316 else { /* not a command */ 317 bifunc = NULL; 318 if (noexec) 319 break; 320 } 321 322 /* 323 * GrP Executing a command - run jobcmd hook 324 * Don't run for builtins 325 * Don't run if we're not in a tty 326 * Don't run if we're not really executing 327 */ 328 if (t->t_dtyp == NODE_COMMAND && !bifunc && !noexec && intty) { 329 Char *cmd = unparse(t); 330 job_cmd(cmd); 331 xfree(cmd); 332 } 333 334 /* 335 * We fork only if we are timed, or are not the end of a parenthesized 336 * list and not a simple builtin function. Simple meaning one that is 337 * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not 338 * fork in some of these cases. 339 */ 340 /* 341 * Prevent forking cd, pushd, popd, chdir cause this will cause the 342 * shell not to change dir! 343 */ 344 #ifdef BACKPIPE 345 /* 346 * Can't have NOFORK for the tail of a pipe - because it is not the 347 * last command spawned (even if it is at the end of a parenthesised 348 * list). 349 */ 350 if (t->t_dflg & F_PIPEIN) 351 t->t_dflg &= ~(F_NOFORK); 352 #endif /* BACKPIPE */ 353 if (bifunc && (bifunc->bfunct == (bfunc_t)dochngd || 354 bifunc->bfunct == (bfunc_t)dopushd || 355 bifunc->bfunct == (bfunc_t)dopopd)) 356 t->t_dflg &= ~(F_NICE); 357 if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && 358 (!bifunc || t->t_dflg & 359 (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP | F_HUP)))) || 360 /* 361 * We have to fork for eval too. 362 */ 363 (bifunc && (t->t_dflg & F_PIPEIN) != 0 && 364 bifunc->bfunct == (bfunc_t)doeval)) { 365 #ifdef VFORK 366 if (t->t_dtyp == NODE_PAREN || 367 t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) 368 #endif /* VFORK */ 369 { 370 forked++; 371 /* 372 * We need to block SIGCHLD here, so that if the process does 373 * not die before we can set the process group 374 */ 375 if (wanttty >= 0 && !nosigchld) { 376 #ifdef BSDSIGS 377 csigmask = sigblock(sigmask(SIGCHLD)); 378 #else /* !BSDSIGS */ 379 (void) sighold(SIGCHLD); 380 #endif /* BSDSIGS */ 381 382 nosigchld = 1; 383 } 384 385 pid = pfork(t, wanttty); 386 if (pid == 0 && nosigchld) { 387 #ifdef BSDSIGS 388 (void) sigsetmask(csigmask); 389 #else /* !BSDSIGS */ 390 (void) sigrelse(SIGCHLD); 391 #endif /* BSDSIGS */ 392 nosigchld = 0; 393 } 394 else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) 395 backpid = pid; 396 } 397 398 #ifdef VFORK 399 else { 400 int ochild, osetintr, ohaderr, odidfds; 401 int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp; 402 int oisoutatty, oisdiagatty; 403 404 # ifndef CLOSE_ON_EXEC 405 int odidcch; 406 # endif /* !CLOSE_ON_EXEC */ 407 # ifdef BSDSIGS 408 sigmask_t omask, ocsigmask; 409 # endif /* BSDSIGS */ 410 411 /* 412 * Prepare for the vfork by saving everything that the child 413 * corrupts before it exec's. Note that in some signal 414 * implementations which keep the signal info in user space 415 * (e.g. Sun's) it will also be necessary to save and restore 416 * the current sigvec's for the signals the child touches 417 * before it exec's. 418 */ 419 420 /* 421 * Sooooo true... If this is a Sun, save the sigvec's. (Skip 422 * Gilbrech - 11/22/87) 423 */ 424 # ifdef SAVESIGVEC 425 sigvec_t savesv[NSIGSAVED]; 426 sigmask_t savesm; 427 428 # endif /* SAVESIGVEC */ 429 if (wanttty >= 0 && !nosigchld && !noexec) { 430 # ifdef BSDSIGS 431 csigmask = sigblock(sigmask(SIGCHLD)); 432 # else /* !BSDSIGS */ 433 (void) sighold(SIGCHLD); 434 # endif /* BSDSIGS */ 435 nosigchld = 1; 436 } 437 # ifdef BSDSIGS 438 omask = sigblock(sigmask(SIGCHLD)|sigmask(SIGINT)); 439 # else /* !BSDSIGS */ 440 (void) sighold(SIGCHLD); 441 (void) sighold(SIGINT); 442 # endif /* BSDSIGS */ 443 ochild = child; 444 osetintr = setintr; 445 ohaderr = haderr; 446 odidfds = didfds; 447 # ifndef CLOSE_ON_EXEC 448 odidcch = didcch; 449 # endif /* !CLOSE_ON_EXEC */ 450 oSHIN = SHIN; 451 oSHOUT = SHOUT; 452 oSHDIAG = SHDIAG; 453 oOLDSTD = OLDSTD; 454 otpgrp = tpgrp; 455 oisoutatty = isoutatty; 456 oisdiagatty = isdiagatty; 457 # ifdef BSDSIGS 458 ocsigmask = csigmask; 459 # endif /* BSDSIGS */ 460 onosigchld = nosigchld; 461 Vsav = Vdp = 0; 462 Vexpath = 0; 463 Vt = 0; 464 # ifdef SAVESIGVEC 465 savesm = savesigvec(savesv); 466 # endif /* SAVESIGVEC */ 467 if (use_fork) 468 pid = fork(); 469 else 470 pid = vfork(); 471 472 if (pid < 0) { 473 # ifdef BSDSIGS 474 # ifdef SAVESIGVEC 475 restoresigvec(savesv, savesm); 476 # endif /* SAVESIGVEC */ 477 (void) sigsetmask(omask); 478 # else /* !BSDSIGS */ 479 (void) sigrelse(SIGCHLD); 480 (void) sigrelse(SIGINT); 481 # endif /* BSDSIGS */ 482 stderror(ERR_NOPROC); 483 } 484 forked++; 485 if (pid) { /* parent */ 486 # ifdef SAVESIGVEC 487 restoresigvec(savesv, savesm); 488 # endif /* SAVESIGVEC */ 489 child = ochild; 490 setintr = osetintr; 491 haderr = ohaderr; 492 didfds = odidfds; 493 SHIN = oSHIN; 494 # ifndef CLOSE_ON_EXEC 495 didcch = odidcch; 496 # endif /* !CLOSE_ON_EXEC */ 497 SHOUT = oSHOUT; 498 SHDIAG = oSHDIAG; 499 OLDSTD = oOLDSTD; 500 tpgrp = otpgrp; 501 isoutatty = oisoutatty; 502 isdiagatty = oisdiagatty; 503 # ifdef BSDSIGS 504 csigmask = ocsigmask; 505 # endif /* BSDSIGS */ 506 nosigchld = onosigchld; 507 508 xfree((ptr_t) Vsav); 509 Vsav = 0; 510 xfree((ptr_t) Vdp); 511 Vdp = 0; 512 xfree((ptr_t) Vexpath); 513 Vexpath = 0; 514 blkfree((Char **) Vt); 515 Vt = 0; 516 /* this is from pfork() */ 517 palloc(pid, t); 518 # ifdef BSDSIGS 519 (void) sigsetmask(omask); 520 # else /* !BSDSIGS */ 521 (void) sigrelse(SIGCHLD); 522 (void) sigrelse(SIGINT); 523 # endif /* BSDSIGS */ 524 } 525 else { /* child */ 526 /* this is from pfork() */ 527 int pgrp; 528 bool ignint = 0; 529 if (nosigchld) { 530 # ifdef BSDSIGS 531 (void) sigsetmask(csigmask); 532 # else /* !BSDSIGS */ 533 (void) sigrelse(SIGCHLD); 534 # endif /* BSDSIGS */ 535 nosigchld = 0; 536 } 537 538 if (setintr) 539 ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) 540 || (gointr && eq(gointr, STRminus)); 541 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); 542 child++; 543 if (setintr) { 544 setintr = 0; 545 /* 546 * casts made right for SunOS 4.0 by Douglas C. Schmidt 547 * <schmidt%sunshine.ics.uci.edu@ROME.ICS.UCI.EDU> 548 * (thanks! -- PWP) 549 * 550 * ignint ifs cleaned by Johan Widen <mcvax!osiris.sics.se!jw@uunet.UU.NET> 551 * (thanks again) 552 */ 553 if (ignint) { 554 (void) signal(SIGINT, SIG_IGN); 555 (void) signal(SIGQUIT, SIG_IGN); 556 } 557 else { 558 (void) signal(SIGINT, vffree); 559 (void) signal(SIGQUIT, SIG_DFL); 560 } 561 # ifdef BSDJOBS 562 if (wanttty >= 0) { 563 (void) signal(SIGTSTP, SIG_DFL); 564 (void) signal(SIGTTIN, SIG_DFL); 565 (void) signal(SIGTTOU, SIG_DFL); 566 } 567 # endif /* BSDJOBS */ 568 569 (void) signal(SIGTERM, parterm); 570 } 571 else if (tpgrp == -1 && 572 (t->t_dflg & F_NOINTERRUPT)) { 573 (void) signal(SIGINT, SIG_IGN); 574 (void) signal(SIGQUIT, SIG_IGN); 575 } 576 577 pgetty(wanttty, pgrp); 578 579 if (t->t_dflg & F_NOHUP) 580 (void) signal(SIGHUP, SIG_IGN); 581 if (t->t_dflg & F_HUP) 582 (void) signal(SIGHUP, SIG_DFL); 583 if (t->t_dflg & F_NICE) { 584 int nval = SIGN_EXTEND_CHAR(t->t_nice); 585 # ifdef BSDNICE 586 if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) 587 stderror(ERR_SYSTEM, "setpriority", 588 strerror(errno)); 589 # else /* !BSDNICE */ 590 (void) nice(nval); 591 # endif /* BSDNICE */ 592 } 593 # ifdef F_VER 594 if (t->t_dflg & F_VER) { 595 tsetenv(STRSYSTYPE, t->t_systype ? STRbsd43 : STRsys53); 596 dohash(NULL, NULL); 597 } 598 # endif /* F_VER */ 599 } 600 601 } 602 #endif /* VFORK */ 603 } 604 if (pid != 0) { 605 /* 606 * It would be better if we could wait for the whole job when we 607 * knew the last process had been started. Pwait, in fact, does 608 * wait for the whole job anyway, but this test doesn't really 609 * express our intentions. 610 */ 611 #ifdef BACKPIPE 612 if (didfds == 0 && t->t_dflg & F_PIPEOUT) { 613 (void) close(pipeout[0]); 614 (void) close(pipeout[1]); 615 } 616 if ((t->t_dflg & F_PIPEIN) != 0) 617 break; 618 #else /* !BACKPIPE */ 619 if (didfds == 0 && t->t_dflg & F_PIPEIN) { 620 (void) close(pipein[0]); 621 (void) close(pipein[1]); 622 } 623 if ((t->t_dflg & F_PIPEOUT) != 0) 624 break; 625 #endif /* BACKPIPE */ 626 627 if (nosigchld) { 628 #ifdef BSDSIGS 629 (void) sigsetmask(csigmask); 630 #else /* !BSDSIGS */ 631 (void) sigrelse(SIGCHLD); 632 #endif /* BSDSIGS */ 633 nosigchld = 0; 634 } 635 if ((t->t_dflg & F_AMPERSAND) == 0) 636 pwait(); 637 break; 638 } 639 640 doio(t, pipein, pipeout); 641 #ifdef BACKPIPE 642 if (t->t_dflg & F_PIPEIN) { 643 (void) close(pipein[0]); 644 (void) close(pipein[1]); 645 } 646 #else /* !BACKPIPE */ 647 if (t->t_dflg & F_PIPEOUT) { 648 (void) close(pipeout[0]); 649 (void) close(pipeout[1]); 650 } 651 #endif /* BACKPIPE */ 652 /* 653 * Perform a builtin function. If we are not forked, arrange for 654 * possible stopping 655 */ 656 if (bifunc) { 657 func(t, bifunc); 658 if (forked) 659 exitstat(); 660 break; 661 } 662 if (t->t_dtyp != NODE_PAREN) { 663 doexec(t); 664 /* NOTREACHED */ 665 } 666 /* 667 * For () commands must put new 0,1,2 in FSH* and recurse 668 */ 669 OLDSTD = dcopy(0, FOLDSTD); 670 SHOUT = dcopy(1, FSHOUT); 671 isoutatty = isatty(SHOUT); 672 SHDIAG = dcopy(2, FSHDIAG); 673 isdiagatty = isatty(SHDIAG); 674 (void) close(SHIN); 675 SHIN = -1; 676 #ifndef CLOSE_ON_EXEC 677 didcch = 0; 678 #endif /* !CLOSE_ON_EXEC */ 679 didfds = 0; 680 wanttty = -1; 681 t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT; 682 execute(t->t_dspr, wanttty, NULL, NULL); 683 exitstat(); 684 685 case NODE_PIPE: 686 #ifdef BACKPIPE 687 t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & 688 (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT)); 689 execute(t->t_dcdr, wanttty, pv, pipeout); 690 t->t_dcar->t_dflg |= F_PIPEOUT | 691 (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT)); 692 execute(t->t_dcar, wanttty, pipein, pv); 693 #else /* !BACKPIPE */ 694 t->t_dcar->t_dflg |= F_PIPEOUT | 695 (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT)); 696 execute(t->t_dcar, wanttty, pipein, pv); 697 t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & 698 (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT)); 699 execute(t->t_dcdr, wanttty, pv, pipeout); 700 #endif /* BACKPIPE */ 701 break; 702 703 case NODE_LIST: 704 if (t->t_dcar) { 705 t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; 706 execute(t->t_dcar, wanttty, NULL, NULL); 707 /* 708 * In strange case of A&B make a new job after A 709 */ 710 if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && 711 (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) 712 pendjob(); 713 } 714 if (t->t_dcdr) { 715 t->t_dcdr->t_dflg |= t->t_dflg & 716 (F_NOFORK | F_NOINTERRUPT); 717 execute(t->t_dcdr, wanttty, NULL, NULL); 718 } 719 break; 720 721 case NODE_OR: 722 case NODE_AND: 723 if (t->t_dcar) { 724 t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; 725 execute(t->t_dcar, wanttty, NULL, NULL); 726 if ((getn(varval(STRstatus)) == 0) != 727 (t->t_dtyp == NODE_AND)) { 728 return; 729 } 730 } 731 if (t->t_dcdr) { 732 t->t_dcdr->t_dflg |= t->t_dflg & 733 (F_NOFORK | F_NOINTERRUPT); 734 execute(t->t_dcdr, wanttty, NULL, NULL); 735 } 736 break; 737 738 default: 739 break; 740 } 741 /* 742 * Fall through for all breaks from switch 743 * 744 * If there will be no more executions of this command, flush all file 745 * descriptors. Places that turn on the F_REPEAT bit are responsible for 746 * doing donefds after the last re-execution 747 */ 748 if (didfds && !(t->t_dflg & F_REPEAT)) 749 donefds(); 750 } 751 752 #ifdef VFORK 753 static sigret_t 754 /*ARGSUSED*/ 755 vffree(snum) 756 int snum; 757 { 758 register Char **v; 759 760 USE(snum); 761 if ((v = gargv) != 0) { 762 gargv = 0; 763 xfree((ptr_t) v); 764 } 765 766 if ((v = pargv) != 0) { 767 pargv = 0; 768 xfree((ptr_t) v); 769 } 770 771 _exit(1); 772 #ifndef SIGVOID 773 /*NOTREACHED*/ 774 return(0); 775 #endif /* SIGVOID */ 776 } 777 #endif /* VFORK */ 778 779 /* 780 * Expand and glob the words after an i/o redirection. 781 * If more than one word is generated, then update the command vector. 782 * 783 * This is done differently in all the shells: 784 * 1. in the bourne shell and ksh globbing is not performed 785 * 2. Bash/csh say ambiguous 786 * 3. zsh does i/o to/from all the files 787 * 4. itcsh concatenates the words. 788 * 789 * I don't know what is best to do. I think that Ambiguous is better 790 * than restructuring the command vector, because the user can get 791 * unexpected results. In any case, the command vector restructuring 792 * code is present and the user can choose it by setting noambiguous 793 */ 794 static Char * 795 splicepipe(t, cp) 796 register struct command *t; 797 Char *cp; /* word after < or > */ 798 { 799 Char *blk[2]; 800 801 if (adrof(STRnoambiguous)) { 802 Char **pv; 803 804 blk[0] = Dfix1(cp); /* expand $ */ 805 blk[1] = NULL; 806 807 gflag = 0, tglob(blk); 808 if (gflag) { 809 pv = globall(blk); 810 if (pv == NULL) { 811 setname(short2str(blk[0])); 812 xfree((ptr_t) blk[0]); 813 stderror(ERR_NAME | ERR_NOMATCH); 814 } 815 gargv = NULL; 816 if (pv[1] != NULL) { /* we need to fix the command vector */ 817 Char **av = blkspl(t->t_dcom, &pv[1]); 818 xfree((ptr_t) t->t_dcom); 819 t->t_dcom = av; 820 } 821 xfree((ptr_t) blk[0]); 822 blk[0] = pv[0]; 823 xfree((ptr_t) pv); 824 } 825 } 826 else { 827 Char buf[BUFSIZE]; 828 829 (void) Strcpy(buf, blk[1] = Dfix1(cp)); 830 xfree((ptr_t) blk[1]); 831 blk[0] = globone(buf, G_ERROR); 832 } 833 return(blk[0]); 834 } 835 836 /* 837 * Perform io redirection. 838 * We may or maynot be forked here. 839 */ 840 static void 841 doio(t, pipein, pipeout) 842 register struct command *t; 843 int *pipein, *pipeout; 844 { 845 register int fd; 846 register Char *cp; 847 register unsigned long flags = t->t_dflg; 848 849 if (didfds || (flags & F_REPEAT)) 850 return; 851 if ((flags & F_READ) == 0) {/* F_READ already done */ 852 if (t->t_dlef) { 853 char tmp[MAXPATHLEN+1]; 854 855 /* 856 * so < /dev/std{in,out,err} work 857 */ 858 (void) dcopy(SHIN, 0); 859 (void) dcopy(SHOUT, 1); 860 (void) dcopy(SHDIAG, 2); 861 cp = splicepipe(t, t->t_dlef); 862 (void) strncpy(tmp, short2str(cp), MAXPATHLEN); 863 tmp[MAXPATHLEN] = '\0'; 864 xfree((ptr_t) cp); 865 if ((fd = open(tmp, O_RDONLY)) < 0) 866 stderror(ERR_SYSTEM, tmp, strerror(errno)); 867 #ifdef O_LARGEFILE 868 /* allow input files larger than 2Gb */ 869 (void) fcntl(fd, O_LARGEFILE, 0); 870 #endif /* O_LARGEFILE */ 871 (void) dmove(fd, 0); 872 } 873 else if (flags & F_PIPEIN) { 874 (void) close(0); 875 (void) dup(pipein[0]); 876 (void) close(pipein[0]); 877 (void) close(pipein[1]); 878 } 879 else if ((flags & F_NOINTERRUPT) && tpgrp == -1) { 880 (void) close(0); 881 (void) open(_PATH_DEVNULL, O_RDONLY); 882 } 883 else { 884 (void) close(0); 885 (void) dup(OLDSTD); 886 #if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) 887 /* 888 * PWP: Unlike Bezerkeley 4.3, FIONCLEX for Pyramid is preserved 889 * across dup()s, so we have to UNSET it here or else we get a 890 * command with NO stdin, stdout, or stderr at all (a bad thing 891 * indeed) 892 */ 893 (void) close_on_exec(0, 0); 894 #endif /* CLOSE_ON_EXEC && CLEX_DUPS */ 895 } 896 } 897 if (t->t_drit) { 898 char tmp[MAXPATHLEN+1]; 899 900 cp = splicepipe(t, t->t_drit); 901 (void) strncpy(tmp, short2str(cp), MAXPATHLEN); 902 tmp[MAXPATHLEN] = '\0'; 903 xfree((ptr_t) cp); 904 /* 905 * so > /dev/std{out,err} work 906 */ 907 (void) dcopy(SHOUT, 1); 908 (void) dcopy(SHDIAG, 2); 909 if ((flags & F_APPEND) != 0) { 910 #ifdef O_APPEND 911 fd = open(tmp, O_WRONLY | O_APPEND); 912 #else /* !O_APPEND */ 913 fd = open(tmp, O_WRONLY); 914 (void) lseek(fd, (off_t) 0, L_XTND); 915 #endif /* O_APPEND */ 916 } 917 else 918 fd = 0; 919 if ((flags & F_APPEND) == 0 || fd == -1) { 920 if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) { 921 if (flags & F_APPEND) 922 stderror(ERR_SYSTEM, tmp, strerror(errno)); 923 chkclob(tmp); 924 } 925 if ((fd = creat(tmp, 0666)) < 0) 926 stderror(ERR_SYSTEM, tmp, strerror(errno)); 927 #ifdef O_LARGEFILE 928 /* allow input files larger than 2Gb */ 929 (void) fcntl(fd, O_LARGEFILE, 0); 930 #endif /* O_LARGEFILE */ 931 } 932 (void) dmove(fd, 1); 933 is1atty = isatty(1); 934 } 935 else if (flags & F_PIPEOUT) { 936 (void) close(1); 937 (void) dup(pipeout[1]); 938 is1atty = 0; 939 } 940 else { 941 (void) close(1); 942 (void) dup(SHOUT); 943 is1atty = isoutatty; 944 # if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) 945 (void) close_on_exec(1, 0); 946 # endif /* CLOSE_ON_EXEC && CLEX_DUPS */ 947 } 948 949 (void) close(2); 950 if (flags & F_STDERR) { 951 (void) dup(1); 952 is2atty = is1atty; 953 } 954 else { 955 (void) dup(SHDIAG); 956 is2atty = isdiagatty; 957 # if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) 958 (void) close_on_exec(2, 0); 959 # endif /* CLOSE_ON_EXEC && CLEX_DUPS */ 960 } 961 didfds = 1; 962 } 963 964 void 965 mypipe(pv) 966 register int *pv; 967 { 968 969 if (pipe(pv) < 0) 970 goto oops; 971 pv[0] = dmove(pv[0], -1); 972 pv[1] = dmove(pv[1], -1); 973 if (pv[0] >= 0 && pv[1] >= 0) 974 return; 975 oops: 976 stderror(ERR_PIPE); 977 } 978 979 static void 980 chkclob(cp) 981 register char *cp; 982 { 983 struct stat stb; 984 985 if (stat(cp, &stb) < 0) 986 return; 987 if (S_ISCHR(stb.st_mode)) 988 return; 989 stderror(ERR_EXISTS, cp); 990 } 991