toybox/toys/posix/head.c
<<
>>
Prefs
   1/* head.c - copy first lines from input to stdout.
   2 *
   3 * Copyright 2006 Timothy Elliott <tle@holymonkey.com>
   4 *
   5 * See http://opengroup.org/onlinepubs/9699919799/utilities/head.html
   6 *
   7 * Deviations from posix: -c
   8
   9USE_HEAD(NEWTOY(head, "?n#<0=10c#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
  10
  11config 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
  29GLOBALS(
  30  long bytes;
  31  long lines;
  32  int file_no;
  33)
  34
  35static void do_head(int fd, char *name)
  36{
  37  int i, len, lines=TT.lines, bytes=TT.bytes;
  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
  62void head_main(void)
  63{
  64  char *arg = *toys.optargs;
  65
  66  // handle old "-42" style arguments
  67  if (arg && *arg == '-' && arg[1]) {
  68    TT.lines = atolx(arg+1);
  69    toys.optc--;
  70  } else arg = 0;
  71  loopfiles(toys.optargs+!!arg, do_head);
  72}
  73