diff options
author | Ilya Kuzmich <ilya.kuzmich@gmail.com> | 2017-05-28 18:29:19 +0300 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2017-06-27 14:55:29 -0500 |
commit | 77997b8e774318631b373a443dc073d3b38b5d84 (patch) | |
tree | 1c7dc8c8a7ce757bfe5a447221714239c5a5ea27 | |
parent | f30035e88bad1748e8e5546ef43409862db1d91e (diff) | |
download | toybox-77997b8e774318631b373a443dc073d3b38b5d84.tar.gz |
teach head -c
Not POSIX, but implemented in coreutils, busybox and freebsd.
-rwxr-xr-x | tests/head.test | 4 | ||||
-rw-r--r-- | toys/posix/head.c | 17 |
2 files changed, 16 insertions, 5 deletions
diff --git a/tests/head.test b/tests/head.test index 6ed027c4..4e4c01bd 100755 --- a/tests/head.test +++ b/tests/head.test @@ -27,3 +27,7 @@ testing "-q, multiple files" "head -q -n 2 input file1" "one\ntwo\nfoo\nbar\n" \ "one\ntwo\nthree\n" "" rm file1 +testing "-c 3" "head -c 3" "one" "" "one\ntwo" +testing "-c bigger than input" "head -c 3" "a" "" "a" +testing "-c 3 -n 1" "head -c 3 -n 1" "one\n" "" "one\ntwo" +testing "-n 1 -c 3" "head -n 1 -c 3" "one" "" "one\ntwo" diff --git a/toys/posix/head.c b/toys/posix/head.c index 63eb85b0..6153b42f 100644 --- a/toys/posix/head.c +++ b/toys/posix/head.c @@ -3,8 +3,9 @@ * Copyright 2006 Timothy Elliott <tle@holymonkey.com> * * See http://opengroup.org/onlinepubs/9699919799/utilities/head.html + * See http://man7.org/linux/man-pages/man1/head.1.html -USE_HEAD(NEWTOY(head, "?n#<0=10qv", TOYFLAG_USR|TOYFLAG_BIN)) +USE_HEAD(NEWTOY(head, "?n#<0=10c#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN)) config HEAD bool "head" @@ -16,6 +17,7 @@ config HEAD stdin. Filename "-" is a synonym for stdin. -n Number of lines to copy + -c Number of bytes to copy -q Never print headers -v Always print headers */ @@ -24,13 +26,14 @@ config HEAD #include "toys.h" GLOBALS( + long bytes; long lines; int file_no; ) static void do_head(int fd, char *name) { - int i, len, lines=TT.lines, size=sizeof(toybuf); + int i, len, lines=TT.lines, bytes=TT.bytes; if ((toys.optc > 1 && !(toys.optflags & FLAG_q)) || toys.optflags & FLAG_v) { // Print an extra newline for all but the first file @@ -39,12 +42,16 @@ static void do_head(int fd, char *name) xflush(); } - while (lines) { - len = read(fd, toybuf, size); + while (toys.optflags & FLAG_c ? bytes : lines) { + len = read(fd, toybuf, sizeof(toybuf)); if (len<0) perror_msg_raw(name); if (len<1) break; - for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break; + if (bytes) { + i = bytes >= len ? len : bytes; + bytes -= i; + } else + for(i=0; i<len;) if (toybuf[i++] == '\n' && !--lines) break; xwrite(1, toybuf, i); } |