Blame


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