Home | History | Annotate | Download | only in posix
      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