From d355da98bcb02c263edaddf08fb3be6e4df0e778 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 25 Feb 2023 15:40:09 +0100 Subject: [PATCH] Fixed restore of STDIO tty on Solaris --- CHANGES | 5 ++++ test.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++++--- xioclose.c | 2 +- xioshutdown.c | 2 +- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index b93e78b..57576a7 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,11 @@ Corrections: Option stderr on addresses EXEC and SYSTEM uses a temporary FD. It lacked the FD_CLOEXEC setting and thus leakt into child processes. + Restoring of STDIO tty settings failed on Solaris type operating + systems. + Thanks to Gordon W.Ross for reporting and fixing this issue. + Test: RESTORE_TTY + Features: VSOCK, VSOCK-L support options pf, socktype, prototype (currently useless) diff --git a/test.sh b/test.sh index 3358f5d..970649a 100755 --- a/test.sh +++ b/test.sh @@ -4210,11 +4210,20 @@ N=$((N+1)) NAME=CHILDDEFAULT case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) -if ! eval $NUMCOND; then :; else +if ! eval $NUMCOND; then : +elif ! a=$(testfeats STDIO EXEC); then + $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! a=$(testaddrs STDIO EXEC); then + $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +else TEST="$NAME: child process default properties" tf="$td/test$N.stdout" te="$td/test$N.stderr" -CMD="$TRACE $SOCAT $opts -u exec:$PROCAN -" +CMD="$TRACE $SOCAT $opts -u EXEC:$PROCAN -" printf "test $F_n $TEST... " $N $CMD >$tf 2>$te MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` @@ -4227,12 +4236,14 @@ if [ "$MYPID" = "$MYPPID" -o "$MYPID" = "$MYPGID" -o "$MYPID" = "$MYSID" -o \ then $PRINTF "$FAILED:\n" echo "$CMD" - cat "$te" + cat "$te" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" - numOK=$((numOK+1)) + if [ "$VERBOSE" ]; then echo "$CMD"; fi + if [ "$DEBUG" ]; then cat "${te}" >&2; fi + numOK=$((numOK+1)) fi fi ;; # NUMCOND esac @@ -15839,6 +15850,67 @@ esac PORT=$((PORT+1)) N=$((N+1)) + +# Test if the settings of the terminal that Socat is invoked in are restored +# on termination. +# This failed on Open-Solaris family OSes up to 1.7.4.4 +NAME=RESTORE_TTY +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%termios%*|*%tty%*|*%$NAME%*) +TEST="$NAME: Restoring of terminal settings" +# With an outer Socat command create a new pty and a bash in it. +# In this bash store the current terminal settings, then invoke a temporary +# inner Socat command that changes the term to raw mode and terminates. +# When the terminal settings afterwards are the same as before the call the +# test succeeded. +if ! eval $NUMCOND; then : +elif ! $(type stty >/dev/null 2>&1); then + $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then + $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then + $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +else +te="$td/test$N.stderr" +tx0="$td/test$N.stty0" +tx1="$td/test$N.stty1" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD="$TRACE $SOCAT $opts -lp outersocat - SYSTEM:\"stty\ >$tx0;\ $SOCAT\ -\,cfmakeraw\ /dev/nul\l >${te};\ stty\ >$tx1\",pty,setsid,ctty,stderr" +printf "test $F_n $TEST... " $N +eval "$CMD" >/dev/null 2>${te}.outer +rc=$? +if diff $tx0 $tx1 >$tdiff 2>&1; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD &"; fi + if [ "$DEBUG" ]; then cat "${te}" >&2; fi + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD" + cat "${te}" >&2 + cat "${te}.outer" >&2 + cat $tdiff >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +fi +fi # NUMCOND + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + # end of common tests ################################################################################## diff --git a/xioclose.c b/xioclose.c index d2922f1..ee5473d 100644 --- a/xioclose.c +++ b/xioclose.c @@ -44,7 +44,7 @@ int xioclose1(struct single *pipe) { #endif /* WITH_OPENSSL */ #if WITH_TERMIOS if (pipe->ttyvalid) { - if (Tcsetattr(pipe->fd, 0, &pipe->savetty) < 0) { + if (Tcsetattr(pipe->fd, TCSANOW, &pipe->savetty) < 0) { Warn2("cannot restore terminal settings on fd %d: %s", pipe->fd, strerror(errno)); } diff --git a/xioshutdown.c b/xioshutdown.c index c9fef8d..041d4ed 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -164,7 +164,7 @@ int xioshutdown(xiofile_t *sock, int how) { } #if WITH_TERMIOS if (sock->stream.ttyvalid) { - if (Tcsetattr(sock->stream.fd, 0, &sock->stream.savetty) < 0) { + if (Tcsetattr(sock->stream.fd, TCSAFLUSH, &sock->stream.savetty) < 0) { Warn2("cannot restore terminal settings on fd %d: %s", sock->stream.fd, strerror(errno)); }