On 2021/01/25 00:53, Sebastian Benoit wrote:
> Sebastian Benoit([email protected]) on 2021.01.25 00:27:05 +0100:
> > Theo de Raadt([email protected]) on 2021.01.24 16:01:32 -0700:
> > > Stuart Henderson <[email protected]> wrote:
> > >
> > > > On 2021/01/24 12:10, Theo de Raadt wrote:
> > > > > I completely despise that the option is called "--null".
> > > > >
> > > > > Someone was a complete idiot.
> > > >
> > > > gnu grep has both --null and -z for this (why do they do that?!).
> > > > If it's added as --null it should be added as -z too.
> > > >
> > > > Looking at Debian codesearch most things using it as --null use other
> > > > long options that we don't have. Maybe just adding as -z would be
> > > > enough. It does seem a useful and fairly widely supported feature.
> > >
> > > Yes, maybe just add -z.
> >
> > Actually it's "-Z, --null". The lowercase -z in gnu grep is
> >
> > -z, --null-data
> > Treat input and output data as sequences of lines, each
> > terminated by a zero byte (the ASCII NUL character) instead of
> > a newline. Like the -Z or --null option, this option can be
> > used with commands like sort-z to process arbitrary file
> > names.
>
> And we already have -z for "force grep to behave as zgrep".
sigh.. OK I guess we are better skipping the short flag and just use --null
> Diff below with tedu@ suggestion and changed manpage text.
ok with me. if I was committing I would whine about the stupid flag in
commit log ;)
> >
> > Note that we have the -z in sort(1), which at least is consistent.
> > That also is a non-posix extension.
> >
> > > > Should have been -0 to match xargs and be similar to find's -print0
> > > > but it's too late for that now.
> > >
> > > Yes it should have been -0.
> > >
> > > But unfortunately some an uneducated idiot got involved. None of this
> > > is standardized. Unix script portability is being ruined by idiots, not
> > > just the people proposing it or writing it originally, but also the people
> > > who don't say "wrong" quickly enough. And much of this is because of
> > > intentional development silos.
>
> diff --git usr.bin/grep/grep.1 usr.bin/grep/grep.1
> index 5cc228df222..e1edae7e432 100644
> --- usr.bin/grep/grep.1
> +++ usr.bin/grep/grep.1
> @@ -49,6 +49,7 @@
> .Op Fl -context Ns Op = Ns Ar num
> .Op Fl -label Ns = Ns Ar name
> .Op Fl -line-buffered
> +.Op Fl -null
> .Op Ar pattern
> .Op Ar
> .Ek
> @@ -297,6 +298,16 @@ instead of the filename before lines.
> Force output to be line buffered.
> By default, output is line buffered when standard output is a terminal
> and block buffered otherwise.
> +.It Fl -null
> +Output a zero byte instead of the character that normally follows a
> +file name.
> +This option makes the output unambiguous, even in the presence of file
> +names containing unusual characters like newlines, making the output
> +suitable for use with the
> +.Fl 0
> +option to
> +.Xr xargs 1 .
> +This option is a non-POSIX extension and may not be portable.
> .El
> .Sh EXIT STATUS
> The
> diff --git usr.bin/grep/grep.c usr.bin/grep/grep.c
> index f41b5e20ca6..279d949fae7 100644
> --- usr.bin/grep/grep.c
> +++ usr.bin/grep/grep.c
> @@ -80,6 +80,7 @@ int vflag; /* -v: only show non-matching lines */
> int wflag; /* -w: pattern must start and end on word boundaries */
> int xflag; /* -x: pattern must match entire line */
> int lbflag; /* --line-buffered */
> +int nullflag; /* --null */
> const char *labelname; /* --label=name */
>
> int binbehave = BIN_FILE_BIN;
> @@ -89,6 +90,7 @@ enum {
> HELP_OPT,
> MMAP_OPT,
> LINEBUF_OPT,
> + NULL_OPT,
> LABEL_OPT,
> };
>
> @@ -134,6 +136,7 @@ static const struct option long_options[] =
> {"mmap", no_argument, NULL, MMAP_OPT},
> {"label", required_argument, NULL, LABEL_OPT},
> {"line-buffered", no_argument, NULL, LINEBUF_OPT},
> + {"null", no_argument, NULL, NULL_OPT},
> {"after-context", required_argument, NULL, 'A'},
> {"before-context", required_argument, NULL, 'B'},
> {"context", optional_argument, NULL, 'C'},
> @@ -436,6 +439,9 @@ main(int argc, char *argv[])
> case LINEBUF_OPT:
> lbflag = 1;
> break;
> + case NULL_OPT:
> + nullflag = 1;
> + break;
> case HELP_OPT:
> default:
> usage();
> diff --git usr.bin/grep/grep.h usr.bin/grep/grep.h
> index b3d24ae662b..37e295d4d40 100644
> --- usr.bin/grep/grep.h
> +++ usr.bin/grep/grep.h
> @@ -68,7 +68,7 @@ extern int cflags, eflags;
> extern int Aflag, Bflag, Eflag, Fflag, Hflag, Lflag,
> Rflag, Zflag,
> bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag, qflag,
> - sflag, vflag, wflag, xflag;
> + sflag, vflag, wflag, xflag, nullflag;
> extern int binbehave;
> extern const char *labelname;
>
> diff --git usr.bin/grep/util.c usr.bin/grep/util.c
> index e16d08e7d85..546bd09dc3b 100644
> --- usr.bin/grep/util.c
> +++ usr.bin/grep/util.c
> @@ -172,13 +172,13 @@ procfile(char *fn)
>
> if (cflag) {
> if (!hflag)
> - printf("%s:", ln.file);
> + printf("%s%c", ln.file, nullflag ? '\0' : ':');
> printf("%llu%s\n", c, overflow ? "+" : "");
> }
> if (lflag && c != 0)
> - printf("%s\n", fn);
> + printf("%s%c", fn, nullflag ? '\0' : '\n');
> if (Lflag && c == 0)
> - printf("%s\n", fn);
> + printf("%s%c", fn, nullflag ? '\0' : '\n');
> if (c && !cflag && !lflag && !Lflag &&
> binbehave == BIN_FILE_BIN && nottext && !qflag)
> printf("Binary file %s matches\n", fn);
> @@ -660,7 +660,7 @@ printline(str_t *line, int sep, regmatch_t *pmatch)
> }
> if (nflag) {
> if (n)
> - putchar(sep);
> + putchar(nullflag ? '\0' : sep);
> printf("%lld", line->line_no);
> ++n;
> }
>