Blob


1 #include <u.h>
2 #include <libc.h>
4 int multi;
5 int nlines;
6 char *status = nil;
8 int
9 line(int fd, char *file)
10 {
11 char c;
12 int m, n, nalloc;
13 char *buf;
15 nalloc = 0;
16 buf = nil;
17 for(m=0; ; ){
18 n = read(fd, &c, 1);
19 if(n < 0){
20 fprint(2, "read: error reading %s: %r\n", file);
21 exits("read error");
22 }
23 if(n == 0){
24 if(m == 0)
25 status = "eof";
26 break;
27 }
28 if(m == nalloc){
29 nalloc += 1024;
30 buf = realloc(buf, nalloc);
31 if(buf == nil){
32 fprint(2, "read: malloc error: %r\n");
33 exits("malloc");
34 }
35 }
36 buf[m++] = c;
37 if(c == '\n')
38 break;
39 }
40 if(m > 0)
41 write(1, buf, m);
42 free(buf);
43 return m;
44 }
46 void
47 lines(int fd, char *file)
48 {
49 do{
50 if(line(fd, file) == 0)
51 break;
52 }while(multi || --nlines>0);
53 }
55 void
56 main(int argc, char *argv[])
57 {
58 int i, fd;
59 char *s;
61 ARGBEGIN{
62 case 'm':
63 multi = 1;
64 break;
65 case 'n':
66 s = ARGF();
67 if(s){
68 nlines = atoi(s);
69 break;
70 }
71 /* fall through */
72 default:
73 fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
74 exits("usage");
75 }ARGEND
77 if(argc == 0)
78 lines(0, "<stdin>");
79 else
80 for(i=0; i<argc; i++){
81 fd = open(argv[i], OREAD);
82 if(fd < 0){
83 fprint(2, "read: can't open %s: %r\n", argv[i]);
84 exits("open");
85 }
86 lines(fd, argv[i]);
87 close(fd);
88 }
90 exits(status);
91 }