diff options
author | Sami Kerola | 2015-02-15 18:12:03 +0100 |
---|---|---|
committer | Karel Zak | 2015-03-05 10:31:18 +0100 |
commit | 16d3d9a04d5d2a7f4f10c3658cccc5aa0c7cd0af (patch) | |
tree | 6615ad4f2450ad0550202d2a20daf89f215aa747 /text-utils | |
parent | tailf: count last lines correctly at initial print out (diff) | |
download | kernel-qcow2-util-linux-16d3d9a04d5d2a7f4f10c3658cccc5aa0c7cd0af.tar.gz kernel-qcow2-util-linux-16d3d9a04d5d2a7f4f10c3658cccc5aa0c7cd0af.tar.xz kernel-qcow2-util-linux-16d3d9a04d5d2a7f4f10c3658cccc5aa0c7cd0af.zip |
tailf: do not allow minus signed last lines argument
Before mmap() the command behavior was not completely correct, as
demonstrated below, and after the mmap() it tried to print some eighteen
quintillion lines.
$ tailf -n-1 x
tailf: cannot allocate 18446744073709543424 bytes: Cannot allocate memory
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'text-utils')
-rw-r--r-- | text-utils/tailf.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/text-utils/tailf.c b/text-utils/tailf.c index 179dfc3d6..a89a3b531 100644 --- a/text-utils/tailf.c +++ b/text-utils/tailf.c @@ -208,16 +208,16 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) } /* parses -N option */ -static long old_style_option(int *argc, char **argv) +static long old_style_option(int *argc, char **argv, unsigned long *lines) { - int i = 1, nargs = *argc; - long lines = -1; + int i = 1, nargs = *argc, ret = 0; while(i < nargs) { if (argv[i][0] == '-' && isdigit(argv[i][1])) { - lines = strtol_or_err(argv[i] + 1, + *lines = strtoul_or_err(argv[i] + 1, _("failed to parse number of lines")); nargs--; + ret = 1; if (nargs - i) memmove(argv + i, argv + i + 1, sizeof(char *) * (nargs - i)); @@ -225,13 +225,13 @@ static long old_style_option(int *argc, char **argv) i++; } *argc = nargs; - return lines; + return ret; } int main(int argc, char **argv) { const char *filename; - long lines; + unsigned long lines; int ch; struct stat st; @@ -247,16 +247,18 @@ int main(int argc, char **argv) textdomain(PACKAGE); atexit(close_stdout); - lines = old_style_option(&argc, argv); - if (lines < 0) + if (!old_style_option(&argc, argv, &lines)) lines = DEFAULT_LINES; while ((ch = getopt_long(argc, argv, "n:N:Vh", longopts, NULL)) != -1) - switch((char)ch) { + switch ((char)ch) { case 'n': case 'N': - lines = strtol_or_err(optarg, - _("failed to parse number of lines")); + if (optarg[0] == '-') + errx(EXIT_FAILURE, "%s: %s", + _("failed to parse number of lines"), optarg); + lines = + strtoul_or_err(optarg, _("failed to parse number of lines")); break; case 'V': printf(UTIL_LINUX_VERSION); |