Index: head/usr.bin/env/env.1 =================================================================== --- head/usr.bin/env/env.1 +++ head/usr.bin/env/env.1 @@ -31,7 +31,7 @@ .\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp .\" $FreeBSD$ .\" -.Dd April 17, 2008 +.Dd November 7, 2019 .Dt ENV 1 .Os .Sh NAME @@ -39,7 +39,7 @@ .Nd set environment and execute command, or print environment .Sh SYNOPSIS .Nm -.Op Fl iv +.Op Fl 0iv .Op Fl P Ar altpath .Op Fl S Ar string .Op Fl u Ar name @@ -64,6 +64,8 @@ .Pp The options are as follows: .Bl -tag -width indent +.It Fl 0 +End each output line with NUL, not newline. .It Fl i Execute the .Ar utility @@ -130,8 +132,15 @@ .Ar utility is specified, .Nm -prints out the names and values -of the variables in the environment, with one name/value pair per line. +prints out the names and values of the variables in the environment. +Each name/value 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 +may not be specified together. .\" .Ss Details of Fl S \&Ss (split-string) processing The processing of the Index: head/usr.bin/env/env.c =================================================================== --- head/usr.bin/env/env.c +++ head/usr.bin/env/env.c @@ -59,22 +59,33 @@ static void usage(void); +/* + * Exit codes. + */ +#define EXIT_CANCELED 125 /* Internal error prior to exec attempt. */ +#define EXIT_CANNOT_INVOKE 126 /* Program located, but not usable. */ +#define EXIT_ENOENT 127 /* Could not find program to exec. */ + int main(int argc, char **argv) { - char *altpath, **ep, *p, **parg; + char *altpath, **ep, *p, **parg, term; char *cleanenv[1]; int ch, want_clear; int rtrn; altpath = NULL; want_clear = 0; - while ((ch = getopt(argc, argv, "-iP:S:u:v")) != -1) + term = '\n'; + while ((ch = getopt(argc, argv, "-0iP:S:u:v")) != -1) switch(ch) { case '-': case 'i': want_clear = 1; break; + case '0': + term = '\0'; + break; case 'P': altpath = strdup(optarg); break; @@ -118,6 +129,8 @@ err(EXIT_FAILURE, "setenv %s", *argv); } if (*argv) { + if (term == '\0') + errx(EXIT_CANCELED, "cannot specify command with -0"); if (altpath) search_paths(altpath, argv); if (env_verbosity) { @@ -129,10 +142,11 @@ sleep(1); } execvp(*argv, argv); - err(errno == ENOENT ? 127 : 126, "%s", *argv); + err(errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE, + "%s", *argv); } for (ep = environ; *ep; ep++) - (void)printf("%s\n", *ep); + (void)printf("%s%c", *ep, term); exit(0); } @@ -140,7 +154,7 @@ usage(void) { (void)fprintf(stderr, - "usage: env [-iv] [-P utilpath] [-S string] [-u name]\n" + "usage: env [-0iv] [-P utilpath] [-S string] [-u name]\n" " [name=value ...] [utility [argument ...]]\n"); exit(1); }