From 2e5ac464a5683c5bf11439ccad74c9f279051820 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Sun, 2 Aug 2020 16:40:18 -0700 Subject: [PATCH] 13037 grep could support -L Reviewed by: Andy Fiddaman Reviewed by: Toomas Soome Approved by: Gordon Ross --- usr/src/cmd/grep/grep.c | 41 ++++++++++++++++--- usr/src/man/man1/grep.1 | 31 +++++++++++--- usr/src/pkg/manifests/system-test-utiltest.mf | 22 ++++++++++ .../util-tests/tests/grep_xpg4/files/Makefile | 22 ++++++++++ .../tests/grep_xpg4/files/gout.t6.0 | 1 + .../tests/grep_xpg4/files/gout.t6.1 | 1 + .../tests/grep_xpg4/files/gout.t6.10 | 2 + .../tests/grep_xpg4/files/gout.t6.11 | 1 + .../tests/grep_xpg4/files/gout.t6.12 | 1 + .../tests/grep_xpg4/files/gout.t6.13 | 1 + .../tests/grep_xpg4/files/gout.t6.14 | 1 + .../tests/grep_xpg4/files/gout.t6.15 | 2 + .../tests/grep_xpg4/files/gout.t6.16 | 1 + .../tests/grep_xpg4/files/gout.t6.17 | 1 + .../tests/grep_xpg4/files/gout.t6.18 | 1 + .../tests/grep_xpg4/files/gout.t6.19 | 1 + .../tests/grep_xpg4/files/gout.t6.2 | 2 + .../tests/grep_xpg4/files/gout.t6.3 | 2 + .../tests/grep_xpg4/files/gout.t6.4 | 2 + .../tests/grep_xpg4/files/gout.t6.5 | 1 + .../tests/grep_xpg4/files/gout.t6.6 | 1 + .../tests/grep_xpg4/files/gout.t6.7 | 1 + .../tests/grep_xpg4/files/gout.t6.8 | 1 + .../tests/grep_xpg4/files/gout.t6.9 | 2 + .../tests/grep_xpg4/files/test.lL.0 | 3 ++ .../tests/grep_xpg4/files/test.lL.1 | 3 ++ .../util-tests/tests/grep_xpg4/grep_test.ksh | 36 ++++++++++++++++ 27 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.0 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.1 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.10 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.11 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.12 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.13 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.14 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.15 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.16 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.17 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.18 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.19 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.2 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.3 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.4 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.5 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.6 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.7 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.8 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.9 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.0 create mode 100644 usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.1 diff --git a/usr/src/cmd/grep/grep.c b/usr/src/cmd/grep/grep.c index ac5102367846..96f0dc4853f4 100644 --- a/usr/src/cmd/grep/grep.c +++ b/usr/src/cmd/grep/grep.c @@ -39,6 +39,7 @@ * Copyright 2018 RackTop Systems. * Copyright 2018 Nexenta Systems, Inc. * Copyright 2013 Damian Bogel. All rights reserved. + * Copyright 2020 Oxide Computer Company */ #include @@ -94,6 +95,7 @@ static uchar_t iflag; /* Case insensitve matching */ static uchar_t Hflag; /* Precede lines by file name */ static uchar_t hflag; /* Suppress printing of filename */ static uchar_t lflag; /* Print file names of matches */ +static uchar_t Lflag; /* Print file names of non-matches */ static uchar_t nflag; /* Precede lines by line number */ static uchar_t rflag; /* Search directories recursively */ static uchar_t bflag; /* Precede matches by block number */ @@ -201,7 +203,8 @@ main(int argc, char **argv) } } - while ((c = getopt(argc, argv, "vwchHilnrbse:f:qxEFIRA:B:C:")) != EOF) { + while ((c = getopt(argc, argv, "vwchHilLnrbse:f:qxEFIRA:B:C:")) != + EOF) { unsigned long tval; switch (c) { case 'v': /* POSIX: negate matches */ @@ -217,8 +220,17 @@ main(int argc, char **argv) regflags |= REG_ICASE; break; + /* + * The last of -l and -L are honored. + */ case 'l': /* POSIX: Write filenames only */ lflag++; + Lflag = 0; + break; + + case 'L': /* Write non-matching filenames */ + Lflag++; + lflag = 0; break; case 'n': /* POSIX: Write line numbers */ @@ -399,9 +411,9 @@ main(int argc, char **argv) usage(); /* - * -l overrides -H like in GNU grep + * -l or -L overrides -H like in GNU grep */ - if (lflag) + if (lflag || Lflag) Hflag = 0; /* @@ -409,8 +421,10 @@ main(int argc, char **argv) * We have -c override -l like in Solaris. * -q overrides -l & -c programmatically in grep() function. */ - if (cflag && lflag) + if (cflag && (lflag || Lflag)) { lflag = 0; + Lflag = 0; + } argv += optind - 1; argc -= optind - 1; @@ -1446,6 +1460,9 @@ grep(int fd, const char *fn) (void) printf("%s\n", fn); goto out; } + if (Lflag) { + goto out; + } if (!cflag) { if (Hflag || outfn) { (void) printf("%s%c", fn, separate); @@ -1518,6 +1535,20 @@ grep(int fd, const char *fn) (void) printf("%lld\n", matches); } } + + /* + * -L tells us to print the filename only when it doesn't match. So we + * run through the normal operationa and then invert it. + */ + if (Lflag) { + if (matches == 0) { + (void) printf("%s\n", fn); + matches = 1; + } else { + matches = 0; + } + } + return (matches != 0); } @@ -1530,7 +1561,7 @@ usage(void) (void) fprintf(stderr, gettext("usage: %5s"), cmdname); if (!egrep && !fgrep) (void) fprintf(stderr, gettext(" [-E|-F]")); - (void) fprintf(stderr, gettext(" [-bchHilnqrRsvx] [-A num] [-B num] " + (void) fprintf(stderr, gettext(" [-bchHilLnqrRsvx] [-A num] [-B num] " "[-C num|-num]\n [-e pattern_list]... " "[-f pattern_file]... [pattern_list] [file]...\n")); exit(2); diff --git a/usr/src/man/man1/grep.1 b/usr/src/man/man1/grep.1 index 92e25a96d397..1843b25c802b 100644 --- a/usr/src/man/man1/grep.1 +++ b/usr/src/man/man1/grep.1 @@ -44,8 +44,9 @@ .\" Portions Copyright (c) 1992, X/Open Company Limited All Rights Reserved .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved .\" Copyright 2018 Nexenta Systems, Inc. +.\" Copyright 2020 Oxide Computer Company .\" -.Dd February 10, 2018 +.Dd August 02, 2020 .Dt GREP 1 .Os .Sh NAME @@ -56,7 +57,7 @@ .Sh SYNOPSIS .Nm grep .Op Fl E Ns | Ns Fl F -.Op Fl bchHilnrRsqvwx +.Op Fl bchHilLnrRsqvwx .Op Fl A Ar num .Op Fl B Ar num .Op Fl C Ar num Ns | Ns Fl Ns Ar num @@ -107,7 +108,9 @@ delimiter line. .It Fl c Prints only a count of the lines that contain the pattern. Overrides -.Fl l . +.Fl l +and +.Fl L . .It Fl C Ar num Ns \&, Fl Ns Ar num Prints .Ar num @@ -168,6 +171,23 @@ Ignores upper/lower case distinction during comparisons. Prints only the names of files with matching lines, separated by NEWLINE characters. Does not repeat the names of files when the pattern is found more than once. +If both +.Fl l +and +.Fl L +are specified, only the last specified takes effect. +Overrides +.Fl H . +.It Fl L +The opposite of the +.Fl l +flag. +Prints only the names of files without matching lines. +If both +.Fl l +and +.Fl L +are specified, only the last specified takes effect. Overrides .Fl H . .It Fl n @@ -177,9 +197,10 @@ Quiet. Does not write anything to the standard output, regardless of matching lines. Exits with zero status if an input line is selected. Overrides -.Fl c +.Fl c , +.Fl l , and -.Fl l . +.Fl L . .It Fl r Read all files under each directory, recursively. Follow symbolic links on the command line, but skip symlinks that are diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf index 44cdcd18bdb2..d0251e5d8909 100644 --- a/usr/src/pkg/manifests/system-test-utiltest.mf +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -1431,6 +1431,28 @@ file path=opt/util-tests/tests/files/grep/gout.t4.0 mode=0444 file path=opt/util-tests/tests/files/grep/gout.t4.1 mode=0444 file path=opt/util-tests/tests/files/grep/gout.t5.0 mode=0444 file path=opt/util-tests/tests/files/grep/gout.t5.1 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.0 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.1 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.10 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.11 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.12 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.13 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.14 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.15 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.16 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.17 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.18 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.19 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.2 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.3 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.4 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.5 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.6 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.7 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.8 mode=0444 +file path=opt/util-tests/tests/files/grep/gout.t6.9 mode=0444 +file path=opt/util-tests/tests/files/grep/test.lL.0 mode=0444 +file path=opt/util-tests/tests/files/grep/test.lL.1 mode=0444 file path=opt/util-tests/tests/files/grep/test0 mode=0444 file path=opt/util-tests/tests/files/grep/test1 mode=0444 file path=opt/util-tests/tests/files/grep/test2 mode=0444 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile b/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile index fc9c12acf4cd..4129aa40e597 100644 --- a/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile @@ -30,6 +30,8 @@ PROGS = test0 \ test5 \ test6 \ test7 \ + test.lL.0 \ + test.lL.1 \ gout.t1.0 \ gout.t1.1 \ gout.t1.2 \ @@ -101,6 +103,26 @@ PROGS = test0 \ gout.t4.1 \ gout.t5.0 \ gout.t5.1 \ + gout.t6.0 \ + gout.t6.1 \ + gout.t6.2 \ + gout.t6.3 \ + gout.t6.4 \ + gout.t6.5 \ + gout.t6.6 \ + gout.t6.7 \ + gout.t6.8 \ + gout.t6.9 \ + gout.t6.10 \ + gout.t6.11 \ + gout.t6.12 \ + gout.t6.13 \ + gout.t6.14 \ + gout.t6.15 \ + gout.t6.16 \ + gout.t6.17 \ + gout.t6.18 \ + gout.t6.19 \ testnl CMDS = $(PROGS:%=$(TESTDIR)/%) diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.0 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.0 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.0 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.1 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.1 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.1 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.10 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.10 new file mode 100644 index 000000000000..3e5b18f1fcfd --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.10 @@ -0,0 +1,2 @@ +test.lL.0:1 +test.lL.1:0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.11 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.11 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.11 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.12 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.12 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.12 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.13 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.13 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.13 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.14 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.14 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.14 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.15 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.15 new file mode 100644 index 000000000000..2dd98874ab62 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.15 @@ -0,0 +1,2 @@ +test.lL.0 +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.16 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.16 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.16 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.17 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.17 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.17 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.18 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.18 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.18 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.19 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.19 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.19 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.2 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.2 new file mode 100644 index 000000000000..2dd98874ab62 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.2 @@ -0,0 +1,2 @@ +test.lL.0 +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.3 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.3 new file mode 100644 index 000000000000..2dd98874ab62 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.3 @@ -0,0 +1,2 @@ +test.lL.0 +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.4 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.4 new file mode 100644 index 000000000000..2dd98874ab62 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.4 @@ -0,0 +1,2 @@ +test.lL.0 +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.5 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.5 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.5 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.6 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.6 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.6 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.7 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.7 new file mode 100644 index 000000000000..0b392591e446 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.7 @@ -0,0 +1 @@ +test.lL.0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.8 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.8 new file mode 100644 index 000000000000..cd07a11199f2 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.8 @@ -0,0 +1 @@ +test.lL.1 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.9 b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.9 new file mode 100644 index 000000000000..3e5b18f1fcfd --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/gout.t6.9 @@ -0,0 +1,2 @@ +test.lL.0:1 +test.lL.1:0 diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.0 b/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.0 new file mode 100644 index 000000000000..86e041dad66a --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.0 @@ -0,0 +1,3 @@ +foo +bar +baz diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.1 b/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.1 new file mode 100644 index 000000000000..a8fdd66a4cb6 --- /dev/null +++ b/usr/src/test/util-tests/tests/grep_xpg4/files/test.lL.1 @@ -0,0 +1,3 @@ +FoO +bAr +BAZ diff --git a/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh b/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh index a1c6b6f64f4e..663ae2691604 100644 --- a/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh +++ b/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh @@ -166,6 +166,42 @@ FLAGS="-r run_tests 0 t5 a /tmp/test0 rm -rf /tmp/test0 +# +# Test Group 6: Test -l and -L which are supposed to match the file or +# not. We break this into cases that should always pass and those that +# should fail. The first group should always pass. +# +FLAGS="-l +-L +-il +-vl +-vil +-hl +-hL +-Hl +-HL +-cl +-cL +-nl +-nL +-l -A5 -B5 +-L -C5 +-nHvl +-l -L -l +-L -l +-l -L +-L -l -L" +run_tests 0 t6 foo test.lL.0 test.lL.1 + +# +# Test Group 7: -l and -L variants that should cause us to not match or +# fail for another reason. +# +FLAGS="-vL +-viL +-nHvL" +run_tests 1 t7 foo test.lL.0 test.lL.1 + # # Clean up temporary files. #