mirror of
https://github.com/coreutils/coreutils.git
synced 2026-10-28 09:44:34 +08:00
env: allow bare --env0-from to round-trip
Support --env0-from reading any environment generated by -0, irrespective of whether -i is specified. * src/env.c (set_envvars_from_file): Now that this function always builds its own vector, support reading entries without an equals, which are just appended to the existing vector. * doc/coreutils.texi (env invocation): Adjust accordingly. * tests/env/env0-from.sh: Likewise.
This commit is contained in:
1 parent
9c28113d8a
commit
e871648b79
3 files changed
+46
-23
No files matched your search
+5
-4
@@ -17573,10 +17573,11 @@ Read NUL-terminated environment entries from @var{file}. If @var{file}
|
||||
is @samp{-}, read from standard input. The file must either be empty or
|
||||
end with a NUL byte.
|
||||
|
||||
Without @option{--ignore-environment}, each entry must be a
|
||||
@samp{@var{name}=@var{value}} assignment. Assignments replace inherited
|
||||
variables with the same name, and a later assignment in @var{file} takes
|
||||
precedence over an earlier one.
|
||||
Without @option{--ignore-environment}, entries of the form
|
||||
@samp{@var{name}=@var{value}} replace inherited variables with the same
|
||||
name, and a later assignment in @var{file} takes precedence over an earlier
|
||||
one. Entries without an @samp{=} byte, including empty entries, are
|
||||
appended to the environment without replacing another entry.
|
||||
|
||||
With @option{--ignore-environment}, the entries replace the environment
|
||||
directly. Their order and contents are preserved, including duplicate
|
||||
|
||||
@@ -346,7 +346,7 @@ read_env_file (char const *file)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Merge the NUL-delimited assignments in FILE into the environment.
|
||||
/* Merge the NUL-delimited entries in FILE into the environment.
|
||||
Return true if ENV now owns the environment vector. */
|
||||
static bool
|
||||
set_envvars_from_file (struct env_vector *env, char const *file)
|
||||
@@ -380,10 +380,6 @@ set_envvars_from_file (struct env_vector *env, char const *file)
|
||||
for (char *assignment = env0_from_buffer; assignment < end; )
|
||||
{
|
||||
char *next = assignment + strlen (assignment) + 1;
|
||||
if (! strchr (assignment, '='))
|
||||
error (EXIT_CANCELED, 0,
|
||||
_("invalid variable specification %s in %s"),
|
||||
quoteaf_n (0, assignment), quoteaf_n (1, file));
|
||||
++file_count;
|
||||
assignment = next;
|
||||
}
|
||||
@@ -424,17 +420,26 @@ set_envvars_from_file (struct env_vector *env, char const *file)
|
||||
for (char *assignment = env0_from_buffer; assignment < end; )
|
||||
{
|
||||
char *next = assignment + strlen (assignment) + 1;
|
||||
devmsg ("setenv: %s\n", assignment);
|
||||
|
||||
char **slot = hash_lookup (slot_table, &assignment);
|
||||
if (slot)
|
||||
*slot = assignment;
|
||||
char *eq = strchr (assignment, '=');
|
||||
if (! eq)
|
||||
{
|
||||
devmsg ("append: %s\n", assignment);
|
||||
merged[merged_count++] = assignment;
|
||||
}
|
||||
else
|
||||
{
|
||||
merged[merged_count] = assignment;
|
||||
if (! hash_insert (slot_table, &merged[merged_count]))
|
||||
xalloc_die ();
|
||||
++merged_count;
|
||||
devmsg ("setenv: %s\n", assignment);
|
||||
|
||||
char **slot = hash_lookup (slot_table, &assignment);
|
||||
if (slot)
|
||||
*slot = assignment;
|
||||
else
|
||||
{
|
||||
merged[merged_count] = assignment;
|
||||
if (! hash_insert (slot_table, &merged[merged_count]))
|
||||
xalloc_die ();
|
||||
++merged_count;
|
||||
}
|
||||
}
|
||||
assignment = next;
|
||||
}
|
||||
|
||||
Vendored
+22
-5
@@ -148,13 +148,30 @@ printf %s '' >empty || framework_failure_
|
||||
env -i --env0-from=empty -0 >out || fail=1
|
||||
compare /dev/null out || fail=1
|
||||
|
||||
# The file must end in NUL. Without -i, every record is an assignment.
|
||||
# Without -i, append entries that have no name to look up. Native Windows
|
||||
# rejects such entries since its environment cannot represent them.
|
||||
case $host_os in
|
||||
mingw* | windows*)
|
||||
printf 'not-an-assignment\0' >invalid || framework_failure_
|
||||
returns_ 125 env --env0-from=invalid >out 2>err || fail=1
|
||||
printf '\0' >invalid || framework_failure_
|
||||
returns_ 125 env --env0-from=invalid >out 2>err || fail=1
|
||||
;;
|
||||
*)
|
||||
printf 'A=file1\0opaque\0\0A=file2\0B=new\0' >mixed \
|
||||
|| framework_failure_
|
||||
printf 'A=file2\0opaque\0\0B=new\0' >exp || framework_failure_
|
||||
LC_ALL=C sort -z exp >exp-sorted || framework_failure_
|
||||
env -i A=old "$abs_top_builddir/src/env$EXEEXT" \
|
||||
--env0-from=mixed -0 >all || fail=1
|
||||
LC_ALL=C sort -z all >out || framework_failure_
|
||||
compare exp-sorted out || fail=1
|
||||
;;
|
||||
esac
|
||||
|
||||
# The file must end in NUL.
|
||||
printf 'A=unterminated' >invalid || framework_failure_
|
||||
returns_ 125 env --env0-from=invalid >out 2>err || fail=1
|
||||
printf 'not-an-assignment\0' >invalid || framework_failure_
|
||||
returns_ 125 env --env0-from=invalid >out 2>err || fail=1
|
||||
printf '\0' >invalid || framework_failure_
|
||||
returns_ 125 env --env0-from=invalid >out 2>err || fail=1
|
||||
returns_ 125 env --env0-from=does-not-exist >out 2>err || fail=1
|
||||
|
||||
# Invalid -u names are still diagnosed after loading variables from a file.
|
||||
|
||||
Reference in new issue
Block a user