Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/coreutils/tee.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/coreutils/tee.c
r821 r1770 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ 25 12 26 #include <stdio.h> 27 #include <stdlib.h> 13 #include "libbb.h" 28 14 #include <signal.h> 29 #include <unistd.h>30 #include "busybox.h"31 15 16 int tee_main(int argc, char **argv); 32 17 int tee_main(int argc, char **argv) 33 18 { 34 19 const char *mode = "w\0a"; 35 20 FILE **files; 36 FILE ** p;37 char ** filenames;38 int flags;39 int retval = EXIT_SUCCESS;40 #if def CONFIG_FEATURE_TEE_USE_BLOCK_IO21 FILE **fp; 22 char **names; 23 char **np; 24 char retval; 25 #if ENABLE_FEATURE_TEE_USE_BLOCK_IO 41 26 ssize_t c; 42 27 # define buf bb_common_bufsiz1 … … 44 29 int c; 45 30 #endif 31 retval = getopt32(argv, "ia"); /* 'a' must be 2nd */ 32 argc -= optind; 33 argv += optind; 46 34 47 flags = bb_getopt_ulflags(argc, argv, "ia"); /* 'a' must be 2nd*/35 mode += (retval & 2); /* Since 'a' is the 2nd option... */ 48 36 49 mode += (flags & 2); /* Since 'a' is the 2nd option... */ 50 51 if (flags & 1) { 52 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction.*/ 37 if (retval & 1) { 38 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. */ 53 39 } 54 40 retval = EXIT_SUCCESS; 55 41 /* gnu tee ignores SIGPIPE in case one of the output files is a pipe 56 42 * that doesn't consume all its input. Good idea... */ 57 signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/43 signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction. */ 58 44 59 45 /* Allocate an array of FILE *'s, with one extra for a sentinal. */ 60 p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); 61 *p = stdout; 62 argv += optind - 1; 63 filenames = argv - 1; 64 *filenames = (char *) bb_msg_standard_input; /* for later */ 46 fp = files = xzalloc(sizeof(FILE *) * (argc + 2)); 47 np = names = argv - 1; 48 49 files[0] = stdout; 65 50 goto GOT_NEW_FILE; 66 67 51 do { 68 if ((*p = bb_wfopen(*argv, mode)) == NULL) { 52 *fp = fopen_or_warn(*argv, mode); 53 if (*fp == NULL) { 69 54 retval = EXIT_FAILURE; 70 55 continue; 71 56 } 72 filenames[(int)(p - files)] = *argv; 73 GOT_NEW_FILE: 74 setbuf(*p, NULL); /* tee must not buffer output. */ 75 ++p; 76 } while (*++argv); 57 *np = *argv++; 58 GOT_NEW_FILE: 59 setbuf(*fp++, NULL); /* tee must not buffer output. */ 60 np++; 61 } while (*argv); 62 /* names[0] will be filled later */ 77 63 78 *p = NULL; /* Store the sentinal value. */ 79 80 #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO 64 #if ENABLE_FEATURE_TEE_USE_BLOCK_IO 81 65 while ((c = safe_read(STDIN_FILENO, buf, BUFSIZ)) > 0) { 82 for (p=files ; *p ; p++) { 83 fwrite(buf, 1, c, *p); 84 } 66 fp = files; 67 do 68 fwrite(buf, 1, c, *fp++); 69 while (*fp); 85 70 } 86 87 if (c < 0) { /* Make sure read errors are signaled. */ 71 if (c < 0) { /* Make sure read errors are signaled. */ 88 72 retval = EXIT_FAILURE; 89 73 } 90 91 74 #else 92 75 setvbuf(stdout, NULL, _IONBF, 0); 93 76 while ((c = getchar()) != EOF) { 94 for (p=files ; *p ; p++) { 95 putc(c, *p); 96 } 77 fp = files; 78 do 79 putc(c, *fp++); 80 while (*fp); 97 81 } 98 82 #endif … … 102 86 * file table is stdout, we can save one "if ferror" test by 103 87 * setting the first entry to stdin and checking stdout error 104 * status with bb_fflush_stdout_and_exit()... although fflush()ing88 * status with fflush_stdout_and_exit()... although fflush()ing 105 89 * is unnecessary here. */ 106 107 p = files; 108 *p = stdin; 109 do { /* Now check for (input and) output errors. */ 90 np = names; 91 fp = files; 92 names[0] = (char *) bb_msg_standard_input; 93 files[0] = stdin; 94 do { /* Now check for input and output errors. */ 110 95 /* Checking ferror should be sufficient, but we may want to fclose. 111 96 * If we do, remember not to close stdin! */ 112 bb_xferror(*p, filenames[(int)(p - files)]);113 } while (* ++p);97 die_if_ferror(*fp++, *np++); 98 } while (*fp); 114 99 115 bb_fflush_stdout_and_exit(retval);100 fflush_stdout_and_exit(retval); 116 101 }
Note:
See TracChangeset
for help on using the changeset viewer.