17bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* $NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $ */ 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1989, 1993 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The Regents of the University of California. All rights reserved. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kevin Fall. 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * documentation and/or other materials provided with the distribution. 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * may be used to endorse or promote products derived from this software 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * without specific prior written permission. 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if HAVE_NBTOOL_CONFIG_H 367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include "nbtool_config.h" 377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif 387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <sys/cdefs.h> 407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if !defined(lint) 417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes__COPYRIGHT( 427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes"@(#) Copyright (c) 1989, 1993\ 437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes The Regents of the University of California. All rights reserved."); 447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if 0 457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95"; 467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#else 477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes__RCSID("$NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $"); 487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif 497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif /* not lint */ 507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h> 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <err.h> 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <locale.h> 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag; 657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic size_t bsize; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int rval; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *filename; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid cook_args(char *argv[]); 707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid cook_buf(FILE *); 717bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid raw_args(char *argv[]); 727bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid raw_cat(int); 737bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 747bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesint 757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesmain(int argc, char *argv[]) 767bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes int ch; 787bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes struct flock stdout_lock; 797bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes setprogname(argv[0]); 817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)setlocale(LC_ALL, ""); 827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes while ((ch = getopt(argc, argv, "B:beflnstuv")) != -1) 847bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes switch (ch) { 857bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'B': 867bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes bsize = (size_t)strtol(optarg, NULL, 0); 877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 887bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'b': 897bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes bflag = nflag = 1; /* -b implies -n */ 907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'e': 927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes eflag = vflag = 1; /* -e implies -v */ 937bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'f': 957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes fflag = 1; 967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'l': 987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes lflag = 1; 997bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'n': 1017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes nflag = 1; 1027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 's': 1047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes sflag = 1; 1057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 't': 1077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes tflag = vflag = 1; /* -t implies -v */ 1087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'u': 1107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes setbuf(stdout, NULL); 1117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case 'v': 1137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes vflag = 1; 1147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes default: 1167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes case '?': 1177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fprintf(stderr, 1187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes "Usage: %s [-beflnstuv] [-B bsize] [-] " 1197bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes "[file ...]\n", getprogname()); 1207bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes return EXIT_FAILURE; 1217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes argv += optind; 1237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (lflag) { 1257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes stdout_lock.l_len = 0; 1267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes stdout_lock.l_start = 0; 1277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes stdout_lock.l_type = F_WRLCK; 1287bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes stdout_lock.l_whence = SEEK_SET; 1297bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) 1307bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdout"); 1317bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1327bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1337bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (bflag || eflag || nflag || sflag || tflag || vflag) 1347bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cook_args(argv); 1357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else 1367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes raw_args(argv); 1377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (fclose(stdout)) 1387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdout"); 1397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes return rval; 1407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 1417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 1437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughescook_args(char **argv) 1447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 1457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes FILE *fp; 1467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes fp = stdin; 1487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes filename = "stdin"; 1497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes do { 1507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (*argv) { 1517bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!strcmp(*argv, "-")) 1527bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes fp = stdin; 1537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else if ((fp = fopen(*argv, 1547bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes fflag ? "rf" : "r")) == NULL) { 1557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warn("%s", *argv); 1567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes rval = EXIT_FAILURE; 1577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ++argv; 1587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes continue; 1597bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1607bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes filename = *argv++; 1617bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1627bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cook_buf(fp); 1637bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (fp != stdin) 1647bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fclose(fp); 1657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else 1667bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes clearerr(fp); 1677bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } while (*argv); 1687bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 1697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcook_buf(FILE *fp) 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ch, gobble, line, prev; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project line = gobble = 0; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prev == '\n') { 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ch == '\n') { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sflag) { 1807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!gobble && nflag && !bflag) 1817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fprintf(stdout, 1827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes "%6d\t\n", ++line); 1837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else if (!gobble && putchar(ch) == EOF) 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gobble = 1; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nflag) { 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!bflag) { 1907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fprintf(stdout, 1917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes "%6d\t", ++line); 1927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ferror(stdout)) 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (eflag) { 1957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fprintf(stdout, 1967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes "%6s\t", ""); 1977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ferror(stdout)) 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (nflag) { 2027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)fprintf(stdout, "%6d\t", ++line); 2037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ferror(stdout)) 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gobble = 0; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ch == '\n') { 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (eflag) 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('$') == EOF) 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ch == '\t') { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tflag) { 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('^') == EOF || putchar('I') == EOF) 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (vflag) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isascii(ch)) { 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('M') == EOF || putchar('-') == EOF) 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 2227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ch = toascii(ch); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (iscntrl(ch)) { 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('^') == EOF || 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project putchar(ch == '\177' ? '?' : 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ch | 0100) == EOF) 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar(ch) == EOF) 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ferror(fp)) { 2367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warn("%s", filename); 2377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes rval = EXIT_FAILURE; 2387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes clearerr(fp); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ferror(stdout)) 2417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdout"); 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectraw_args(char **argv) 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = fileno(stdin); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = "stdin"; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argv) { 2537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!strcmp(*argv, "-")) { 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = fileno(stdin); 2557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (fd < 0) 2567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes goto skip; 2577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } else if (fflag) { 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(*argv, O_RDONLY|O_NONBLOCK, 0); 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skip; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fstat(fd, &st) == -1) { 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skip; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!S_ISREG(st.st_mode)) { 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 2697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warnx("%s: not a regular file", *argv); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skipnomsg; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskip: 2757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warn("%s", *argv); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskipnomsg: 2777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes rval = EXIT_FAILURE; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ++argv; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = *argv++; 2827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } else if (fd < 0) { 2837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdin"); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project raw_cat(fd); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd != fileno(stdin)) 2877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)close(fd); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (*argv); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 2927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesraw_cat(int rfd) 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes static char *buf; 2957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes static char fb_buf[BUFSIZ]; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ssize_t nr, nw, off; 2987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes int wfd; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes wfd = fileno(stdout); 3017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (wfd < 0) 3027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdout"); 3037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (buf == NULL) { 3047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes struct stat sbuf; 3057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 3067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (bsize == 0) { 3077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (fstat(wfd, &sbuf) == 0 && sbuf.st_blksize > 0 && 3087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (size_t)sbuf.st_blksize > sizeof(fb_buf)) 3097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes bsize = sbuf.st_blksize; 3107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 3117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (bsize > sizeof(fb_buf)) { 3127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes buf = malloc(bsize); 3137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (buf == NULL) 3147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warnx("malloc, using %zu buffer", bsize); 3157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 3167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (buf == NULL) { 3177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes bsize = sizeof(fb_buf); 3187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes buf = fb_buf; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes while ((nr = read(rfd, buf, bsize)) > 0) 3227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (off = 0; nr; nr -= nw, off += nw) 3237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) 3247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes err(EXIT_FAILURE, "stdout"); 3257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (nr < 0) { 3267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warn("%s", filename); 3277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes rval = EXIT_FAILURE; 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 330