diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-02 17:46:21 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-02 17:46:21 +0200 |
commit | bdb228e14ac13eeb34601f7f360692cfd467e945 (patch) | |
tree | be993be52bbe0e65719c44a705cc819d225c8f3d /sys/src/cmd/read.c | |
parent | 44f97f0cb1f3fd07c348ae634cb33c3aa74e64db (diff) |
read: add -c flag to copy bytes instead of lines
Diffstat (limited to 'sys/src/cmd/read.c')
-rw-r--r-- | sys/src/cmd/read.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/sys/src/cmd/read.c b/sys/src/cmd/read.c index 56d80136d..6377fdc1d 100644 --- a/sys/src/cmd/read.c +++ b/sys/src/cmd/read.c @@ -3,6 +3,7 @@ int multi; int nlines; +vlong nchars; char *status = nil; int @@ -53,29 +54,60 @@ lines(int fd, char *file) } void +chars(int fd, char *file) +{ + char buf[8*1024]; + vlong m; + int n; + + for(m = 0; m < nchars; m += n){ + n = sizeof(buf); + if(n > (nchars - m)) + n = nchars - m; + if((n = read(fd, buf, n)) < 0){ + fprint(2, "read: error reading %s: %r\n", file); + exits("read error"); + } + if(n == 0){ + if(m == 0) + status = "eof"; + break; + } + write(1, buf, n); + } +} + +void +usage(void) +{ + fprint(2, "usage: read [-m] [-n nlines] [-c nbytes] [files...]\n"); + exits("usage"); +} + +void main(int argc, char *argv[]) { + void (*proc)(int, char*); int i, fd; - char *s; + proc = lines; ARGBEGIN{ + case 'c': + nchars = atoll(EARGF(usage())); + proc = chars; + break; + case 'n': + nlines = atoi(EARGF(usage())); + break; 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"); + usage(); }ARGEND if(argc == 0) - lines(0, "<stdin>"); + (*proc)(0, "<stdin>"); else for(i=0; i<argc; i++){ fd = open(argv[i], OREAD); @@ -83,7 +115,7 @@ main(int argc, char *argv[]) fprint(2, "read: can't open %s: %r\n", argv[i]); exits("open"); } - lines(fd, argv[i]); + (*proc)(fd, argv[i]); close(fd); } |