pty: Activate the signature wrapper of forkpty.
[gnulib.git] / tests / test-echo.sh
1 #! /bin/sh
2
3 # func_exit STATUS
4 # exit with status
5 func_exit ()
6 {
7   (exit $1); exit $1
8 }
9
10 # func_fatal_error message
11 # outputs to stderr a fatal error message, and terminates the program.
12 func_fatal_error ()
13 {
14   echo "test-echo.sh: *** $1" 1>&2
15   echo "test-echo.sh: *** Stop." 1>&2
16   func_exit 1
17 }
18
19 # Ensure an 'echo' command that does not interpret backslashes.
20 # Test cases:
21 #   echo '\n' | wc -l                 prints 1 when OK, 2 when KO
22 #   echo '\t' | grep t > /dev/null    has return code 0 when OK, 1 when KO
23 # This problem is a weird heritage from SVR4. BSD got it right (except that
24 # BSD echo interprets '-n' as an option, which is also not desirable).
25 # Nowadays the problem occurs in 4 situations:
26 # - in bash, when the shell option xpg_echo is set (bash >= 2.04)
27 #            or when it was built with --enable-usg-echo-default (bash >= 2.0)
28 #            or when it was built with DEFAULT_ECHO_TO_USG (bash < 2.0),
29 # - in zsh, when sh-emulation is not set,
30 # - in ksh (e.g. AIX /bin/sh and Solaris /usr/xpg4/bin/sh are ksh instances,
31 #           and HP-UX /bin/sh and IRIX /bin/sh behave similarly),
32 # - in Solaris /bin/sh and OSF/1 /bin/sh.
33 # We try the following workarounds:
34 # - for all: respawn using $CONFIG_SHELL if that is set and works.
35 # - for bash >= 2.04: unset the shell option xpg_echo.
36 # - for bash >= 2.0: define echo to a function that uses the printf built-in.
37 # - for bash < 2.0: define echo to a function that uses cat of a here document.
38 # - for zsh: turn sh-emulation on.
39 # - for ksh: alias echo to 'print -r'.
40 # - for ksh: alias echo to a function that uses cat of a here document.
41 # - for Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh and rely on
42 #   the ksh workaround.
43 # - otherwise: respawn using /bin/sh and rely on the workarounds.
44 # When respawning, we pass --no-reexec as first argument, so as to avoid
45 # turning this script into a fork bomb in unlucky situations.
46 have_echo=
47 if echo '\t' | grep t > /dev/null; then
48   have_echo=yes # Lucky!
49 fi
50 # Try the workarounds.
51 # Respawn using $CONFIG_SHELL if that is set and works.
52 if test -z "$have_echo" \
53    && test "X$1" != "X--no-reexec" \
54    && test -n "$CONFIG_SHELL" \
55    && test -f "$CONFIG_SHELL" \
56    && $CONFIG_SHELL -c 'echo '\t' | grep t > /dev/null'; then
57   exec $CONFIG_SHELL "$0" --no-reexec "$@"
58   exit 127
59 fi
60 # For bash >= 2.04: unset the shell option xpg_echo.
61 if test -z "$have_echo" \
62    && test -n "$BASH_VERSION" \
63    && (shopt -o xpg_echo; echo '\t' | grep t > /dev/null) 2>/dev/null; then
64   shopt -o xpg_echo
65   have_echo=yes
66 fi
67 # For bash >= 2.0: define echo to a function that uses the printf built-in.
68 # For bash < 2.0: define echo to a function that uses cat of a here document.
69 # (There is no win in using 'printf' over 'cat' if it is not a shell built-in.)
70 if test -z "$have_echo" \
71    && test -n "$BASH_VERSION"; then \
72   if type printf 2>/dev/null | grep / > /dev/null; then
73     # 'printf' is not a shell built-in.
74 echo ()
75 {
76 cat <<EOF
77 $*
78 EOF
79 }
80   else
81     # 'printf' is a shell built-in.
82 echo ()
83 {
84   printf '%s\n' "$*"
85 }
86   fi
87   if echo '\t' | grep t > /dev/null; then
88     have_echo=yes
89   fi
90 fi
91 # For zsh: turn sh-emulation on.
92 if test -z "$have_echo" \
93    && test -n "$ZSH_VERSION" \
94    && (emulate sh) >/dev/null 2>&1; then
95   emulate sh
96 fi
97 # For ksh: alias echo to 'print -r'.
98 if test -z "$have_echo" \
99    && (type print) >/dev/null 2>&1; then
100   # A 'print' command exists.
101   if type print 2>/dev/null | grep / > /dev/null; then
102     :
103   else
104     # 'print' is a shell built-in.
105     if (print -r '\told' | grep told > /dev/null) 2>/dev/null; then
106       # 'print' is the ksh shell built-in.
107       alias echo='print -r'
108     fi
109   fi
110 fi
111 if test -z "$have_echo" \
112    && echo '\t' | grep t > /dev/null; then
113   have_echo=yes
114 fi
115 # For ksh: alias echo to a function that uses cat of a here document.
116 # The ksh manual page says:
117 #   "Aliasing is performed when scripts are read, not while they are executed.
118 #    Therefore, for an alias to take effect, the alias definition command has
119 #    to be executed before the command which references the alias is read."
120 # Because of this, we have to play strange tricks with have_echo, to ensure
121 # that the top-level statement containing the test starts after the 'alias'
122 # command.
123 if test -z "$have_echo"; then
124 bsd_echo ()
125 {
126 cat <<EOF
127 $*
128 EOF
129 }
130 alias echo=bsd_echo 2>/dev/null
131 fi
132 if test -z "$have_echo" \
133    && echo '\t' | grep t > /dev/null; then
134   have_echo=yes
135 fi
136 if test -z "$have_echo"; then
137   unalias echo 2>/dev/null
138 fi
139 # For Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh.
140 if test -z "$have_echo" \
141    && test "X$1" != "X--no-reexec" \
142    && test -f /bin/ksh; then
143   exec /bin/ksh "$0" --no-reexec "$@"
144   exit 127
145 fi
146 # Otherwise: respawn using /bin/sh.
147 if test -z "$have_echo" \
148    && test "X$1" != "X--no-reexec" \
149    && test -f /bin/sh; then
150   exec /bin/sh "$0" --no-reexec "$@"
151   exit 127
152 fi
153 if test -z "$have_echo"; then
154   func_fatal_error "Shell does not support 'echo' correctly. Please install GNU bash and set the environment variable CONFIG_SHELL to point to it."
155 fi
156 if echo '\t' | grep t > /dev/null; then
157   : # Works fine now.
158 else
159   func_fatal_error "Shell does not support 'echo' correctly. Workaround does not work. Please report this as a bug to bug-gnulib@gnu.org."
160 fi
161 if test "X$1" = "X--no-reexec"; then
162   shift
163 fi
164
165 # This command determines the exit code.
166 echo '\t' | grep t > /dev/null