1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: cat.c,v 1.43 2004/01/04 03:31:28 jschauma 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 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CAT_BUFSIZ (4096) 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int rval; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *filename; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcook_buf(FILE *fp) 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ch, gobble, line, prev; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int stdout_err = 0; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project line = gobble = 0; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prev == '\n') { 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ch == '\n') { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sflag) { 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!gobble && putchar(ch) == EOF) 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gobble = 1; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nflag) { 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!bflag) { 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fprintf(stdout, 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "%6d\t", ++line) < 0) { 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_err++; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (eflag) { 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fprintf(stdout, 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "%6s\t", "") < 0) { 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_err++; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (nflag) { 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fprintf(stdout, "%6d\t", ++line) < 0) { 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_err++; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gobble = 0; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ch == '\n') { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (eflag) 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('$') == EOF) 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ch == '\t') { 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tflag) { 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('^') == EOF || putchar('I') == EOF) 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (vflag) { 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isascii(ch)) { 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('M') == EOF || putchar('-') == EOF) 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ch = (ch) & 0x7f; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (iscntrl(ch)) { 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar('^') == EOF || 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project putchar(ch == '\177' ? '?' : 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ch | 0100) == EOF) 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (putchar(ch) == EOF) 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (stdout_err) { 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror(filename); 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rval = 1; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcook_args(char **argv) 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE *fp; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fp = stdin; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = "stdin"; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argv) { 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(*argv, "-")) 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fp = stdin; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ((fp = fopen(*argv, 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fflag ? "rf" : "r")) == NULL) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("fopen"); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rval = 1; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ++argv; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = *argv++; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cook_buf(fp); 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fp != stdin) 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(fp); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (*argv); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectraw_cat(int rfd) 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char *buf; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char fb_buf[CAT_BUFSIZ]; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static size_t bsize; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat sbuf; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ssize_t nr, nw, off; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int wfd; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wfd = fileno(stdout); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buf == NULL) { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fstat(wfd, &sbuf) == 0) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bsize = sbuf.st_blksize > CAT_BUFSIZ ? 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sbuf.st_blksize : CAT_BUFSIZ; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf = malloc(bsize); 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buf == NULL) { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf = fb_buf; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bsize = CAT_BUFSIZ; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((nr = read(rfd, buf, bsize)) > 0) 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (off = 0; nr; nr -= nw, off += nw) 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("write"); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nr < 0) { 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"%s: invalid length\n", filename); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rval = 1; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectraw_args(char **argv) 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = fileno(stdin); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = "stdin"; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argv) { 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(*argv, "-")) 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = fileno(stdin); 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (fflag) { 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(*argv, O_RDONLY|O_NONBLOCK, 0); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skip; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fstat(fd, &st) == -1) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skip; 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!S_ISREG(st.st_mode)) { 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = EINVAL; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto skipnomsg; 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskip: 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror(*argv); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskipnomsg: 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rval = 1; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ++argv; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project filename = *argv++; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project raw_cat(fd); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd != fileno(stdin)) 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (*argv); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcat_main(int argc, char *argv[]) 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ch; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct flock stdout_lock; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((ch = getopt(argc, argv, "beflnstv")) != -1) 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (ch) { 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'b': 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bflag = nflag = 1; /* -b implies -n */ 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'e': 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project eflag = vflag = 1; /* -e implies -v */ 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'f': 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fflag = 1; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'l': 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project lflag = 1; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nflag = 1; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 's': 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sflag = 1; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 't': 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tflag = vflag = 1; /* -t implies -v */ 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vflag = 1; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '?': 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "usage: cat [-beflnstv] [-] [file ...]\n"); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += optind; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lflag) { 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_lock.l_len = 0; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_lock.l_start = 0; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_lock.l_type = F_WRLCK; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdout_lock.l_whence = SEEK_SET; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("fcntl"); 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (bflag || eflag || nflag || sflag || tflag || vflag) 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cook_args(argv); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project raw_args(argv); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fclose(stdout)) 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("fclose"); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(rval); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 292