xref: /third_party/toybox/toys/posix/head.c (revision 0f66f451)
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