head.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. USE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
  9. config HEAD
  10. bool "head"
  11. default y
  12. help
  13. usage: head [-n NUM] [FILE...]
  14. Copy first lines from files to stdout. If no files listed, copy from
  15. stdin. Filename "-" is a synonym for stdin.
  16. -n Number of lines to copy
  17. -c Number of bytes to copy
  18. -q Never print headers
  19. -v Always print headers
  20. */
  21. #define FOR_head
  22. #include "toys.h"
  23. GLOBALS(
  24. long c, n;
  25. int file_no;
  26. )
  27. static void do_head(int fd, char *name)
  28. {
  29. long i, len, lines=TT.n, bytes=TT.c;
  30. if ((toys.optc > 1 && !FLAG(q)) || FLAG(v)) {
  31. // Print an extra newline for all but the first file
  32. if (TT.file_no) xprintf("\n");
  33. xprintf("==> %s <==\n", name);
  34. }
  35. while (FLAG(c) ? bytes : lines) {
  36. len = read(fd, toybuf, sizeof(toybuf));
  37. if (len<0) perror_msg_raw(name);
  38. if (len<1) break;
  39. if (bytes) {
  40. i = bytes >= len ? len : bytes;
  41. bytes -= i;
  42. } else for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break;
  43. xwrite(1, toybuf, i);
  44. }
  45. TT.file_no++;
  46. }
  47. void head_main(void)
  48. {
  49. char *arg = *toys.optargs;
  50. // handle old "-42" style arguments
  51. if (arg && *arg == '-' && arg[1]) {
  52. TT.n = atolx(arg+1);
  53. toys.optc--;
  54. } else arg = 0;
  55. loopfiles(toys.optargs+!!arg, do_head);
  56. }