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 }