summaryrefslogtreecommitdiffstats
path: root/text-utils
diff options
context:
space:
mode:
authorSami Kerola2015-02-15 18:12:03 +0100
committerKarel Zak2015-03-05 10:31:18 +0100
commit16d3d9a04d5d2a7f4f10c3658cccc5aa0c7cd0af (patch)
tree6615ad4f2450ad0550202d2a20daf89f215aa747 /text-utils
parenttailf: count last lines correctly at initial print out (diff)
downloadkernel-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.c24
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);