head.c revision 24665
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1980, 1987, 1992, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 351590Srgrimesstatic char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1980, 1987, 1992, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4123693Speterstatic char sccsid[] = "@(#)head.c 8.2 (Berkeley) 5/4/95"; 421590Srgrimes#endif /* not lint */ 431590Srgrimes 441590Srgrimes#include <sys/types.h> 4523693Speter 4623693Speter#include <ctype.h> 471590Srgrimes#include <errno.h> 4823693Speter#include <stdio.h> 491590Srgrimes#include <stdlib.h> 501590Srgrimes#include <string.h> 5123693Speter#include <unistd.h> 521590Srgrimes 531590Srgrimes/* 541590Srgrimes * head - give the first few lines of a stream or of each of a set of files 551590Srgrimes * 561590Srgrimes * Bill Joy UCB August 24, 1977 571590Srgrimes */ 581590Srgrimes 591590Srgrimesvoid err __P((int, const char *, ...)); 601590Srgrimesvoid head __P((FILE *, int)); 6124665Salexvoid head_bytes __P((FILE *, int)); 621590Srgrimesvoid obsolete __P((char *[])); 631590Srgrimesvoid usage __P((void)); 641590Srgrimes 651590Srgrimesint eval; 661590Srgrimes 671590Srgrimesint 681590Srgrimesmain(argc, argv) 691590Srgrimes int argc; 701590Srgrimes char *argv[]; 711590Srgrimes{ 721590Srgrimes register int ch; 731590Srgrimes FILE *fp; 7424665Salex int first, linecnt = -1, bytecnt = -1; 751590Srgrimes char *ep; 761590Srgrimes 771590Srgrimes obsolete(argv); 7824665Salex while ((ch = getopt(argc, argv, "n:c:")) != -1) 791590Srgrimes switch(ch) { 8024665Salex case 'c': 8124665Salex bytecnt = strtol(optarg, &ep, 10); 8224665Salex if (*ep || bytecnt <= 0) 8324665Salex err(1, "illegal byte count -- %s", optarg); 8424665Salex break; 851590Srgrimes case 'n': 861590Srgrimes linecnt = strtol(optarg, &ep, 10); 871590Srgrimes if (*ep || linecnt <= 0) 881590Srgrimes err(1, "illegal line count -- %s", optarg); 891590Srgrimes break; 901590Srgrimes case '?': 911590Srgrimes default: 921590Srgrimes usage(); 931590Srgrimes } 941590Srgrimes argc -= optind; 951590Srgrimes argv += optind; 961590Srgrimes 9724665Salex if (linecnt != -1 && bytecnt != -1) 9824665Salex err(1, "can't combine line and byte counts"); 9924665Salex if (linecnt == -1 ) 10024665Salex linecnt = 10; 10124665Salex if (*argv) { 1021590Srgrimes for (first = 1; *argv; ++argv) { 1031590Srgrimes if ((fp = fopen(*argv, "r")) == NULL) { 1041590Srgrimes err(0, "%s: %s", *argv, strerror(errno)); 1051590Srgrimes continue; 1061590Srgrimes } 1071590Srgrimes if (argc > 1) { 1081590Srgrimes (void)printf("%s==> %s <==\n", 1091590Srgrimes first ? "" : "\n", *argv); 1101590Srgrimes first = 0; 1111590Srgrimes } 11224665Salex if (bytecnt == -1) 11324665Salex head(fp, linecnt); 11424665Salex else 11524665Salex head_bytes(fp, bytecnt); 1161590Srgrimes (void)fclose(fp); 1171590Srgrimes } 11824665Salex } 11924665Salex else if (bytecnt == -1) 12024665Salex head(stdin, linecnt); 1211590Srgrimes else 12224665Salex head_bytes(stdin, bytecnt); 12324665Salex 1241590Srgrimes exit(eval); 1251590Srgrimes} 1261590Srgrimes 1271590Srgrimesvoid 1281590Srgrimeshead(fp, cnt) 1291590Srgrimes FILE *fp; 1301590Srgrimes register int cnt; 1311590Srgrimes{ 1321590Srgrimes register int ch; 1331590Srgrimes 13414269Swosch while (cnt && (ch = getc(fp)) != EOF) { 1351590Srgrimes if (putchar(ch) == EOF) 1361590Srgrimes err(1, "stdout: %s", strerror(errno)); 1371590Srgrimes if (ch == '\n') 13810064Sjoerg cnt--; 1391590Srgrimes } 1401590Srgrimes} 1411590Srgrimes 1421590Srgrimesvoid 14324665Salexhead_bytes(fp, cnt) 14424665Salex FILE *fp; 14524665Salex register int cnt; 14624665Salex{ 14724665Salex char buf[4096]; 14824665Salex register int readlen; 14924665Salex 15024665Salex while (cnt) { 15124665Salex if (cnt < sizeof(buf)) 15224665Salex readlen = cnt; 15324665Salex else 15424665Salex readlen = sizeof(buf); 15524665Salex readlen = fread(buf, sizeof(char), readlen, fp); 15624665Salex if (readlen == EOF) 15724665Salex break; 15824665Salex if (fwrite(buf, sizeof(char), readlen, stdout) != readlen) 15924665Salex err(1, "stdout: %s", strerror(errno)); 16024665Salex cnt -= readlen; 16124665Salex } 16224665Salex} 16324665Salex 16424665Salexvoid 1651590Srgrimesobsolete(argv) 1661590Srgrimes char *argv[]; 1671590Srgrimes{ 1681590Srgrimes char *ap; 1691590Srgrimes 17024665Salex while ((ap = *++argv)) { 1711590Srgrimes /* Return if "--" or not "-[0-9]*". */ 1721590Srgrimes if (ap[0] != '-' || ap[1] == '-' || !isdigit(ap[1])) 1731590Srgrimes return; 1741590Srgrimes if ((ap = malloc(strlen(*argv) + 2)) == NULL) 1751590Srgrimes err(1, "%s", strerror(errno)); 1761590Srgrimes ap[0] = '-'; 1771590Srgrimes ap[1] = 'n'; 1781590Srgrimes (void)strcpy(ap + 2, *argv + 1); 1791590Srgrimes *argv = ap; 1801590Srgrimes } 1811590Srgrimes} 1821590Srgrimes 1831590Srgrimesvoid 1841590Srgrimesusage() 1851590Srgrimes{ 1861590Srgrimes (void)fprintf(stderr, "usage: head [-n lines] [file ...]\n"); 1871590Srgrimes exit(1); 1881590Srgrimes} 1891590Srgrimes 1901590Srgrimes#if __STDC__ 1911590Srgrimes#include <stdarg.h> 1921590Srgrimes#else 1931590Srgrimes#include <varargs.h> 1941590Srgrimes#endif 1951590Srgrimes 1961590Srgrimesvoid 1971590Srgrimes#if __STDC__ 1981590Srgrimeserr(int fatal, const char *fmt, ...) 1991590Srgrimes#else 2001590Srgrimeserr(fatal, fmt, va_alist) 2011590Srgrimes int fatal; 2021590Srgrimes char *fmt; 2031590Srgrimes va_dcl 2041590Srgrimes#endif 2051590Srgrimes{ 2061590Srgrimes va_list ap; 2071590Srgrimes#if __STDC__ 2081590Srgrimes va_start(ap, fmt); 2091590Srgrimes#else 2101590Srgrimes va_start(ap); 2111590Srgrimes#endif 2121590Srgrimes (void)fprintf(stderr, "head: "); 2131590Srgrimes (void)vfprintf(stderr, fmt, ap); 2141590Srgrimes va_end(ap); 2151590Srgrimes (void)fprintf(stderr, "\n"); 2161590Srgrimes if (fatal) 2171590Srgrimes exit(1); 2181590Srgrimes eval = 1; 2191590Srgrimes} 220