/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <unistd.h>30#include <string.h>31#include <err.h>3233/*34* cat - concatenate and print35* Usage: cat [files]36*/37383940/* Print a file that's already been opened. */41static42void43docat(const char *name, int fd)44{45char buf[1024];46int len, wr, wrtot;4748/*49* As long as we get more than zero bytes, we haven't hit EOF.50* Zero means EOF. Less than zero means an error occurred.51* We may read less than we asked for, though, in various cases52* for various reasons.53*/54while ((len = read(fd, buf, sizeof(buf)))>0) {55/*56* Likewise, we may actually write less than we attempted57* to. So loop until we're done.58*/59wrtot = 0;60while (wrtot < len) {61wr = write(STDOUT_FILENO, buf+wrtot, len-wrtot);62if (wr<0) {63err(1, "stdout");64}65wrtot += wr;66}67}68/*69* If we got a read error, print it and exit.70*/71if (len<0) {72err(1, "%s", name);73}74}7576/* Print a file by name. */77static78void79cat(const char *file)80{81int fd;8283/*84* "-" means print stdin.85*/86if (!strcmp(file, "-")) {87docat("stdin", STDIN_FILENO);88return;89}9091/*92* Open the file, print it, and close it.93* Bail out if we can't open it.94*/95fd = open(file, O_RDONLY);96if (fd<0) {97err(1, "%s", file);98}99docat(file, fd);100close(fd);101}102103104int105main(int argc, char *argv[])106{107if (argc==1) {108/* No args - just do stdin */109docat("stdin", STDIN_FILENO);110}111else {112/* Print all the files specified on the command line. */113int i;114for (i=1; i<argc; i++) {115cat(argv[i]);116}117}118return 0;119}120121122