13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier
49a747e4fSDavid du Colombier int multi;
59a747e4fSDavid du Colombier int nlines;
6*5d459b5aSDavid du Colombier char *status = nil;
79a747e4fSDavid du Colombier
89a747e4fSDavid du Colombier int
line(int fd,char * file)99a747e4fSDavid du Colombier line(int fd, char *file)
109a747e4fSDavid du Colombier {
119a747e4fSDavid du Colombier char c;
129a747e4fSDavid du Colombier int m, n, nalloc;
139a747e4fSDavid du Colombier char *buf;
149a747e4fSDavid du Colombier
159a747e4fSDavid du Colombier nalloc = 0;
169a747e4fSDavid du Colombier buf = nil;
179a747e4fSDavid du Colombier for(m=0; ; ){
189a747e4fSDavid du Colombier n = read(fd, &c, 1);
199a747e4fSDavid du Colombier if(n < 0){
209a747e4fSDavid du Colombier fprint(2, "read: error reading %s: %r\n", file);
21*5d459b5aSDavid du Colombier exits("read error");
229a747e4fSDavid du Colombier }
23*5d459b5aSDavid du Colombier if(n == 0){
24*5d459b5aSDavid du Colombier if(m == 0)
25*5d459b5aSDavid du Colombier status = "eof";
269a747e4fSDavid du Colombier break;
27*5d459b5aSDavid du Colombier }
289a747e4fSDavid du Colombier if(m == nalloc){
299a747e4fSDavid du Colombier nalloc += 1024;
309a747e4fSDavid du Colombier buf = realloc(buf, nalloc);
319a747e4fSDavid du Colombier if(buf == nil){
329a747e4fSDavid du Colombier fprint(2, "read: malloc error: %r\n");
339a747e4fSDavid du Colombier exits("malloc");
349a747e4fSDavid du Colombier }
359a747e4fSDavid du Colombier }
369a747e4fSDavid du Colombier buf[m++] = c;
379a747e4fSDavid du Colombier if(c == '\n')
389a747e4fSDavid du Colombier break;
399a747e4fSDavid du Colombier }
409a747e4fSDavid du Colombier if(m > 0)
419a747e4fSDavid du Colombier write(1, buf, m);
429a747e4fSDavid du Colombier free(buf);
439a747e4fSDavid du Colombier return m;
449a747e4fSDavid du Colombier }
459a747e4fSDavid du Colombier
469a747e4fSDavid du Colombier void
lines(int fd,char * file)479a747e4fSDavid du Colombier lines(int fd, char *file)
489a747e4fSDavid du Colombier {
499a747e4fSDavid du Colombier do{
509a747e4fSDavid du Colombier if(line(fd, file) == 0)
519a747e4fSDavid du Colombier break;
529a747e4fSDavid du Colombier }while(multi || --nlines>0);
539a747e4fSDavid du Colombier }
543e12c5d1SDavid du Colombier
553e12c5d1SDavid du Colombier void
main(int argc,char * argv[])563e12c5d1SDavid du Colombier main(int argc, char *argv[])
573e12c5d1SDavid du Colombier {
589a747e4fSDavid du Colombier int i, fd;
599a747e4fSDavid du Colombier char *s;
603e12c5d1SDavid du Colombier
619a747e4fSDavid du Colombier ARGBEGIN{
629a747e4fSDavid du Colombier case 'm':
639a747e4fSDavid du Colombier multi = 1;
649a747e4fSDavid du Colombier break;
659a747e4fSDavid du Colombier case 'n':
669a747e4fSDavid du Colombier s = ARGF();
679a747e4fSDavid du Colombier if(s){
689a747e4fSDavid du Colombier nlines = atoi(s);
693e12c5d1SDavid du Colombier break;
703e12c5d1SDavid du Colombier }
719a747e4fSDavid du Colombier /* fall through */
729a747e4fSDavid du Colombier default:
739a747e4fSDavid du Colombier fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
749a747e4fSDavid du Colombier exits("usage");
759a747e4fSDavid du Colombier }ARGEND
769a747e4fSDavid du Colombier
779a747e4fSDavid du Colombier if(argc == 0)
789a747e4fSDavid du Colombier lines(0, "<stdin>");
799a747e4fSDavid du Colombier else
809a747e4fSDavid du Colombier for(i=0; i<argc; i++){
819a747e4fSDavid du Colombier fd = open(argv[i], OREAD);
829a747e4fSDavid du Colombier if(fd < 0){
839a747e4fSDavid du Colombier fprint(2, "read: can't open %s: %r\n", argv[i]);
849a747e4fSDavid du Colombier exits("open");
859a747e4fSDavid du Colombier }
869a747e4fSDavid du Colombier lines(fd, argv[i]);
879a747e4fSDavid du Colombier close(fd);
889a747e4fSDavid du Colombier }
899a747e4fSDavid du Colombier
90*5d459b5aSDavid du Colombier exits(status);
913e12c5d1SDavid du Colombier }
92