Importing usr.bin/head

This commit is contained in:
Thomas Cort 2013-03-18 22:56:28 +00:00 committed by Lionel Sambuc
parent d5a4c35980
commit ab046ee6ea
10 changed files with 311 additions and 132 deletions

View File

@ -10,7 +10,7 @@ SUBDIR= add_route arp ash at backup basename btrace \
dhrystone diff dirname diskctl dumpcore \
eject env expand factor fbdctl \
find finger fingerd fix fold format fortune fsck.mfs \
ftp101 gcore gcov-pull getty grep head hexdump host \
ftp101 gcore gcov-pull getty grep hexdump host \
hostaddr id ifconfig ifdef \
intr ipcrm ipcs irdpd isoread last \
less loadkeys loadramdisk logger look lp \

View File

@ -1,4 +0,0 @@
PROG= head
MAN=
.include <bsd.prog.mk>

View File

@ -1,88 +0,0 @@
/* head - print the first few lines of a file Author: Andy Tanenbaum */
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEFAULT 10
int main(int argc, char **argv);
void do_file(int n, FILE *f);
void usage(void);
int main(argc, argv)
int argc;
char *argv[];
{
FILE *f;
int legacy, n, k, nfiles;
char *ptr;
/* Check for flags. One can only specify how many lines to print. */
k = 1;
n = DEFAULT;
legacy = 0;
for (k = 1; k < argc && argv[k][0] == '-'; k++) {
ptr = &argv[k][1];
if (ptr[0] == 'n' && ptr[1] == 0) {
k++;
if (k >= argc) usage();
ptr = argv[k];
}
else if (ptr[0] == '-' && ptr[1] == 0) {
k++;
break;
}
else if (++legacy > 1) usage();
n = atoi(ptr);
if (n <= 0) usage();
}
nfiles = argc - k;
if (nfiles == 0) {
/* Print standard input only. */
do_file(n, stdin);
exit(0);
}
/* One or more files have been listed explicitly. */
while (k < argc) {
if (nfiles > 1) printf("==> %s <==\n", argv[k]);
if ((f = fopen(argv[k], "r")) == NULL)
fprintf(stderr, "%s: cannot open %s: %s\n",
argv[0], argv[k], strerror(errno));
else {
do_file(n, f);
fclose(f);
}
k++;
if (k < argc) printf("\n");
}
return(0);
}
void do_file(n, f)
int n;
FILE *f;
{
int c;
/* Print the first 'n' lines of a file. */
while (n) switch (c = getc(f)) {
case EOF:
return;
case '\n':
--n;
default: putc((char) c, stdout);
}
}
void usage()
{
fprintf(stderr, "Usage: head [-lines | -n lines] [file ...]\n");
exit(1);
}

View File

@ -6,7 +6,7 @@ MAN= ash.1 at.1 basename.1 \
dumpcore.1 eject.1 \
env.1 expand.1 factor.1 \
finger.1 flexdoc.1 fold.1 format.1 fortune.1 \
fsck.mfs.1 head.1 host.1 hostaddr.1 ifdef.1 \
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
isodir.1 isoinfo.1 isoread.1 \
last.1 loadfont.1 loadkeys.1 logger.1 \
look.1 lp.1 lspci.1 mail.1 \

View File

@ -1,37 +0,0 @@
.TH HEAD 1
.SH NAME
head \- print the first few lines of a file
.SH SYNOPSIS
\fBhead\fR [\fB\-\fIn\fR | \fB\-n\fR \fIn\fR]\fR [\fIfile\fR] ...\fR
.br
.de FL
.TP
\\fB\\$1\\fR
\\$2
..
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.SH OPTIONS
.TP 5
.B \-n \fIn\fR
# How many lines to print
.TP 5
.B \-\fIn\fR
# How many lines to print (backwards-compatible)
.SH EXAMPLES
.TP 20
.B head \-n 6
# Print first 6 lines of \fIstdin\fR
.TP 20
.B head \-1 file1 file2
# Print first line of two files
.SH DESCRIPTION
.PP
The first few lines of one or more files are printed.
The default count is 10 lines.
The default file is \fIstdin\fR.
.SH "SEE ALSO"
.BR tail (1).

View File

@ -130,6 +130,7 @@
2012/10/17 12:00:00,usr.bin/col
2012/10/17 12:00:00,usr.bin/ctags
2011/09/01 13:37:33,usr.bin/du
2013/03/18 12:00:00,usr.bin/head
2012/10/17 12:00:00,usr.bin/genassym
2013/03/09 12:00:00,usr.bin/getopt
2012/10/17 12:00:00,usr.bin/gzip

View File

@ -11,7 +11,7 @@ SUBDIR= \
du \
\
\
genassym getopt \
genassym getopt head \
indent infocmp join \
ldd \
login lorder m4 \

6
usr.bin/head/Makefile Normal file
View File

@ -0,0 +1,6 @@
# $NetBSD: Makefile,v 1.4 1997/10/18 13:15:18 mrg Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= head
.include <bsd.prog.mk>

97
usr.bin/head/head.1 Normal file
View File

