1 /* $NetBSD: redir.c,v 1.51 2017/02/03 23:16:38 kre Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Kenneth Almquist. 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. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; 39 #else 40 __RCSID("$NetBSD: redir.c,v 1.51 2017/02/03 23:16:38 kre Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <sys/types.h> 45 #include <sys/param.h> /* PIPE_BUF */ 46 #include <sys/stat.h> 47 #include <signal.h> 48 #include <string.h> 49 #include <fcntl.h> 50 #include <errno.h> 51 #include <unistd.h> 52 #include <stdlib.h> 53 54 /* 55 * Code for dealing with input/output redirection. 56 */ 57 58 #include "main.h" 59 #include "builtins.h" 60 #include "shell.h" 61 #include "nodes.h" 62 #include "jobs.h" 63 #include "options.h" 64 #include "expand.h" 65 #include "redir.h" 66 #include "output.h" 67 #include "memalloc.h" 68 #include "mystring.h" 69 #include "error.h" 70 71 72 #define EMPTY -2 /* marks an unused slot in redirtab */ 73 #define CLOSED -1 /* fd was not open before redir */ 74 #ifndef PIPE_BUF 75 # define PIPESIZE 4096 /* amount of buffering in a pipe */ 76 #else 77 # define PIPESIZE PIPE_BUF 78 #endif 79 80 81 MKINIT 82 struct renamelist { 83 struct renamelist *next; 84 int orig; 85 int into; 86 }; 87 88 MKINIT 89 struct redirtab { 90 struct redirtab *next; 91 struct renamelist *renamed; 92 }; 93 94 95 MKINIT struct redirtab *redirlist; 96 97 /* 98 * We keep track of whether or not fd0 has been redirected. This is for 99 * background commands, where we want to redirect fd0 to /dev/null only 100 * if it hasn't already been redirected. 101 */ 102 STATIC int fd0_redirected = 0; 103 104 /* 105 * And also where to put internal use fds that should be out of the 106 * way of user defined fds (normally) 107 */ 108 STATIC int big_sh_fd = 0; 109 110 STATIC const struct renamelist *is_renamed(const struct renamelist *, int); 111 STATIC void fd_rename(struct redirtab *, int, int); 112 STATIC void free_rl(struct redirtab *, int); 113 STATIC void openredirect(union node *, char[10], int); 114 STATIC int openhere(const union node *); 115 STATIC int copyfd(int, int, int); 116 STATIC void find_big_fd(void); 117 118 STATIC const struct renamelist * 119 is_renamed(const struct renamelist *rl, int fd) 120 { 121 while (rl != NULL) { 122 if (rl->orig == fd) 123 return rl; 124 rl = rl->next; 125 } 126 return NULL; 127 } 128 129 STATIC void 130 free_rl(struct redirtab *rt, int reset) 131 { 132 struct renamelist *rl, *rn = rt->renamed; 133 134 while ((rl = rn) != NULL) { 135 rn = rl->next; 136 if (rl->orig == 0) 137 fd0_redirected--; 138 if (reset) { 139 if (rl->into < 0) 140 close(rl->orig); 141 else 142 movefd(rl->into, rl->orig); 143 } 144 ckfree(rl); 145 } 146 rt->renamed = NULL; 147 } 148 149 STATIC void 150 fd_rename(struct redirtab *rt, int from, int to) 151 { 152 struct renamelist *rl = ckmalloc(sizeof(struct renamelist)); 153 154 rl->next = rt->renamed; 155 rt->renamed = rl; 156 157 rl->orig = from; 158 rl->into = to; 159 } 160 161 /* 162 * Process a list of redirection commands. If the REDIR_PUSH flag is set, 163 * old file descriptors are stashed away so that the redirection can be 164 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the 165 * standard output, and the standard error if it becomes a duplicate of 166 * stdout, is saved in memory. 167 */ 168 169 void 170 redirect(union node *redir, int flags) 171 { 172 union node *n; 173 struct redirtab *sv = NULL; 174 int i; 175 int fd; 176 char memory[10]; /* file descriptors to write to memory */ 177 178 for (i = 10 ; --i >= 0 ; ) 179 memory[i] = 0; 180 memory[1] = flags & REDIR_BACKQ; 181 if (flags & REDIR_PUSH) { 182 /* We don't have to worry about REDIR_VFORK here, as 183 * flags & REDIR_PUSH is never true if REDIR_VFORK is set. 184 */ 185 sv = ckmalloc(sizeof (struct redirtab)); 186 sv->renamed = NULL; 187 sv->next = redirlist; 188 redirlist = sv; 189 } 190 for (n = redir ; n ; n = n->nfile.next) { 191 fd = n->nfile.fd; 192 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && 193 n->ndup.dupfd == fd) { 194 /* redirect from/to same file descriptor */ 195 /* make sure it stays open */ 196 if (fcntl(fd, F_SETFD, 0) < 0) 197 error("fd %d: %s", fd, strerror(errno)); 198 continue; 199 } 200 201 if ((flags & REDIR_PUSH) && !is_renamed(sv->renamed, fd)) { 202 INTOFF; 203 if (big_sh_fd < 10) 204 find_big_fd(); 205 if ((i = fcntl(fd, F_DUPFD, big_sh_fd)) == -1) { 206 switch (errno) { 207 case EBADF: 208 i = CLOSED; 209 break; 210 case EMFILE: 211 case EINVAL: 212 find_big_fd(); 213 i = fcntl(fd, F_DUPFD, big_sh_fd); 214 if (i >= 0) 215 break; 216 /* FALLTHRU */ 217 default: 218 i = errno; 219 INTON; /* XXX not needed here ? */ 220 error("%d: %s", fd, strerror(i)); 221 /* NOTREACHED */ 222 } 223 } 224 if (i >= 0) 225 (void)fcntl(i, F_SETFD, FD_CLOEXEC); 226 fd_rename(sv, fd, i); 227 INTON; 228 } 229 if (fd == 0) 230 fd0_redirected++; 231 openredirect(n, memory, flags); 232 } 233 if (memory[1]) 234 out1 = &memout; 235 if (memory[2]) 236 out2 = &memout; 237 } 238 239 240 STATIC void 241 openredirect(union node *redir, char memory[10], int flags) 242 { 243 struct stat sb; 244 int fd = redir->nfile.fd; 245 char *fname; 246 int f; 247 int eflags, cloexec; 248 249 /* 250 * We suppress interrupts so that we won't leave open file 251 * descriptors around. This may not be such a good idea because 252 * an open of a device or a fifo can block indefinitely. 253 */ 254 INTOFF; 255 if (fd < 10) 256 memory[fd] = 0; 257 switch (redir->nfile.type) { 258 case NFROM: 259 fname = redir->nfile.expfname; 260 if (flags & REDIR_VFORK) 261 eflags = O_NONBLOCK; 262 else 263 eflags = 0; 264 if ((f = open(fname, O_RDONLY|eflags)) < 0) 265 goto eopen; 266 if (eflags) 267 (void)fcntl(f, F_SETFL, fcntl(f, F_GETFL, 0) & ~eflags); 268 break; 269 case NFROMTO: 270 fname = redir->nfile.expfname; 271 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) 272 goto ecreate; 273 break; 274 case NTO: 275 if (Cflag) { 276 fname = redir->nfile.expfname; 277 if ((f = open(fname, O_WRONLY)) == -1) { 278 if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 279 0666)) < 0) 280 goto ecreate; 281 } else if (fstat(f, &sb) == -1) { 282 int serrno = errno; 283 close(f); 284 errno = serrno; 285 goto ecreate; 286 } else if (S_ISREG(sb.st_mode)) { 287 close(f); 288 errno = EEXIST; 289 goto ecreate; 290 } 291 break; 292 } 293 /* FALLTHROUGH */ 294 case NCLOBBER: 295 fname = redir->nfile.expfname; 296 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 297 goto ecreate; 298 break; 299 case NAPPEND: 300 fname = redir->nfile.expfname; 301 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) 302 goto ecreate; 303 break; 304 case NTOFD: 305 case NFROMFD: 306 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ 307 if (fd < 10 && redir->ndup.dupfd < 10 && 308 memory[redir->ndup.dupfd]) 309 memory[fd] = 1; 310 else if (copyfd(redir->ndup.dupfd, fd, 311 (flags & REDIR_KEEP) == 0) < 0) 312 error("Redirect (from %d to %d) failed: %s", 313 redir->ndup.dupfd, fd, strerror(errno)); 314 } else 315 (void) close(fd); 316 INTON; 317 return; 318 case NHERE: 319 case NXHERE: 320 f = openhere(redir); 321 break; 322 default: 323 abort(); 324 } 325 326 cloexec = fd > 2 && (flags & REDIR_KEEP) == 0; 327 if (f != fd) { 328 if (copyfd(f, fd, cloexec) < 0) { 329 int e = errno; 330 331 close(f); 332 error("redirect reassignment (fd %d) failed: %s", fd, 333 strerror(e)); 334 } 335 close(f); 336 } else if (cloexec) 337 (void)fcntl(f, F_SETFD, FD_CLOEXEC); 338 339 INTON; 340 return; 341 ecreate: 342 exerrno = 1; 343 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); 344 eopen: 345 exerrno = 1; 346 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); 347 } 348 349 350 /* 351 * Handle here documents. Normally we fork off a process to write the 352 * data to a pipe. If the document is short, we can stuff the data in 353 * the pipe without forking. 354 */ 355 356 STATIC int 357 openhere(const union node *redir) 358 { 359 int pip[2]; 360 int len = 0; 361 362 if (pipe(pip) < 0) 363 error("Pipe call failed"); 364 if (redir->type == NHERE) { 365 len = strlen(redir->nhere.doc->narg.text); 366 if (len <= PIPESIZE) { 367 xwrite(pip[1], redir->nhere.doc->narg.text, len); 368 goto out; 369 } 370 } 371 if (forkshell(NULL, NULL, FORK_NOJOB) == 0) { 372 close(pip[0]); 373 signal(SIGINT, SIG_IGN); 374 signal(SIGQUIT, SIG_IGN); 375 signal(SIGHUP, SIG_IGN); 376 #ifdef SIGTSTP 377 signal(SIGTSTP, SIG_IGN); 378 #endif 379 signal(SIGPIPE, SIG_DFL); 380 if (redir->type == NHERE) 381 xwrite(pip[1], redir->nhere.doc->narg.text, len); 382 else 383 expandhere(redir->nhere.doc, pip[1]); 384 _exit(0); 385 } 386 out: 387 close(pip[1]); 388 return pip[0]; 389 } 390 391 392 393 /* 394 * Undo the effects of the last redirection. 395 */ 396 397 void 398 popredir(void) 399 { 400 struct redirtab *rp = redirlist; 401 402 INTOFF; 403 free_rl(rp, 1); 404 redirlist = rp->next; 405 ckfree(rp); 406 INTON; 407 } 408 409 /* 410 * Undo all redirections. Called on error or interrupt. 411 */ 412 413 #ifdef mkinit 414 415 INCLUDE "redir.h" 416 417 RESET { 418 while (redirlist) 419 popredir(); 420 } 421 422 SHELLPROC { 423 clearredir(0); 424 } 425 426 #endif 427 428 /* Return true if fd 0 has already been redirected at least once. */ 429 int 430 fd0_redirected_p(void) 431 { 432 return fd0_redirected != 0; 433 } 434 435 /* 436 * Discard all saved file descriptors. 437 */ 438 439 void 440 clearredir(int vforked) 441 { 442 struct redirtab *rp; 443 struct renamelist *rl; 444 445 for (rp = redirlist ; rp ; rp = rp->next) { 446 if (!vforked) 447 free_rl(rp, 0); 448 else for (rl = rp->renamed; rl; rl = rl->next) 449 if (rl->into >= 0) 450 close(rl->into); 451 } 452 } 453 454 455 456 /* 457 * Copy a file descriptor to be == to. 458 * cloexec indicates if we want close-on-exec or not. 459 * Returns -1 if any error occurs. 460 */ 461 462 STATIC int 463 copyfd(int from, int to, int cloexec) 464 { 465 int newfd; 466 467 if (cloexec && to > 2) 468 newfd = dup3(from, to, O_CLOEXEC); 469 else 470 newfd = dup2(from, to); 471 472 return newfd; 473 } 474 475 /* 476 * rename fd from to be fd to (closing from). 477 * close-on-exec is never set on 'to' (unless 478 * from==to and it was set on from) - ie: a no-op 479 * returns to (or errors() if an error occurs). 480 * 481 * This is mostly used for rearranging the 482 * results from pipe(). 483 */ 484 int 485 movefd(int from, int to) 486 { 487 if (from == to) 488 return to; 489 490 (void) close(to); 491 if (copyfd(from, to, 0) != to) { 492 int e = errno; 493 494 (void) close(from); 495 error("Unable to make fd %d: %s", to, strerror(e)); 496 } 497 (void) close(from); 498 499 return to; 500 } 501 502 STATIC void 503 find_big_fd(void) 504 { 505 int i, fd; 506 507 for (i = (1 << 10); i >= 10; i >>= 1) { 508 if ((fd = fcntl(0, F_DUPFD, i - 1)) >= 0) { 509 close(fd); 510 break; 511 } 512 } 513 514 fd = (i / 5) * 4; 515 if ((i - fd) > 100) 516 fd = i - 100; 517 else if (fd < 10) 518 fd = 10; 519 520 big_sh_fd = fd; 521 } 522 523 /* 524 * If possible, move file descriptor fd out of the way 525 * of expected user fd values. Returns the new fd 526 * (which may be the input fd if things do not go well.) 527 * Always set close-on-exec on the result, and close 528 * the input fd unless it is to be our result. 529 */ 530 int 531 to_upper_fd(int fd) 532 { 533 int i; 534 535 if (big_sh_fd < 10) 536 find_big_fd(); 537 do { 538 i = fcntl(fd, F_DUPFD_CLOEXEC, big_sh_fd); 539 if (i >= 0) { 540 if (fd != i) 541 close(fd); 542 return i; 543 } 544 if (errno != EMFILE) 545 break; 546 find_big_fd(); 547 } while (big_sh_fd > 10); 548 549 /* 550 * If we wanted to move this fd to some random high number 551 * we certainly do not intend to pass it through exec, even 552 * if the reassignment failed. 553 */ 554 (void)fcntl(fd, F_SETFD, FD_CLOEXEC); 555 return fd; 556 } 557 558 static const struct flgnames { 559 const char *name; 560 uint32_t value; 561 } nv[] = { 562 #ifdef O_APPEND 563 { "append", O_APPEND }, 564 #endif 565 #ifdef O_ASYNC 566 { "async", O_ASYNC }, 567 #endif 568 #ifdef O_SYNC 569 { "sync", O_SYNC }, 570 #endif 571 #ifdef O_NONBLOCK 572 { "nonblock", O_NONBLOCK }, 573 #endif 574 #ifdef O_FSYNC 575 { "fsync", O_FSYNC }, 576 #endif 577 #ifdef O_DSYNC 578 { "dsync", O_DSYNC }, 579 #endif 580 #ifdef O_RSYNC 581 { "rsync", O_RSYNC }, 582 #endif 583 #ifdef O_ALTIO 584 { "altio", O_ALT_IO }, 585 #endif 586 #ifdef O_DIRECT 587 { "direct", O_DIRECT }, 588 #endif 589 #ifdef O_NOSIGPIPE 590 { "nosigpipe", O_NOSIGPIPE }, 591 #endif 592 #ifdef O_CLOEXEC 593 { "cloexec", O_CLOEXEC }, 594 #endif 595 { 0, 0 } 596 }; 597 #define ALLFLAGS (O_APPEND|O_ASYNC|O_SYNC|O_NONBLOCK|O_DSYNC|O_RSYNC|\ 598 O_ALT_IO|O_DIRECT|O_NOSIGPIPE|O_CLOEXEC) 599 600 static int 601 getflags(int fd, int p) 602 { 603 int c, f; 604 605 if ((c = fcntl(fd, F_GETFD)) == -1) { 606 if (!p) 607 return -1; 608 error("Can't get status for fd=%d (%s)", fd, strerror(errno)); 609 } 610 if ((f = fcntl(fd, F_GETFL)) == -1) { 611 if (!p) 612 return -1; 613 error("Can't get flags for fd=%d (%s)", fd, strerror(errno)); 614 } 615 if (c & FD_CLOEXEC) 616 f |= O_CLOEXEC; 617 return f & ALLFLAGS; 618 } 619 620 static void 621 printone(int fd, int p, int verbose, int pfd) 622 { 623 int f = getflags(fd, p); 624 const struct flgnames *fn; 625 626 if (f == -1) 627 return; 628 629 if (pfd) 630 outfmt(out1, "%d: ", fd); 631 for (fn = nv; fn->name; fn++) { 632 if (f & fn->value) { 633 outfmt(out1, "%s%s", verbose ? "+" : "", fn->name); 634 f &= ~fn->value; 635 } else if (verbose) 636 outfmt(out1, "-%s", fn->name); 637 else 638 continue; 639 if (f || (verbose && fn[1].name)) 640 outfmt(out1, ","); 641 } 642 if (verbose && f) /* f should be normally be 0 */ 643 outfmt(out1, " +%#x", f); 644 outfmt(out1, "\n"); 645 } 646 647 static void 648 parseflags(char *s, int *p, int *n) 649 { 650 int *v, *w; 651 const struct flgnames *fn; 652 653 *p = 0; 654 *n = 0; 655 for (s = strtok(s, ","); s; s = strtok(NULL, ",")) { 656 switch (*s++) { 657 case '+': 658 v = p; 659 w = n; 660 break; 661 case '-': 662 v = n; 663 w = p; 664 break; 665 default: 666 error("Missing +/- indicator before flag %s", s-1); 667 } 668 669 for (fn = nv; fn->name; fn++) 670 if (strcmp(s, fn->name) == 0) { 671 *v |= fn->value; 672 *w &=~ fn->value; 673 break; 674 } 675 if (fn->name == 0) 676 error("Bad flag `%s'", s); 677 } 678 } 679 680 static void 681 setone(int fd, int pos, int neg, int verbose) 682 { 683 int f = getflags(fd, 1); 684 int n, cloexec; 685 686 if (f == -1) 687 return; 688 689 cloexec = -1; 690 if ((pos & O_CLOEXEC) && !(f & O_CLOEXEC)) 691 cloexec = FD_CLOEXEC; 692 if ((neg & O_CLOEXEC) && (f & O_CLOEXEC)) 693 cloexec = 0; 694 695 if (cloexec != -1 && fcntl(fd, F_SETFD, cloexec) == -1) 696 error("Can't set status for fd=%d (%s)", fd, strerror(errno)); 697 698 pos &= ~O_CLOEXEC; 699 neg &= ~O_CLOEXEC; 700 f &= ~O_CLOEXEC; 701 n = f; 702 n |= pos; 703 n &= ~neg; 704 if (n != f && fcntl(fd, F_SETFL, n) == -1) 705 error("Can't set flags for fd=%d (%s)", fd, strerror(errno)); 706 if (verbose) 707 printone(fd, 1, verbose, 1); 708 } 709 710 int 711 fdflagscmd(int argc, char *argv[]) 712 { 713 char *num; 714 int verbose = 0, ch, pos = 0, neg = 0; 715 char *setflags = NULL; 716 717 optreset = 1; optind = 1; /* initialize getopt */ 718 while ((ch = getopt(argc, argv, ":vs:")) != -1) 719 switch ((char)ch) { 720 case 'v': 721 verbose = 1; 722 break; 723 case 's': 724 if (setflags) 725 goto msg; 726 setflags = optarg; 727 break; 728 case '?': 729 default: 730 msg: 731 error("Usage: fdflags [-v] [-s <flags> fd] [fd...]"); 732 /* NOTREACHED */ 733 } 734 735 argc -= optind, argv += optind; 736 737 if (setflags) 738 parseflags(setflags, &pos, &neg); 739 740 if (argc == 0) { 741 int maxfd; 742 743 if (setflags) 744 goto msg; 745 746 /* 747 * XXX this has to go, maxfd might be 700 (or something) 748 * 749 * XXX we should only ever operate on user defined fds 750 * XXX not on sh internal fds that might be open. 751 * XXX but for that we need to know their range (later) 752 */ 753 maxfd = fcntl(0, F_MAXFD); 754 if (maxfd == -1) 755 error("Can't get max fd (%s)", strerror(errno)); 756 for (int i = 0; i <= maxfd; i++) 757 printone(i, 0, verbose, 1); 758 return 0; 759 } 760 761 while ((num = *argv++) != NULL) { 762 int fd = number(num); 763 764 if (strlen(num) > 5) 765 error("%s too big to be a file descriptor", num); 766 767 if (setflags) 768 setone(fd, pos, neg, verbose); 769 else 770 printone(fd, 1, verbose, argc > 1); 771 } 772 return 0; 773 } 774