1 /* head.c - copy first lines from input to stdout. 2 * 3 * Copyright 2006 Timothy Elliott <tle (at) holymonkey.com> 4 * 5 * See http://opengroup.org/onlinepubs/9699919799/utilities/head.html 6 * 7 * Deviations from posix: -c 8 9 USE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN)) 10 11 config HEAD 12 bool "head" 13 default y 14 help 15 usage: head [-n number] [file...] 16 17 Copy first lines from files to stdout. If no files listed, copy from 18 stdin. Filename "-" is a synonym for stdin. 19 20 -n Number of lines to copy 21 -c Number of bytes to copy 22 -q Never print headers 23 -v Always print headers 24 */ 25 26 #define FOR_head 27 #include "toys.h" 28 29 GLOBALS( 30 long c, n; 31 32 int file_no; 33 ) 34 35 static void do_head(int fd, char *name) 36 { 37 int i, len, lines=TT.n, bytes=TT.c; 38 39 if ((toys.optc > 1 && !(toys.optflags & FLAG_q)) || toys.optflags & FLAG_v) { 40 // Print an extra newline for all but the first file 41 if (TT.file_no) xprintf("\n"); 42 xprintf("==> %s <==\n", name); 43 xflush(); 44 } 45 46 while ((toys.optflags&FLAG_c) ? bytes : lines) { 47 len = read(fd, toybuf, sizeof(toybuf)); 48 if (len<0) perror_msg_raw(name); 49 if (len<1) break; 50 51 if (bytes) { 52 i = bytes >= len ? len : bytes; 53 bytes -= i; 54 } else for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break; 55 56 xwrite(1, toybuf, i); 57 } 58 59 TT.file_no++; 60 } 61 62 void head_main(void) 63 { 64 char *arg = *toys.optargs; 65 66 // handle old "-42" style arguments 67 if (arg && *arg == '-' && arg[1]) { 68 TT.n = atolx(arg+1); 69 toys.optc--; 70 } else arg = 0; 71 loopfiles(toys.optargs+!!arg, do_head); 72 } 73