added read to 9base

This commit is contained in:
Anselm R. Garbe
2006-01-29 22:17:04 +02:00
parent 2b4ad5ac67
commit 08aaa60fa8
4 changed files with 206 additions and 1 deletions

View File

@@ -4,7 +4,7 @@
include config.mk
SUBDIRS = lib9 yacc awk basename bc dc cat cleanname date echo grep mk \
rc sed seq sleep sort tee test touch tr uniq
rc read sed seq sleep sort tee test touch tr uniq
all:
@echo 9base build options:

6
read/Makefile Normal file
View File

@@ -0,0 +1,6 @@
# read - read unix port from plan9
# Depends on ../lib9
TARG = read
include ../std.mk

108
read/read.1 Normal file
View File

@@ -0,0 +1,108 @@
.TH CAT 1
.SH NAME
cat, read, nobs \- catenate files
.SH SYNOPSIS
.B cat
[
.I file ...
]
.br
.B read
[
.B -m
] [
.B -n
.I nline
] [
.I file ...
]
.br
.B nobs
[
.I file ...
]
.SH DESCRIPTION
.I Cat
reads each
.I file
in sequence and writes it on the standard output.
Thus
.IP
.L
cat file
.LP
prints a file and
.IP
.L
cat file1 file2 >file3
.LP
concatenates the first two files and places the result
on the third.
.PP
If no
.I file
is given,
.I cat
reads from the standard input.
Output is buffered in blocks matching the input.
.PP
.I Read
copies to standard output exactly one line from the named
.IR file ,
default standard input.
It is useful in interactive
.IR rc (1)
scripts.
.PP
The
.B -m
flag causes it to continue reading and writing multiple lines until end of file;
.B -n
causes it to read no more than
.I nline
lines.
.PP
.I Read
always executes a single
.B write
for each line of input, which can be helpful when
preparing input to programs that expect line-at-a-time data.
It never reads any more data from the input than it prints to the output.
.PP
.I Nobs
copies the named files to
standard output except that it removes all backspace
characters and the characters that precede them.
It is useful to use as
.B $PAGER
with the Unix version of
.IR man (1)
when run inside a
.I win
(see
.IR acme (1))
window.
.SH SOURCE
.B \*9/src/cmd/cat.c
.br
.B \*9/src/cmd/read.c
.br
.B \*9/bin/nobs
.SH SEE ALSO
.IR cp (1)
.SH DIAGNOSTICS
.I Read
exits with status
.B eof
on end of file or, in the
.B -n
case, if it doesn't read
.I nlines
lines.
.SH BUGS
Beware of
.L "cat a b >a"
and
.LR "cat a b >b" ,
which
destroy input files before reading them.

91
read/read.c Normal file
View File

@@ -0,0 +1,91 @@
#include <u.h>
#include <libc.h>
int multi;
int nlines;
char *status = nil;
int
line(int fd, char *file)
{
char c;
int m, n, nalloc;
char *buf;
nalloc = 0;
buf = nil;
for(m=0; ; ){
n = read(fd, &c, 1);
if(n < 0){
fprint(2, "read: error reading %s: %r\n", file);
exits("read error");
}
if(n == 0){
if(m == 0)
status = "eof";
break;
}
if(m == nalloc){
nalloc += 1024;
buf = realloc(buf, nalloc);
if(buf == nil){
fprint(2, "read: malloc error: %r\n");
exits("malloc");
}
}
buf[m++] = c;
if(c == '\n')
break;
}
if(m > 0)
write(1, buf, m);
free(buf);
return m;
}
void
lines(int fd, char *file)
{
do{
if(line(fd, file) == 0)
break;
}while(multi || --nlines>0);
}
void
main(int argc, char *argv[])
{
int i, fd;
char *s;
ARGBEGIN{
case 'm':
multi = 1;
break;
case 'n':
s = ARGF();
if(s){
nlines = atoi(s);
break;
}
/* fall through */
default:
fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
exits("usage");
}ARGEND
if(argc == 0)
lines(0, "<stdin>");
else
for(i=0; i<argc; i++){
fd = open(argv[i], OREAD);
if(fd < 0){
fprint(2, "read: can't open %s: %r\n", argv[i]);
exits("open");
}
lines(fd, argv[i]);
close(fd);
}
exits(status);
}