1# Copyright (C) 2014-2018 Free Software Foundation, Inc.
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3, or (at your option)
6# any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16# Set up standalone info test environment
17# This file is to be sourced, not to be run directly
18
19# write each expanded command to the *.log file for the test.
20set -x
21
22# Use the second line to run the program under valgrind.
23ginfo="./ginfo --init-file $srcdir/t/Infokey-config"
24#ginfo="valgrind --log-file=$0.val.log --leak-check=full ./ginfo --init-file $srcdir/t/Infokey-config"
25
26# Only look for Info files in our test directory
27INFOPATH=$srcdir/t/infodir; export INFOPATH
28
29t=$srcdir/t; export t
30
31ginfo_output=t/`basename $0.out`
32
33# These are only used for interactive tests
34pipein=t/`basename $0.pipein`
35pty_type=t/`basename $0.pipeout`
36
37# Remove left over file from previous tests
38rm -f $ginfo_output
39
40# File to dump nodes to with M-x print-node
41INFO_PRINT_COMMAND=">$ginfo_output"; export INFO_PRINT_COMMAND
42
43# Not an interactive test
44pty_pid=0
45
46# Get error messages in English
47LC_ALL=C; export LC_ALL
48
49# Make sure that non-interactive operation works even if terminal is dumb
50TERM=dumb; export TERM
51
52# Clean up if the test is interrupted, for example if the user types
53# C-c, to avoid lingering child processes.  Signal 2 is SIGINT.
54trap cleanup 2
55
56# Cleanup and exit
57cleanup ()
58{
59  # Delete created files and kill spawned processes if any.
60  test $pty_pid -ne 0 && kill $pty_pid
61
62  rm -f $ginfo_output
63  rm -f $pipein $pty_type
64
65  #killall `basename $0`  # see below
66  exit $retval
67}
68
69# Uncomment this line and "killall" above if previous test runs were not
70# cleaned up properly, and rerun "make check".
71
72#cleanup
73
74timeout_test ()
75{
76  wait $ginfo_pid
77  status=$?
78
79  # If the program was not ended by a signal, kill the subshell that
80  # is waiting to send it a signal.
81  test $status -lt 128 && kill $killer_pid
82
83  retval=0
84  if test $status != 0; then
85    retval=1
86  fi
87
88  # Program is gone, so avoid trying to kill it in cleanup
89  ginfo_pid=0
90}
91
92# Functions for interactive tests
93
94
95#  we may look up whether a couple of utilities exist.
96
97path_sep=":"
98
99# findprog PROG - Return true if PROG is somewhere in PATH, else false.
100findprog ()
101{
102  saveIFS=$IFS
103  IFS=$path_sep  # break path components at the path separator
104  for dir in $PATH; do
105    IFS=$saveIFS
106    # The basic test for an executable is `test -f $f && test -x $f'.
107    # (`test -x' is not enough, because it can also be true for directories.)
108    # We have to try this both for $1 and $1.exe.
109    #
110    # Note: On Cygwin and DJGPP, `test -x' also looks for .exe.  On Cygwin,
111    # also `test -f' has this enhancement, but not on DJGPP.  (Both are
112    # design decisions, so there is little chance to make them consistent.)
113    # Thusly, it seems to be difficult to make use of these enhancements.
114    #
115    if   { test -f "$dir/$1"     && test -x "$dir/$1"; } \
116      || { test -f "$dir/$1.exe" && test -x "$dir/$1.exe"; }; then
117      return 0
118    fi
119  done
120  return 1
121}
122
123# Initialize test of interactive operation
124initialization_done=0
125init_interactive_test ()
126{
127  test $initialization_done -eq 1 && return 0
128  initialization_done=1
129
130  # Skip test if pseudotty wasn't built
131  test -x pseudotty || exit 77
132
133  # Avoid ginfo complaining that terminal is too dumb
134  TERM=vt100; export TERM
135
136  # Create named pipes to communicate with pseudotty program, or quit.
137  rm -f $pipein $pty_type # must already be defined
138  if findprog mkfifo; then
139    mkfifo $pipein
140    mkfifo $pty_type
141    #
142    if test ! -r $pipein || test ! -r $pty_type; then
143      echo "$0: could not mkfifo pipes" >&2
144      exit 77
145    fi
146    # ok, we'll proceed with the test.
147  else
148    echo "$0: mkfifo program not found - cannot make named pipes" >&2
149    exit 77
150  fi
151
152  # We can feed input bytes into $pty_type to be passed onto ginfo, as
153  # if they were typed by a user in an interactive session.
154  # We redirect to the FIFO within a subshell, because under NetBSD 6.1.4
155  # it hangs otherwise.
156  (exec ./pseudotty "$pty_type" >$pipein) &
157  pty_pid=$!
158  # Get name of pseudo-terminal slave device
159  read pts_device <$pipein
160
161  # For passing bytes to the program
162  exec 7>$pty_type
163
164  # glibc can kill a running process if it detects a condition like a
165  # double free.  This specifies that the message it prints when it does
166  # this should be sent to stderr so it can be recorded in the test *.log
167  # files.
168  LIBC_FATAL_STDERR_=1; export LIBC_FATAL_STDERR
169}
170
171run_ginfo ()
172{
173  init_interactive_test
174
175  (
176    exec 7>&- ; # Close fd from parent shell
177    exec $ginfo "$@" 0<>$pts_device 1<&0 ;
178  ) &
179  ginfo_pid=$!
180  (sleep 5 ; kill $ginfo_pid) &
181  killer_pid=$!
182}
183