xref: /plan9/sys/src/cmd/read.c (revision 5d459b5a09e427ae1acd4e6afcf028853c73946e)
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