Init-inter.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # Copyright (C) 2014, 2015, 2016 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. # Initialize test of interactive operation
  16. # This file is to be sourced, not run directly
  17. # Skip test if pseudotty wasn't built
  18. test -x pseudotty || exit 77
  19. # we may look up whether a couple of utilities exist.
  20. path_sep=":"
  21. # findprog PROG - Return true if PROG is somewhere in PATH, else false.
  22. findprog ()
  23. {
  24. saveIFS=$IFS
  25. IFS=$path_sep # break path components at the path separator
  26. for dir in $PATH; do
  27. IFS=$saveIFS
  28. # The basic test for an executable is `test -f $f && test -x $f'.
  29. # (`test -x' is not enough, because it can also be true for directories.)
  30. # We have to try this both for $1 and $1.exe.
  31. #
  32. # Note: On Cygwin and DJGPP, `test -x' also looks for .exe. On Cygwin,
  33. # also `test -f' has this enhancement, but not on DJGPP. (Both are
  34. # design decisions, so there is little chance to make them consistent.)
  35. # Thusly, it seems to be difficult to make use of these enhancements.
  36. #
  37. if { test -f "$dir/$1" && test -x "$dir/$1"; } \
  38. || { test -f "$dir/$1.exe" && test -x "$dir/$1.exe"; }; then
  39. return 0
  40. fi
  41. done
  42. return 1
  43. }
  44. #
  45. # Avoid ginfo complaining that terminal is too dumb
  46. TERM=vt100; export TERM
  47. FINISHEDFIFO=t/`basename $0.finished`
  48. # See cleanup in Init-test.inc.
  49. findprog stty && { STTY=stty ; reset_required=yes ; }
  50. test $reset_required=yes && { $STTY | grep [-]echo ; } && reset_required=no
  51. # Create named pipes to communicate with pseudotty program, or quit.
  52. rm -f $PIPEIN $PTY_TYPE # must already be defined
  53. if findprog mkfifo; then
  54. mkfifo $PIPEIN
  55. mkfifo $PTY_TYPE
  56. #
  57. if test ! -r $PIPEIN || test ! -r $PTY_TYPE; then
  58. echo "$0: could not mkfifo pipes" >&2
  59. exit 77
  60. fi
  61. # ok, we'll proceed with the test.
  62. else
  63. echo "$0: mkfifo program not found - cannot make named pipes" >&2
  64. exit 77
  65. fi
  66. # We can feed input bytes into $PTY_TYPE to be passed onto ginfo, as
  67. # if they were typed by a user in an interactive session.
  68. # We redirect to the FIFO within a subshell, because under NetBSD 6.1.4
  69. # it hangs otherwise.
  70. (exec ./pseudotty "$PTY_TYPE" >$PIPEIN) &
  71. PTY_PID=$!
  72. # Get name of pseudo-terminal slave device
  73. read PTS_DEVICE <$PIPEIN
  74. # Keeping the FIFO open for writing prevents the select call in
  75. # pseudotty returning EOF after a single "printf something >$PTY_TYPE".
  76. exec 7>$PTY_TYPE
  77. # glibc can kill a running process if it detects a condition like a
  78. # double free. This specifies that the message it prints when it does
  79. # this should be sent to stderr so it can be recorded in the test *.log
  80. # files.
  81. LIBC_FATAL_STDERR_=1; export LIBC_FATAL_STDERR
  82. run_ginfo ()
  83. {
  84. rm -f $FINISHEDFIFO
  85. mkfifo $FINISHEDFIFO
  86. { # Close fd opened to control FIFO in subshell so pseudotty can exit
  87. # for an EOF. This prevents lingering processes if a test is
  88. # interrupted.
  89. exec 7>&- ;
  90. exec 8>$FINISHEDFIFO ;
  91. $GINFO $GINFO_OPTIONS "$@" ;
  92. test $? -eq 0 || echo failure >$FINISHEDFIFO ;
  93. echo finished >$FINISHEDFIFO ; } 0<>$PTS_DEVICE 1<&0 &
  94. SUBSHELL=$!
  95. exec 8<$FINISHEDFIFO
  96. # Although we don't write to the FIFO in this process, we still need
  97. # to open it for writing, because if the above subshell exits before
  98. # we read from it, we won't be able to open it - even though
  99. # "finished" is buffered.
  100. exec 9>$FINISHEDFIFO
  101. # Check for pgrep
  102. if findprog pgrep; then
  103. # Get the PID of the running ginfo process. Look for a process called
  104. # "ginfo" whose parent process is the subshell executed by the previous
  105. # command.
  106. echo 'Fetching PID of ginfo process under test...' >&2
  107. GINFO_PID=
  108. # Try 3 times and then give up. The process may never have started,
  109. # have started under a different name, or have already exited.
  110. for i in 1 2 3; do
  111. GINFO_PID=`pgrep -P $SUBSHELL $GINFO_NAME ; \
  112. test $? -eq 0 || test $? -eq 1 || exit 99`
  113. # This use of pgrep is likely not portable (works on procps).
  114. # Check if it is likely to have worked.
  115. # Exit status was anything other than 0 or 1
  116. test $? -eq 99 && { GINFO_PID=unknown; break; }
  117. # More than one line in output
  118. echo $GINFO_PID | wc -l | grep '^0$\|^1$' >/dev/null \
  119. || { GINFO_PID=unknown; break; }
  120. # Non-numeral characters present
  121. echo $GINFO_PID | grep -v '^[0-9]*$' >/dev/null
  122. test $? -eq 0 && { GINFO_PID=unknown; break; }
  123. GINFO_PID=`echo $GINFO_PID | tr -d '\n'`
  124. test "$GINFO_PID" = "" || break
  125. sleep 1 # Give subshell time to spawn ginfo process
  126. done
  127. test "$GINFO_PID" = "" && GINFO_PID=unknown
  128. echo ...$GINFO_PID >&2
  129. else
  130. echo 'pgrep program not found - cannot get PID of ginfo process' >&2
  131. GINFO_PID=unknown
  132. fi
  133. }