diff options
author | rsc <devnull@localhost> | 2005-01-04 22:30:59 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-01-04 22:30:59 +0000 |
commit | b2ad2ef1387571c7b917a7fd63e8670582ae8b7f (patch) | |
tree | a46fed64d497f15e824a1c394952a583c98c607b /src/cmd/read.c | |
parent | 48bfee4e5b72db021da3538c97ef68ce2308f12b (diff) | |
download | plan9port-b2ad2ef1387571c7b917a7fd63e8670582ae8b7f.tar.gz plan9port-b2ad2ef1387571c7b917a7fd63e8670582ae8b7f.tar.bz2 plan9port-b2ad2ef1387571c7b917a7fd63e8670582ae8b7f.zip |
in with the new
Diffstat (limited to 'src/cmd/read.c')
-rw-r--r-- | src/cmd/read.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/cmd/read.c b/src/cmd/read.c new file mode 100644 index 00000000..56d80136 --- /dev/null +++ b/src/cmd/read.c @@ -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); +} |