Import NetBSD cat(1)
This commit is contained in:
parent
7e81b07cc5
commit
24f1e18846
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
SUBDIR= date ed mkdir rm rmdir
|
SUBDIR= cat date ed mkdir rm rmdir
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
6
bin/cat/Makefile
Normal file
6
bin/cat/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# $NetBSD: Makefile,v 1.12 2003/05/18 07:57:31 lukem Exp $
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||||
|
|
||||||
|
PROG= cat
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
209
bin/cat/cat.1
Normal file
209
bin/cat/cat.1
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
.\" $NetBSD: cat.1,v 1.32 2006/09/23 11:24:44 wiz Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1989, 1990, 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" This code is derived from software contributed to Berkeley by
|
||||||
|
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
||||||
|
.\"
|
||||||
|
.\" 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.
|
||||||
|
.\"
|
||||||
|
.\" @(#)cat.1 8.3 (Berkeley) 5/2/95
|
||||||
|
.\"
|
||||||
|
.Dd September 23, 2006
|
||||||
|
.Dt CAT 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm cat
|
||||||
|
.Nd concatenate and print files
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl beflnstuv
|
||||||
|
.Op Fl
|
||||||
|
.Op Ar
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility reads files sequentially, writing them to the standard output.
|
||||||
|
The
|
||||||
|
.Ar file
|
||||||
|
operands are processed in command line order.
|
||||||
|
A single dash represents the standard input,
|
||||||
|
and may appear multiple times in the
|
||||||
|
.Ar file
|
||||||
|
list.
|
||||||
|
.Pp
|
||||||
|
The word
|
||||||
|
.Dq concatenate
|
||||||
|
is just a verbose synonym for
|
||||||
|
.Dq catenate .
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fl b
|
||||||
|
Implies the
|
||||||
|
.Fl n
|
||||||
|
option but doesn't number blank lines.
|
||||||
|
.It Fl e
|
||||||
|
Implies the
|
||||||
|
.Fl v
|
||||||
|
option, and displays a dollar sign
|
||||||
|
.Pq Ql \&$
|
||||||
|
at the end of each line
|
||||||
|
as well.
|
||||||
|
.It Fl f
|
||||||
|
Only attempt to display regular files.
|
||||||
|
.It Fl l
|
||||||
|
Set an exclusive advisory lock on the standard output file descriptor.
|
||||||
|
This lock is set using
|
||||||
|
.Xr fcntl 2
|
||||||
|
with the
|
||||||
|
.Dv F_SETLKW
|
||||||
|
command.
|
||||||
|
If the output file is already locked,
|
||||||
|
.Nm
|
||||||
|
will block until the lock is acquired.
|
||||||
|
.It Fl n
|
||||||
|
Number the output lines, starting at 1.
|
||||||
|
.It Fl s
|
||||||
|
Squeeze multiple adjacent empty lines, causing the output to be
|
||||||
|
single spaced.
|
||||||
|
.It Fl t
|
||||||
|
Implies the
|
||||||
|
.Fl v
|
||||||
|
option, and displays tab characters as
|
||||||
|
.Ql ^I
|
||||||
|
as well.
|
||||||
|
.It Fl u
|
||||||
|
The
|
||||||
|
.Fl u
|
||||||
|
option guarantees that the output is unbuffered.
|
||||||
|
.It Fl v
|
||||||
|
Displays non-printing characters so they are visible.
|
||||||
|
Control characters print as
|
||||||
|
.Ql ^X
|
||||||
|
for control-X; the delete
|
||||||
|
character (octal 0177) prints as
|
||||||
|
.Ql ^? .
|
||||||
|
Non-ascii characters (with the high bit set) are printed as
|
||||||
|
.Ql M-
|
||||||
|
(for meta) followed by the character for the low 7 bits.
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility exits 0 on success, and \*[Gt]0 if an error occurs.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
The command:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
.Ic cat file1
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
will print the contents of
|
||||||
|
.Ar file1
|
||||||
|
to the standard output.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
.Ic cat file1 file2 \*[Gt] file3
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
will sequentially print the contents of
|
||||||
|
.Ar file1
|
||||||
|
and
|
||||||
|
.Ar file2
|
||||||
|
to the file
|
||||||
|
.Ar file3 ,
|
||||||
|
truncating
|
||||||
|
.Ar file3
|
||||||
|
if it already exists.
|
||||||
|
See the manual page for your shell (i.e.,
|
||||||
|
.Xr sh 1 )
|
||||||
|
for more information on redirection.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
.Ic cat file1 - file2 - file3
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
will print the contents of
|
||||||
|
.Ar file1 ,
|
||||||
|
print data it receives from the standard input until it receives an
|
||||||
|
.Dv EOF
|
||||||
|
.Pq Sq ^D
|
||||||
|
character, print the contents of
|
||||||
|
.Ar file2 ,
|
||||||
|
read and output contents of the standard input again, then finally output
|
||||||
|
the contents of
|
||||||
|
.Ar file3 .
|
||||||
|
Note that if the standard input referred to a file, the second dash
|
||||||
|
on the command-line would have no effect, since the entire contents of the file
|
||||||
|
would have already been read and printed by
|
||||||
|
.Nm
|
||||||
|
when it encountered the first
|
||||||
|
.Ql \&-
|
||||||
|
operand.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr head 1 ,
|
||||||
|
.Xr hexdump 1 ,
|
||||||
|
.Xr lpr 1 ,
|
||||||
|
.Xr more 1 ,
|
||||||
|
.Xr pr 1 ,
|
||||||
|
.Xr tail 1 ,
|
||||||
|
.Xr view 1 ,
|
||||||
|
.Xr vis 1 ,
|
||||||
|
.Xr fcntl 2
|
||||||
|
.Rs
|
||||||
|
.%A Rob Pike
|
||||||
|
.%T "UNIX Style, or cat -v Considered Harmful"
|
||||||
|
.%J "USENIX Summer Conference Proceedings"
|
||||||
|
.%D 1983
|
||||||
|
.Re
|
||||||
|
.Sh STANDARDS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is expected to conform to the
|
||||||
|
.St -p1003.2-92
|
||||||
|
specification.
|
||||||
|
.Pp
|
||||||
|
The flags
|
||||||
|
.Op Fl belnstv
|
||||||
|
are extensions to the specification.
|
||||||
|
.Sh HISTORY
|
||||||
|
A
|
||||||
|
.Nm
|
||||||
|
utility appeared in
|
||||||
|
.At v1 .
|
||||||
|
Dennis Ritchie designed and wrote the first man page.
|
||||||
|
It appears to have been
|
||||||
|
.Xr cat 1 .
|
||||||
|
.Sh BUGS
|
||||||
|
Because of the shell language mechanism used to perform output
|
||||||
|
redirection, the command
|
||||||
|
.Dq Li cat file1 file2 \*[Gt] file1
|
||||||
|
will cause the original data in file1 to be destroyed!
|
||||||
|
This is performed by the shell before
|
||||||
|
.Nm
|
||||||
|
is run.
|
316
bin/cat/cat.c
Normal file
316
bin/cat/cat.c
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
/* $NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Kevin Fall.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_NBTOOL_CONFIG_H
|
||||||
|
#include "nbtool_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if !defined(lint)
|
||||||
|
__COPYRIGHT(
|
||||||
|
"@(#) Copyright (c) 1989, 1993\
|
||||||
|
The Regents of the University of California. All rights reserved.");
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
|
||||||
|
int rval;
|
||||||
|
const char *filename;
|
||||||
|
|
||||||
|
int main(int, char *[]);
|
||||||
|
void cook_args(char *argv[]);
|
||||||
|
void cook_buf(FILE *);
|
||||||
|
void raw_args(char *argv[]);
|
||||||
|
void raw_cat(int);
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
struct flock stdout_lock;
|
||||||
|
|
||||||
|
setprogname(argv[0]);
|
||||||
|
(void)setlocale(LC_ALL, "");
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "beflnstuv")) != -1)
|
||||||
|
switch (ch) {
|
||||||
|
case 'b':
|
||||||
|
bflag = nflag = 1; /* -b implies -n */
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
eflag = vflag = 1; /* -e implies -v */
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
fflag = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
lflag = 1;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
nflag = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sflag = 1;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
tflag = vflag = 1; /* -t implies -v */
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
setbuf(stdout, NULL);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
vflag = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case '?':
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
"usage: cat [-beflnstuv] [-] [file ...]\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (lflag) {
|
||||||
|
stdout_lock.l_len = 0;
|
||||||
|
stdout_lock.l_start = 0;
|
||||||
|
stdout_lock.l_type = F_WRLCK;
|
||||||
|
stdout_lock.l_whence = SEEK_SET;
|
||||||
|
if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
|
||||||
|
err(EXIT_FAILURE, "stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bflag || eflag || nflag || sflag || tflag || vflag)
|
||||||
|
cook_args(argv);
|
||||||
|
else
|
||||||
|
raw_args(argv);
|
||||||
|
if (fclose(stdout))
|
||||||
|
err(EXIT_FAILURE, "stdout");
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cook_args(char **argv)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = stdin;
|
||||||
|
filename = "stdin";
|
||||||
|
do {
|
||||||
|
if (*argv) {
|
||||||
|
if (!strcmp(*argv, "-"))
|
||||||
|
fp = stdin;
|
||||||
|
else if ((fp = fopen(*argv,
|
||||||
|
fflag ? "rf" : "r")) == NULL) {
|
||||||
|
warn("%s", *argv);
|
||||||
|
rval = EXIT_FAILURE;
|
||||||
|
++argv;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
filename = *argv++;
|
||||||
|
}
|
||||||
|
cook_buf(fp);
|
||||||
|
if (fp != stdin)
|
||||||
|
(void)fclose(fp);
|
||||||
|
else
|
||||||
|
clearerr(fp);
|
||||||
|
} while (*argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cook_buf(FILE *fp)
|
||||||
|
{
|
||||||
|
int ch, gobble, line, prev;
|
||||||
|
|
||||||
|
line = gobble = 0;
|
||||||
|
for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
|
||||||
|
if (prev == '\n') {
|
||||||
|
if (ch == '\n') {
|
||||||
|
if (sflag) {
|
||||||
|
if (!gobble && nflag && !bflag)
|
||||||
|
(void)fprintf(stdout,
|
||||||
|
"%6d\t\n", ++line);
|
||||||
|
else if (!gobble && putchar(ch) == EOF)
|
||||||
|
break;
|
||||||
|
gobble = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nflag) {
|
||||||
|
if (!bflag) {
|
||||||
|
(void)fprintf(stdout,
|
||||||
|
"%6d\t", ++line);
|
||||||
|
if (ferror(stdout))
|
||||||
|
break;
|
||||||
|
} else if (eflag) {
|
||||||
|
(void)fprintf(stdout,
|
||||||
|
"%6s\t", "");
|
||||||
|
if (ferror(stdout))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nflag) {
|
||||||
|
(void)fprintf(stdout, "%6d\t", ++line);
|
||||||
|
if (ferror(stdout))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gobble = 0;
|
||||||
|
if (ch == '\n') {
|
||||||
|
if (eflag)
|
||||||
|
if (putchar('$') == EOF)
|
||||||
|
break;
|
||||||
|
} else if (ch == '\t') {
|
||||||
|
if (tflag) {
|
||||||
|
if (putchar('^') == EOF || putchar('I') == EOF)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (vflag) {
|
||||||
|
if (!isascii(ch)) {
|
||||||
|
if (putchar('M') == EOF || putchar('-') == EOF)
|
||||||
|
break;
|
||||||
|
ch = toascii(ch);
|
||||||
|
}
|
||||||
|
if (iscntrl(ch)) {
|
||||||
|
if (putchar('^') == EOF ||
|
||||||
|
putchar(ch == '\177' ? '?' :
|
||||||
|
ch | 0100) == EOF)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (putchar(ch) == EOF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ferror(fp)) {
|
||||||
|
warn("%s", filename);
|
||||||
|
rval = EXIT_FAILURE;
|
||||||
|
clearerr(fp);
|
||||||
|
}
|
||||||
|
if (ferror(stdout))
|
||||||
|
err(EXIT_FAILURE, "stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
raw_args(char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = fileno(stdin);
|
||||||
|
filename = "stdin";
|
||||||
|
do {
|
||||||
|
if (*argv) {
|
||||||
|
if (!strcmp(*argv, "-"))
|
||||||
|
fd = fileno(stdin);
|
||||||
|
else if (fflag) {
|
||||||
|
struct stat st;
|
||||||
|
fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
if (fstat(fd, &st) == -1) {
|
||||||
|
close(fd);
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
if (!S_ISREG(st.st_mode)) {
|
||||||
|
close(fd);
|
||||||
|
warnx("%s: not a regular file", *argv);
|
||||||
|
goto skipnomsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
|
||||||
|
skip:
|
||||||
|
warn("%s", *argv);
|
||||||
|
skipnomsg:
|
||||||
|
rval = EXIT_FAILURE;
|
||||||
|
++argv;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
filename = *argv++;
|
||||||
|
}
|
||||||
|
raw_cat(fd);
|
||||||
|
if (fd != fileno(stdin))
|
||||||
|
(void)close(fd);
|
||||||
|
} while (*argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
raw_cat(int rfd)
|
||||||
|
{
|
||||||
|
static char *buf;
|
||||||
|
static char fb_buf[BUFSIZ];
|
||||||
|
static size_t bsize;
|
||||||
|
|
||||||
|
ssize_t nr, nw, off;
|
||||||
|
int wfd;
|
||||||
|
|
||||||
|
wfd = fileno(stdout);
|
||||||
|
if (buf == NULL) {
|
||||||
|
struct stat sbuf;
|
||||||
|
|
||||||
|
if (fstat(wfd, &sbuf) == 0 &&
|
||||||
|
sbuf.st_blksize > sizeof(fb_buf)) {
|
||||||
|
bsize = sbuf.st_blksize;
|
||||||
|
buf = malloc(bsize);
|
||||||
|
}
|
||||||
|
if (buf == NULL) {
|
||||||
|
bsize = sizeof(fb_buf);
|
||||||
|
buf = fb_buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((nr = read(rfd, buf, bsize)) > 0)
|
||||||
|
for (off = 0; nr; nr -= nw, off += nw)
|
||||||
|
if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
|
||||||
|
err(EXIT_FAILURE, "stdout");
|
||||||
|
if (nr < 0) {
|
||||||
|
warn("%s", filename);
|
||||||
|
rval = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
SUBDIR= add_route arp ash at awk \
|
SUBDIR= add_route arp ash at awk \
|
||||||
backup badblocks banner basename \
|
backup badblocks banner basename \
|
||||||
btrace cal calendar \
|
btrace cal calendar \
|
||||||
cat cawf cd cdprobe checkhier cpp \
|
cawf cd cdprobe checkhier cpp \
|
||||||
chmod chown chroot ci cksum cleantmp clear cmp co \
|
chmod chown chroot ci cksum cleantmp clear cmp co \
|
||||||
comm compress cp crc cron crontab cut \
|
comm compress cp crc cron crontab cut \
|
||||||
dd decomp16 DESCRIBE dev2name devsize df dhcpd \
|
dd decomp16 DESCRIBE dev2name devsize df dhcpd \
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
PROG= cat
|
|
||||||
BINDIR= /bin
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,137 +0,0 @@
|
||||||
/* cat - concatenates files Author: Andy Tanenbaum */
|
|
||||||
|
|
||||||
/* 30 March 1990 - Slightly modified for efficiency by Norbert Schlenker. */
|
|
||||||
/* 23 March 2002 - Proper error messages by Kees J. Bot. */
|
|
||||||
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <minix/minlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define CHUNK_SIZE (2048 * sizeof(char *))
|
|
||||||
|
|
||||||
static int unbuffered;
|
|
||||||
static char ibuf[CHUNK_SIZE];
|
|
||||||
static char obuf[CHUNK_SIZE];
|
|
||||||
static char *op = obuf;
|
|
||||||
|
|
||||||
static void copyout(const char *file, int fd);
|
|
||||||
static void output(const char *buf, size_t count);
|
|
||||||
static void report(const char *label);
|
|
||||||
static void fatal(const char *label);
|
|
||||||
|
|
||||||
static char STDIN[] = "standard input";
|
|
||||||
static char STDOUT[] = "standard output";
|
|
||||||
|
|
||||||
static int excode = 0;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i, fd;
|
|
||||||
|
|
||||||
i = 1;
|
|
||||||
while (i < argc && argv[i][0] == '-') {
|
|
||||||
char *opt = argv[i] + 1;
|
|
||||||
|
|
||||||
if (opt[0] == 0) break; /* - */
|
|
||||||
i++;
|
|
||||||
if (opt[0] == '-' && opt[1] == 0) break; /* -- */
|
|
||||||
|
|
||||||
while (*opt != 0) switch (*opt++) {
|
|
||||||
case 'u':
|
|
||||||
unbuffered = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std_err("Usage: cat [-u] [file ...]\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= argc) {
|
|
||||||
copyout(STDIN, STDIN_FILENO);
|
|
||||||
} else {
|
|
||||||
while (i < argc) {
|
|
||||||
char *file = argv[i++];
|
|
||||||
|
|
||||||
if (file[0] == '-' && file[1] == 0) {
|
|
||||||
copyout(STDIN, STDIN_FILENO);
|
|
||||||
} else {
|
|
||||||
fd = open(file, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
report(file);
|
|
||||||
} else {
|
|
||||||
copyout(file, fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output(obuf, (op - obuf));
|
|
||||||
return(excode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void copyout(const char *file, int fd)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
n = read(fd, ibuf, CHUNK_SIZE);
|
|
||||||
if (n < 0) fatal(file);
|
|
||||||
if (n == 0) return;
|
|
||||||
if (unbuffered || (op == obuf && n == CHUNK_SIZE)) {
|
|
||||||
output(ibuf, n);
|
|
||||||
} else {
|
|
||||||
int bytes_left;
|
|
||||||
|
|
||||||
bytes_left = &obuf[CHUNK_SIZE] - op;
|
|
||||||
if (n <= bytes_left) {
|
|
||||||
memcpy(op, ibuf, (size_t)n);
|
|
||||||
op += n;
|
|
||||||
} else {
|
|
||||||
memcpy(op, ibuf, (size_t)bytes_left);
|
|
||||||
output(obuf, CHUNK_SIZE);
|
|
||||||
n -= bytes_left;
|
|
||||||
memcpy(obuf, ibuf + bytes_left, (size_t)n);
|
|
||||||
op = obuf + n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void output(const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
ssize_t n;
|
|
||||||
|
|
||||||
while (count > 0) {
|
|
||||||
n = write(STDOUT_FILENO, buf, count);
|
|
||||||
if (n <= 0) {
|
|
||||||
if (n < 0) fatal(STDOUT);
|
|
||||||
std_err("cat: standard output: EOF\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
buf += n;
|
|
||||||
count -= n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void report(const char *label)
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
std_err("cat: ");
|
|
||||||
std_err(label);
|
|
||||||
std_err(": ");
|
|
||||||
std_err(strerror(e));
|
|
||||||
std_err("\n");
|
|
||||||
excode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fatal(const char *label)
|
|
||||||
{
|
|
||||||
report(label);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
MAN= ash.1 at.1 banner.1 basename.1 \
|
MAN= ash.1 at.1 banner.1 basename.1 \
|
||||||
bsfilt.1 cal.1 \
|
bsfilt.1 cal.1 \
|
||||||
calendar.1 cat.1 cawf.1 chgrp.1 \
|
calendar.1 cawf.1 chgrp.1 \
|
||||||
chmod.1 cksum.1 clear.1 cmp.1 comm.1 compress.1 \
|
chmod.1 cksum.1 clear.1 cmp.1 comm.1 compress.1 \
|
||||||
cp.1 crc.1 crontab.1 ctags.1 dd.1 dev2name.1 \
|
cp.1 crc.1 crontab.1 ctags.1 dd.1 dev2name.1 \
|
||||||
df.1 dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
|
df.1 dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
.TH CAT 1
|
|
||||||
.SH NAME
|
|
||||||
cat \- concatenate files and write them to stdout
|
|
||||||
.SH SYNOPSIS
|
|
||||||
\fBcat\fR [\fB\-u\fR]\fR [\fIfile\fR] ...\fR
|
|
||||||
.br
|
|
||||||
.de FL
|
|
||||||
.TP
|
|
||||||
\\fB\\$1\\fR
|
|
||||||
\\$2
|
|
||||||
..
|
|
||||||
.de EX
|
|
||||||
.TP 20
|
|
||||||
\\fB\\$1\\fR
|
|
||||||
# \\$2
|
|
||||||
..
|
|
||||||
.SH OPTIONS
|
|
||||||
.FL "\-u" "Unbuffered output"
|
|
||||||
.SH EXAMPLES
|
|
||||||
.EX "cat file" "Display file on the terminal"
|
|
||||||
.EX "cat file1 file2 | lp" "Concatenate 2 files and print result"
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
.I Cat
|
|
||||||
concatenates its input files and copies the result to \fIstdout\fR.
|
|
||||||
If no input file is named, or \- is encountered as a file name, standard
|
|
||||||
input is used.
|
|
||||||
Output is buffered in 512 byte blocks unless the
|
|
||||||
.B \-u
|
|
||||||
flag is given.
|
|
||||||
If you just want to copy a file, \fIcp\fR should be used since it is faster.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR cp (1).
|
|
|
@ -27,6 +27,7 @@
|
||||||
2011/08/29 14:48:46,bin/rm
|
2011/08/29 14:48:46,bin/rm
|
||||||
2011/08/29 14:49:38,bin/rmdir
|
2011/08/29 14:49:38,bin/rmdir
|
||||||
2012/01/16 18:47:57,bin/ed
|
2012/01/16 18:47:57,bin/ed
|
||||||
|
2012/01/16 18:47:57,bin/cat
|
||||||
2011/06/09 21:23:29,sbin/fsck
|
2011/06/09 21:23:29,sbin/fsck
|
||||||
2009/04/11 12:10:02,usr.bin/chpass
|
2009/04/11 12:10:02,usr.bin/chpass
|
||||||
2010/05/14 17:14:28,usr.bin/m4
|
2010/05/14 17:14:28,usr.bin/m4
|
||||||
|
|
Loading…
Reference in a new issue