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(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
  10
  11config HEAD
  12  bool "head"
  13  default y
  14  help
  15    usage: head [-n NUM] [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 c, n;
  31
  32  int file_no;
  33)
  34
  35static void do_head(int fd, char *name)
  36{
  37  long i, len, lines=TT.n, bytes=TT.c;
  38
  39  if ((toys.optc > 1 && !FLAG(q)) || 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  }
  44
  45  while (FLAG(c) ? bytes : lines) {
  46    len = read(fd, toybuf, sizeof(toybuf));
  47    if (len<0) perror_msg_raw(name);
  48    if (len<1) break;
  49
  50    if (bytes) {
  51      i = bytes >= len ? len : bytes;
  52      bytes -= i;
  53    } else for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break;
  54
  55    xwrite(1, toybuf, i);
  56  }
  57
  58  TT.file_no++;
  59}
  60
  61void head_main(void)
  62{
  63  char *arg = *toys.optargs;
  64
  65  // handle old "-42" style arguments
  66  if (arg && *arg == '-' && arg[1]) {
  67    TT.n = atolx(arg+1);
  68    toys.optc--;
  69  } else arg = 0;
  70  loopfiles(toys.optargs+!!arg, do_head);
  71}
  72