read.c - 9base - revived minimalist port of Plan 9 userland to Unix
(HTM) git clone git://git.suckless.org/9base
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
read.c (1771B)
---
1 #include <u.h>
2 #include <libc.h>
3
4 int multi;
5 int nlines;
6 vlong nchars;
7 char *status = nil;
8
9 int
10 line(int fd, char *file)
11 {
12 char c;
13 int m, n, nalloc;
14 char *buf;
15
16 nalloc = 0;
17 buf = nil;
18 for(m=0; ; ){
19 n = read(fd, &c, 1);
20 if(n < 0){
21 fprint(2, "read: error reading %s: %r\n", file);
22 exits("read error");
23 }
24 if(n == 0){
25 if(m == 0)
26 status = "eof";
27 break;
28 }
29 if(m == nalloc){
30 nalloc += 1024;
31 buf = realloc(buf, nalloc);
32 if(buf == nil){
33 fprint(2, "read: malloc error: %r\n");
34 exits("malloc");
35 }
36 }
37 buf[m++] = c;
38 if(c == '\n')
39 break;
40 }
41 if(m > 0)
42 write(1, buf, m);
43 free(buf);
44 return m;
45 }
46
47 void
48 lines(int fd, char *file)
49 {
50 do{
51 if(line(fd, file) == 0)
52 break;
53 }while(multi || --nlines>0);
54 }
55
56 void
57 chars(int fd, char *file)
58 {
59 char buf[8*1024];
60 vlong m;
61 int n;
62
63 for(m = 0; m < nchars; m += n){
64 n = sizeof(buf);
65 if(n > (nchars - m))
66 n = nchars - m;
67 if((n = read(fd, buf, n)) < 0){
68 fprint(2, "read: error reading %s: %r\n", file);
69 exits("read error");
70 }
71 if(n == 0){
72 if(m == 0)
73 status = "eof";
74 break;
75 }
76 write(1, buf, n);
77 }
78 }
79
80 void
81 usage(void)
82 {
83 fprint(2, "usage: read [-m] [-n nlines] [-c nbytes] [files...]\n");
84 exits("usage");
85 }
86
87 void
88 main(int argc, char *argv[])
89 {
90 void (*proc)(int, char*);
91 int i, fd;
92
93 proc = lines;
94 ARGBEGIN{
95 case 'c':
96 nchars = atoll(EARGF(usage()));
97 proc = chars;
98 break;
99 case 'n':
100 nlines = atoi(EARGF(usage()));
101 break;
102 case 'm':
103 multi = 1;
104 break;
105 default:
106 usage();
107 }ARGEND
108
109 if(argc == 0)
110 (*proc)(0, "<stdin>");
111 else
112 for(i=0; i<argc; i++){
113 fd = open(argv[i], OREAD);
114 if(fd < 0){
115 fprint(2, "read: can't open %s: %r\n", argv[i]);
116 exits("open");
117 }
118 (*proc)(fd, argv[i]);
119 close(fd);
120 }
121
122 exits(status);
123 }