123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- # Copyright (C) 2014, 2015, 2016 Free Software Foundation, Inc.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 3, or (at your option)
- # any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- # Initialize test of interactive operation
- # This file is to be sourced, not run directly
- # Skip test if pseudotty wasn't built
- test -x pseudotty || exit 77
- # we may look up whether a couple of utilities exist.
- path_sep=":"
- # findprog PROG - Return true if PROG is somewhere in PATH, else false.
- findprog ()
- {
- saveIFS=$IFS
- IFS=$path_sep # break path components at the path separator
- for dir in $PATH; do
- IFS=$saveIFS
- # The basic test for an executable is `test -f $f && test -x $f'.
- # (`test -x' is not enough, because it can also be true for directories.)
- # We have to try this both for $1 and $1.exe.
- #
- # Note: On Cygwin and DJGPP, `test -x' also looks for .exe. On Cygwin,
- # also `test -f' has this enhancement, but not on DJGPP. (Both are
- # design decisions, so there is little chance to make them consistent.)
- # Thusly, it seems to be difficult to make use of these enhancements.
- #
- if { test -f "$dir/$1" && test -x "$dir/$1"; } \
- || { test -f "$dir/$1.exe" && test -x "$dir/$1.exe"; }; then
- return 0
- fi
- done
- return 1
- }
- #
- # Avoid ginfo complaining that terminal is too dumb
- TERM=vt100; export TERM
- FINISHEDFIFO=t/`basename $0.finished`
- # See cleanup in Init-test.inc.
- findprog stty && { STTY=stty ; reset_required=yes ; }
- test $reset_required=yes && { $STTY | grep [-]echo ; } && reset_required=no
- # Create named pipes to communicate with pseudotty program, or quit.
- rm -f $PIPEIN $PTY_TYPE # must already be defined
- if findprog mkfifo; then
- mkfifo $PIPEIN
- mkfifo $PTY_TYPE
- #
- if test ! -r $PIPEIN || test ! -r $PTY_TYPE; then
- echo "$0: could not mkfifo pipes" >&2
- exit 77
- fi
- # ok, we'll proceed with the test.
- else
- echo "$0: mkfifo program not found - cannot make named pipes" >&2
- exit 77
- fi
- # We can feed input bytes into $PTY_TYPE to be passed onto ginfo, as
- # if they were typed by a user in an interactive session.
- # We redirect to the FIFO within a subshell, because under NetBSD 6.1.4
- # it hangs otherwise.
- (exec ./pseudotty "$PTY_TYPE" >$PIPEIN) &
- PTY_PID=$!
- # Get name of pseudo-terminal slave device
- read PTS_DEVICE <$PIPEIN
- # Keeping the FIFO open for writing prevents the select call in
- # pseudotty returning EOF after a single "printf something >$PTY_TYPE".
- exec 7>$PTY_TYPE
- # glibc can kill a running process if it detects a condition like a
- # double free. This specifies that the message it prints when it does
- # this should be sent to stderr so it can be recorded in the test *.log
- # files.
- LIBC_FATAL_STDERR_=1; export LIBC_FATAL_STDERR
- run_ginfo ()
- {
- rm -f $FINISHEDFIFO
- mkfifo $FINISHEDFIFO
- { # Close fd opened to control FIFO in subshell so pseudotty can exit
- # for an EOF. This prevents lingering processes if a test is
- # interrupted.
- exec 7>&- ;
- exec 8>$FINISHEDFIFO ;
- $GINFO $GINFO_OPTIONS "$@" ;
- test $? -eq 0 || echo failure >$FINISHEDFIFO ;
- echo finished >$FINISHEDFIFO ; } 0<>$PTS_DEVICE 1<&0 &
- SUBSHELL=$!
- exec 8<$FINISHEDFIFO
- # Although we don't write to the FIFO in this process, we still need
- # to open it for writing, because if the above subshell exits before
- # we read from it, we won't be able to open it - even though
- # "finished" is buffered.
- exec 9>$FINISHEDFIFO
- # Check for pgrep
- if findprog pgrep; then
- # Get the PID of the running ginfo process. Look for a process called
- # "ginfo" whose parent process is the subshell executed by the previous
- # command.
- echo 'Fetching PID of ginfo process under test...' >&2
- GINFO_PID=
- # Try 3 times and then give up. The process may never have started,
- # have started under a different name, or have already exited.
- for i in 1 2 3; do
- GINFO_PID=`pgrep -P $SUBSHELL $GINFO_NAME ; \
- test $? -eq 0 || test $? -eq 1 || exit 99`
- # This use of pgrep is likely not portable (works on procps).
- # Check if it is likely to have worked.
- # Exit status was anything other than 0 or 1
- test $? -eq 99 && { GINFO_PID=unknown; break; }
- # More than one line in output
- echo $GINFO_PID | wc -l | grep '^0$\|^1$' >/dev/null \
- || { GINFO_PID=unknown; break; }
- # Non-numeral characters present
- echo $GINFO_PID | grep -v '^[0-9]*$' >/dev/null
- test $? -eq 0 && { GINFO_PID=unknown; break; }
- GINFO_PID=`echo $GINFO_PID | tr -d '\n'`
- test "$GINFO_PID" = "" || break
- sleep 1 # Give subshell time to spawn ginfo process
- done
- test "$GINFO_PID" = "" && GINFO_PID=unknown
- echo ...$GINFO_PID >&2
- else
- echo 'pgrep program not found - cannot get PID of ginfo process' >&2
- GINFO_PID=unknown
- fi
- }
|