xref: /third_party/toybox/toys/posix/head.c (revision 0f66f451)
10f66f451Sopenharmony_ci/* head.c - copy first lines from input to stdout.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2006 Timothy Elliott <tle@holymonkey.com>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/head.html
60f66f451Sopenharmony_ci *
70f66f451Sopenharmony_ci * Deviations from posix: -c
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciUSE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
100f66f451Sopenharmony_ci
110f66f451Sopenharmony_ciconfig HEAD
120f66f451Sopenharmony_ci  bool "head"
130f66f451Sopenharmony_ci  default y
140f66f451Sopenharmony_ci  help
150f66f451Sopenharmony_ci    usage: head [-n NUM] [FILE...]
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    Copy first lines from files to stdout. If no files listed, copy from
180f66f451Sopenharmony_ci    stdin. Filename "-" is a synonym for stdin.
190f66f451Sopenharmony_ci
200f66f451Sopenharmony_ci    -n	Number of lines to copy
210f66f451Sopenharmony_ci    -c	Number of bytes to copy
220f66f451Sopenharmony_ci    -q	Never print headers
230f66f451Sopenharmony_ci    -v	Always print headers
240f66f451Sopenharmony_ci*/
250f66f451Sopenharmony_ci
260f66f451Sopenharmony_ci#define FOR_head
270f66f451Sopenharmony_ci#include "toys.h"
280f66f451Sopenharmony_ci
290f66f451Sopenharmony_ciGLOBALS(
300f66f451Sopenharmony_ci  long c, n;
310f66f451Sopenharmony_ci
320f66f451Sopenharmony_ci  int file_no;
330f66f451Sopenharmony_ci)
340f66f451Sopenharmony_ci
350f66f451Sopenharmony_cistatic void do_head(int fd, char *name)
360f66f451Sopenharmony_ci{
370f66f451Sopenharmony_ci  long i, len, lines=TT.n, bytes=TT.c;
380f66f451Sopenharmony_ci
390f66f451Sopenharmony_ci  if ((toys.optc > 1 && !FLAG(q)) || FLAG(v)) {
400f66f451Sopenharmony_ci    // Print an extra newline for all but the first file
410f66f451Sopenharmony_ci    if (TT.file_no) xprintf("\n");
420f66f451Sopenharmony_ci    xprintf("==> %s <==\n", name);
430f66f451Sopenharmony_ci  }
440f66f451Sopenharmony_ci
450f66f451Sopenharmony_ci  while (FLAG(c) ? bytes : lines) {
460f66f451Sopenharmony_ci    len = read(fd, toybuf, sizeof(toybuf));
470f66f451Sopenharmony_ci    if (len<0) perror_msg_raw(name);
480f66f451Sopenharmony_ci    if (len<1) break;
490f66f451Sopenharmony_ci
500f66f451Sopenharmony_ci    if (bytes) {
510f66f451Sopenharmony_ci      i = bytes >= len ? len : bytes;
520f66f451Sopenharmony_ci      bytes -= i;
530f66f451Sopenharmony_ci    } else for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break;
540f66f451Sopenharmony_ci
550f66f451Sopenharmony_ci    xwrite(1, toybuf, i);
560f66f451Sopenharmony_ci  }
570f66f451Sopenharmony_ci
580f66f451Sopenharmony_ci  TT.file_no++;
590f66f451Sopenharmony_ci}
600f66f451Sopenharmony_ci
610f66f451Sopenharmony_civoid head_main(void)
620f66f451Sopenharmony_ci{
630f66f451Sopenharmony_ci  char *arg = *toys.optargs;
640f66f451Sopenharmony_ci
650f66f451Sopenharmony_ci  // handle old "-42" style arguments
660f66f451Sopenharmony_ci  if (arg && *arg == '-' && arg[1]) {
670f66f451Sopenharmony_ci    TT.n = atolx(arg+1);
680f66f451Sopenharmony_ci    toys.optc--;
690f66f451Sopenharmony_ci  } else arg = 0;
700f66f451Sopenharmony_ci  loopfiles(toys.optargs+!!arg, do_head);
710f66f451Sopenharmony_ci}
72