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