1#!/bin/sh
2# Verify behavior of printenv.
3
4# Copyright (C) 2009-2023 Free Software Foundation, Inc.
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
20print_ver_ printenv
21
22# Without arguments, printenv behaves like env.  Some shells provide
23# printenv as a builtin, so we must invoke it via "env".
24# But beware of $_, set by many shells to the last command run.
25# Also, filter out LD_PRELOAD, which is set when running under valgrind.
26# Note the apparently redundant "env  env": this is to ensure to get
27# env's output the same way as that of printenv and works around a bug
28# on aarch64 at least where libc's execvp reverses the order of the
29# output.
30env -- env | grep -Ev '^(_|LD_PRELOAD)=' > exp || framework_failure_
31env -- printenv | grep -Ev '^(_|LD_PRELOAD)=' > out || fail=1
32compare exp out || fail=1
33
34# POSIX is clear that environ may, but need not be, sorted.
35# Environment variable values may contain newlines, which cannot be
36# observed by merely inspecting output from printenv.
37if env -- printenv | grep '^ENV_TEST' >/dev/null ; then
38  skip_ "environment has potential interference from ENV_TEST*"
39fi
40
41# Printing a single variable's value.
42returns_ 1 env -- printenv ENV_TEST > out || fail=1
43compare /dev/null out || fail=1
44echo a > exp || framework_failure_
45ENV_TEST=a env -- printenv ENV_TEST > out || fail=1
46compare exp out || fail=1
47
48# Printing multiple variables.  Order follows command line.
49ENV_TEST1=a ENV_TEST2=b env -- printenv ENV_TEST2 ENV_TEST1 ENV_TEST2 > out \
50  || fail=1
51ENV_TEST1=a ENV_TEST2=b env -- printenv ENV_TEST1 ENV_TEST2 >> out || fail=1
52cat <<EOF > exp || framework_failure_
53b
54a
55b
56a
57b
58EOF
59compare exp out || fail=1
60
61# Exit status reflects missing variable, but remaining arguments processed.
62export ENV_TEST1=a
63returns_ 1 env -- printenv ENV_TEST2 ENV_TEST1 > out || fail=1
64returns_ 1 env -- printenv ENV_TEST1 ENV_TEST2 >> out || fail=1
65unset ENV_TEST1
66cat <<EOF > exp || framework_failure_
67a
68a
69EOF
70compare exp out || fail=1
71
72# Non-standard environment variable name.  Shells won't create it, but
73# env can, and printenv must be able to deal with it.
74echo b > exp || framework_failure_
75env -- -a=b printenv -- -a > out || fail=1
76compare exp out || fail=1
77
78# Silently reject invalid env-var names.
79# Bug present through coreutils 8.0.
80returns_ 1 env a=b=c printenv a=b > out || fail=1
81compare /dev/null out || fail=1
82
83Exit $fail
84