@ -0,0 +1,97 @@
.\" $NetBSD: head.1,v 1.12 2004/05/04 23:44:21 wiz Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)head.1 8.1 (Berkeley) 6/6/93
.\"
.Dd May 4, 2004
.Dt HEAD 1
.Os
.Sh NAME
.Nm head
.Nd display first lines of a file
.Sh SYNOPSIS
.Nm
.Op Fl qv
.Op Fl n Ar count
.Op Fl c Ar byte_count
.Op Ar file ...
.Sh DESCRIPTION
This filter displays the first
.Ar count
lines of each of the specified files, or of the standard input if no
files are specified.
If
.Ar count
is omitted it defaults to 10.
If
.Fl c Ar byte_count
is specified,
.Nm
counts bytes instead of lines.
.Pp
If more than a single file is specified, or the
.Fl v
option is used, each file is preceded by a header consisting of the string
.Dq ==\*[Gt] XXX \*[Le]=
where
.Dq XXX
is the name of the file.
The
.Fl q
flag disables the printing of the header in all cases.
.Pp
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
.Sh COMPATIBILITY
The historic command line syntax of
.Nm
is supported by this implementation.
.Pp
This command is mostly compatible with GNU extensions to
.Nm .
.Sh SEE ALSO
.Xr tail 1
.Sh STANDARDS
The
.Nm
utility conforms to
.St -p1003.2-92 .
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 3.0 .
It was enhanced to include the
.Fl c ,
.Fl q ,
and
.Fl v
options for
.Nx 2.1 .

204
usr.bin/head/head.c Normal file
View File

@ -0,0 +1,204 @@
/* $NetBSD: head.c,v 1.23 2010/03/31 21:55:23 joerg Exp $ */
/*
* Copyright (c) 1980, 1987, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1987, 1992, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)head.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: head.c,v 1.23 2010/03/31 21:55:23 joerg Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* head - give the first few lines of a stream or of each of a set of files
*
* Bill Joy UCB August 24, 1977
*/
static void head(FILE *, intmax_t, intmax_t);
static void obsolete(char *[]);
__dead static void usage(void);
int
main(int argc, char *argv[])
{
int ch;
FILE *fp;
int first;
uintmax_t linecnt;
uintmax_t bytecnt;
char *ep;
int eval = 0;
int qflag = 0;
int vflag = 0;
(void)setlocale(LC_ALL, "");
obsolete(argv);
linecnt = 10;
bytecnt = 0;
while ((ch = getopt(argc, argv, "c:n:qv")) != -1)
switch(ch) {
case 'c':
errno = 0;
bytecnt = strtoimax(optarg, &ep, 10);
if ((bytecnt == INTMAX_MAX && errno == ERANGE) ||
*ep || bytecnt <= 0)
errx(1, "illegal byte count -- %s", optarg);
break;
case 'n':
errno = 0;
linecnt = strtoimax(optarg, &ep, 10);
if ((linecnt == INTMAX_MAX && errno == ERANGE) ||
*ep || linecnt <= 0)
errx(1, "illegal line count -- %s", optarg);
break;
case 'q':
qflag = 1;
vflag = 0;
break;
case 'v':
qflag = 0;
vflag = 1;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (*argv)
for (first = 1; *argv; ++argv) {
if ((fp = fopen(*argv, "r")) == NULL) {
warn("%s", *argv);
eval = 1;
continue;
}
if (vflag || (qflag == 0 && argc > 1)) {
(void)printf("%s==> %s <==\n",
first ? "" : "\n", *argv);
first = 0;
}
head(fp, linecnt, bytecnt);
(void)fclose(fp);
}
else
head(stdin, linecnt, bytecnt);
exit(eval);
}
static void
head(FILE *fp, intmax_t cnt, intmax_t bytecnt)
{
char buf[65536];
size_t len, rv, rv2;
int ch;
if (bytecnt) {
while (bytecnt) {
len = sizeof(buf);
if (bytecnt > (intmax_t)sizeof(buf))
len = sizeof(buf);
else
len = bytecnt;
rv = fread(buf, 1, len, fp);
if (rv == 0)
break; /* Distinguish EOF and error? */
rv2 = fwrite(buf, 1, rv, stdout);
if (rv2 != rv) {
if (feof(stdout))
errx(1, "EOF on stdout");
else
err(1, "failure writing to stdout");
}
bytecnt -= rv;
}
} else {
while ((ch = getc(fp)) != EOF) {
if (putchar(ch) == EOF)
err(1, "stdout");
if (ch == '\n' && --cnt == 0)
break;
}
}
}
static void
obsolete(char *argv[])
{
char *ap;
while ((ap = *++argv)) {
/* Return if "--" or not "-[0-9]*". */
if (ap[0] != '-' || ap[1] == '-' ||
!isdigit((unsigned char)ap[1]))
return;
if ((ap = malloc(strlen(*argv) + 2)) == NULL)
err(1, NULL);
ap[0] = '-';
ap[1] = 'n';
(void)strcpy(ap + 2, *argv + 1);
*argv = ap;
}
}
static void
usage(void)
{
(void)fprintf(stderr, "usage: %s [-n lines] [file ...]\n",
getprogname());
exit(1);
}