# HG changeset patch # User Robert Mustacchi # Date 1365000346 25200 # Node ID d8c293f5983b6db92c27cd322750f0119bc41f13 # Parent f0c04f0fa2ad5f7453d4ca8377cf2214e51d782b 3682 /usr/bin/head should implement -c -q and -v Reviewed by: Jerry Jelinek Reviewed by: Carlos Cardenas Reviewed by: Alexander Eremin Reviewed by: Peter Tribble Reviewed by: Garrett D'Amore Approved by: Dan McDonald diff -r f0c04f0fa2ad -r d8c293f5983b usr/src/cmd/head/head.c --- a/usr/src/cmd/head/head.c Thu Apr 04 14:26:49 2013 -0400 +++ b/usr/src/cmd/head/head.c Wed Apr 03 07:45:46 2013 -0700 @@ -36,8 +36,9 @@ * software developed by the University of California, Berkeley, and its * contributors. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include @@ -49,13 +50,13 @@ #define DEF_LINE_COUNT 10 -static void copyout(off_t); +static void copyout(off_t, int); static void Usage(); /* - * head - give the first few lines of a stream or of each of a set of files - * + * head - give the first few lines of a stream or of each of a set of files. + * Optionally shows a specific number of bytes instead. */ int main(int argc, char **argv) @@ -65,7 +66,9 @@ int i; int opt; off_t linecnt = DEF_LINE_COUNT; + int isline = 1; int error = 0; + int quiet = 0; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ @@ -86,7 +89,7 @@ Usage(); } - linecnt = (off_t) strtoll(&argv[i][1], (char **)NULL, + linecnt = (off_t)strtoll(&argv[i][1], (char **)NULL, 10); while (i < argc) { argv[i] = argv[i + 1]; @@ -97,23 +100,31 @@ } /* get options */ - while ((opt = getopt(argc, argv, "n:")) != EOF) { + while ((opt = getopt(argc, argv, "qvn:c:")) != EOF) { switch (opt) { case 'n': + case 'c': if ((strcmp(optarg, "--") == 0) || (optind > argc)) { (void) fprintf(stderr, gettext( - "%s: Missing -n argument\n"), argv[0]), + "%s: Missing -%c argument\n"), argv[0], + optopt); Usage(); } - linecnt = (off_t) strtoll(optarg, (char **)NULL, 10); + linecnt = (off_t)strtoll(optarg, (char **)NULL, 10); if (linecnt <= 0) { (void) fprintf(stderr, gettext( - "%s: Invalid \"-n %s\" option\n"), - argv[0], optarg); + "%s: Invalid \"-%c %s\" option\n"), + argv[0], optopt, optarg); Usage(); } + isline = optopt != 'c'; break; - + case 'q': + quiet = 1; + break; + case 'v': + quiet = 0; + break; default: Usage(); } @@ -135,16 +146,18 @@ } } - if (around) - (void) putchar('\n'); + if (quiet == 0) { + if (around) + (void) putchar('\n'); - if (fileCount > 1) - (void) printf("==> %s <==\n", argv[optind]); + if (fileCount > 1) + (void) printf("==> %s <==\n", argv[optind]); + } if (argv[optind] != NULL) optind++; - copyout(linecnt); + copyout(linecnt, isline); (void) fflush(stdout); around++; @@ -154,20 +167,32 @@ } static void -copyout(cnt) - register off_t cnt; +copyout(off_t cnt, int isline) { char lbuf[BUFSIZ]; size_t len; while (cnt > 0 && fgets(lbuf, sizeof (lbuf), stdin) != 0) { - (void) printf("%s", lbuf); - /* only count as a line if buffer read ends with newline */ - if ((len = strlen(lbuf)) > 0) { - if (lbuf[len - 1] == '\n') { + len = strlen(lbuf); + if (isline) { + (void) printf("%s", lbuf); + /* + * only count as a line if buffer read ends with newline + */ + if (len > 0) { + if (lbuf[len - 1] == '\n') { + (void) fflush(stdout); + cnt--; + } + } + } else { + if (len > cnt) { + lbuf[cnt] = '\0'; + len = cnt; + } + (void) printf("%s", lbuf); + cnt -= len; (void) fflush(stdout); - cnt--; - } } } } @@ -175,6 +200,7 @@ static void Usage() { - (void) printf(gettext("usage: head [-n #] [-#] [filename...]\n")); + (void) printf(gettext("usage: head [-q] [-v] [-n #] [-c #] [-#] " + "[filename...]\n")); exit(1); } diff -r f0c04f0fa2ad -r d8c293f5983b usr/src/man/man1/head.1 --- a/usr/src/man/man1/head.1 Thu Apr 04 14:26:49 2013 -0400 +++ b/usr/src/man/man1/head.1 Wed Apr 03 07:45:46 2013 -0700 @@ -1,4 +1,5 @@ '\" te +.\" Portions Copyright (c) 2013, Joyent, Inc. All Rights Reserved .\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions .\" Copyright 1989 AT&T .\" Portions Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved @@ -10,20 +11,20 @@ .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH HEAD 1 "Nov 2, 2007" +.TH HEAD 1 "Mar 4, 2013" .SH NAME head \- display first few lines of files .SH SYNOPSIS .SS "/usr/bin/head" .LP .nf -\fB/usr/bin/head\fR [\fB-number\fR | \fB-n\fR \fInumber\fR] [\fIfilename\fR]... +\fB/usr/bin/head\fR [\fB-q\fR] [\fB-v\fR] [\fB-number\fR ] [ \fB-n\fR \fInumber\fR ] [ \fB-c\fR \fInumber\fR] [\fIfilename\fR]... .fi .SS "ksh93" .LP .nf -\fBhead\fR [\fB-qv\fR] [\fB-n\fR \fIlines\fR] [\fB-c\fR \fIchars\fR] [\fB-s\fR \fIskip\fR][\fIfilename\fR]... +\fBhead\fR [\fB-qv\fR] [\fB-n\fR \fIlines\fR] [\fB-c\fR \fIchars\fR] [\fB-s\fR \fIskip\fR] [\fIfilename\fR]... .fi .SH DESCRIPTION @@ -33,7 +34,8 @@ The \fBhead\fR utility copies the first \fInumber\fR of lines of each \fIfilename\fR to the standard output. If no \fIfilename\fR is given, \fBhead\fR copies lines from the standard input. The default value of -\fInumber\fR is \fB10\fR lines. +\fInumber\fR is \fB10\fR lines. If \fB-c\fR is specified, \fBhead\fR +copies the first \fInumber\fR of bytes of each filename. .sp .LP When more than one file is specified, the start of each file looks like: @@ -124,6 +126,18 @@ .sp .ne 2 .na +\fB\fB-c\fR \fInumber\fR\fR +.ad +.RS 13n +The first \fInumber\fR bytes of each input file is copied to standard output. +The \fInumber\fR option-argument must be a positive decimal integer. Note, +output may end in the middle of a character if a file contains multi-byte +characters. +.RE + +.sp +.ne 2 +.na \fB\fB-\fR\fInumber\fR\fR .ad .RS 13n @@ -132,6 +146,24 @@ .RE .sp +.ne 2 +.na +\fB\FB-q\fR\fR +.ad +.RS 13n +\fBhead\fR will not print a header in between each specified file. +.RE + +.sp +.ne 2 +.na +\fB\FB-v\fR\fR +.ad +.RS 13n +\fBhead\fR will always print a header in between each specified file. +.RE + +.sp .LP If no options are specified, \fBhead\fR acts as if \fB-n\fR \fB10\fR had been specified.