Implement env(1) -0

-0      End each output line with NUL, not newline.

FreeBSD and GNU env(1) implement -0 which is used in 3rd party scripts.

This change is based on the FreeBSD code.
This commit is contained in:
kamil 2020-02-08 11:02:07 +00:00
parent 1b5d8d2ce0
commit f342178338
2 changed files with 39 additions and 15 deletions

32
usr.bin/env/env.1 vendored
View File

@ -1,4 +1,4 @@
.\" $NetBSD: env.1,v 1.13 2020/02/08 10:30:22 kamil Exp $ .\" $NetBSD: env.1,v 1.14 2020/02/08 11:02:07 kamil Exp $
.\" .\"
.\" Copyright (c) 1980, 1990 The Regents of the University of California. .\" Copyright (c) 1980, 1990 The Regents of the University of California.
.\" All rights reserved. .\" All rights reserved.
@ -30,7 +30,7 @@
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" from: @(#)printenv.1 6.7 (Berkeley) 7/28/91 .\" from: @(#)printenv.1 6.7 (Berkeley) 7/28/91
.\" $NetBSD: env.1,v 1.13 2020/02/08 10:30:22 kamil Exp $ .\" $NetBSD: env.1,v 1.14 2020/02/08 11:02:07 kamil Exp $
.\" .\"
.Dd February 8, 2020 .Dd February 8, 2020
.Dt ENV 1 .Dt ENV 1
@ -40,7 +40,7 @@
.Nd set and print environment .Nd set and print environment
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl i .Op Fl 0i
.Op Fl u Ar name .Op Fl u Ar name
.Op Ar name=value ... .Op Ar name=value ...
.Oo .Oo
@ -86,10 +86,17 @@ If no
.Ar utility .Ar utility
is specified, is specified,
.Nm .Nm
prints out the names and values prints out the names and values of the variables in the environment.
of the variables in the environment, with one Each
.Ar name=value .Ar name=value
pair per line. pair is separated by a new line unless
.Fl 0
is specified, in which case name/value pairs are separated by NUL.
Both
.Fl 0
and
.Ar utility
must not be specified together.
.Sh EXIT STATUS .Sh EXIT STATUS
.Nm .Nm
exits with one of the following values: exits with one of the following values:
@ -111,6 +118,11 @@ was invoked, but failed in some way;
see its manual page for more information. see its manual page for more information.
In this case the exit code is returned by the utility itself, not In this case the exit code is returned by the utility itself, not
.Nm . .Nm .
.It 125
.Ar utility
was specified together with the
.Fl 0
option.
.It 126 .It 126
.Ar utility .Ar utility
was found, but could not be invoked. was found, but could not be invoked.
@ -125,7 +137,9 @@ option has been deprecated but is still supported in this implementation.
.Pp .Pp
The The
.Fl u .Fl u
option is a non-standard extension. and
.Fl 0
options are non-standard extensions.
.Sh SEE ALSO .Sh SEE ALSO
.Xr execvp 3 , .Xr execvp 3 ,
.Xr environ 7 .Xr environ 7
@ -142,7 +156,9 @@ command appeared in
.Pp .Pp
The The
.Fl u .Fl u
option first appeared in and
.Fl 0
optionss first appeared in
.Nx 10 . .Nx 10 .
.Sh BUGS .Sh BUGS
.Nm .Nm

22
usr.bin/env/env.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: env.c,v 1.22 2020/02/08 10:36:02 kamil Exp $ */ /* $NetBSD: env.c,v 1.23 2020/02/08 11:02:07 kamil Exp $ */
/* /*
* Copyright (c) 1988, 1993, 1994 * Copyright (c) 1988, 1993, 1994
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
#ifndef lint #ifndef lint
/*static char sccsid[] = "@(#)env.c 8.3 (Berkeley) 4/2/94";*/ /*static char sccsid[] = "@(#)env.c 8.3 (Berkeley) 4/2/94";*/
__RCSID("$NetBSD: env.c,v 1.22 2020/02/08 10:36:02 kamil Exp $"); __RCSID("$NetBSD: env.c,v 1.23 2020/02/08 11:02:07 kamil Exp $");
#endif /* not lint */ #endif /* not lint */
#include <err.h> #include <err.h>
@ -54,15 +54,19 @@ extern char **environ;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char **ep; char **ep, term;
char *cleanenv[1]; char *cleanenv[1];
int ch; int ch;
setprogname(*argv); setprogname(*argv);
(void)setlocale(LC_ALL, ""); (void)setlocale(LC_ALL, "");
while ((ch = getopt(argc, argv, "-iu:")) != -1) term = '\n';
while ((ch = getopt(argc, argv, "-0iu:")) != -1)
switch((char)ch) { switch((char)ch) {
case '0':
term = '\0';
break;
case '-': /* obsolete */ case '-': /* obsolete */
case 'i': case 'i':
environ = cleanenv; environ = cleanenv;
@ -82,7 +86,11 @@ main(int argc, char **argv)
if (*argv) { if (*argv) {
/* return 127 if the command to be run could not be found; 126 /* return 127 if the command to be run could not be found; 126
if the command was found but could not be invoked */ if the command was found but could not be invoked; 125 if
-0 was specified with utility.*/
if (term == '\0')
errx(125, "cannot specify command with -0");
(void)execvp(*argv, argv); (void)execvp(*argv, argv);
err((errno == ENOENT) ? 127 : 126, "%s", *argv); err((errno == ENOENT) ? 127 : 126, "%s", *argv);
@ -90,7 +98,7 @@ main(int argc, char **argv)
} }
for (ep = environ; *ep; ep++) for (ep = environ; *ep; ep++)
(void)printf("%s\n", *ep); (void)printf("%s%c", *ep, term);
exit(0); exit(0);
} }
@ -99,7 +107,7 @@ static void
usage(void) usage(void)
{ {
(void)fprintf(stderr, (void)fprintf(stderr,
"Usage: %s [-i] [-u name] [name=value ...] [command]\n", "Usage: %s [-0i] [-u name] [name=value ...] [command]\n",
getprogname()); getprogname());
exit(1); exit(1);
} }