#include #include #include enum{MINREAD = 8192}; char *buf; int i, c, sz = MINREAD; void slurp(char *f){ int fd, n; fd = open(f, OREAD); if(fd < 0) sysfatal("open: %r"); for(;;){ if(sz - i <= MINREAD){ buf = realloc(buf, sz <<= 1); if(buf == nil) sysfatal("realloc: %r"); } n = read(fd, buf + i, sz - i); if(n == 0) break; if(n < 0) sysfatal("read: %r"); while(n--) if(buf[i++] == '\n') c++; } close(fd); if(i && buf[i - 1] != '\n'){ if(i == sz){ buf = realloc(buf, ++sz); if(buf == nil) sysfatal("realloc: %r"); } fprint(2, "adding newline at end of %s\n", f); buf[i++] = '\n'; c++; } } void main(int argc, char *argv[]){ Biobuf *out; int j, *start, *len; if(argc == 1) slurp("/fd/0"); else while(--argc) slurp(argv[argc]); if(c == 0) exits(nil); start = calloc(c, sizeof(int)); len = calloc(c, sizeof(int)); if(start == nil || len == nil) sysfatal("calloc: %r"); len[j = 0] = --i; while(i--){ if(buf[i] == '\n'){ len[j] -= i; start[j] = i + 1; len[++j] = i; } } len[j]++; assert(j + 1 == c); out = Bfdopen(1, OWRITE); if(out == nil) sysfatal("Bfdopen: %r"); srand(truerand()); while(c){ j = nrand(c--); Bwrite(out, buf + start[j], len[j]); start[j] = start[c]; len[j] = len[c]; } exits(nil); }