diff --git a/CHANGES b/CHANGES index bcee6cc..c465073 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,11 @@ corrections: Test: EXEC_NOFORK_UNIDIR Thanks to David Reiss for reporting this problem. + Socat exited with status 0 even when a program invoked with SYSTEM or + EXEC failed. + Tests: SYSTEM_RC EXEC_RC + Issue reported by Felix Winkelmann. + porting: Type conflict between int and sig_atomic_t between declaration and definition of diag_immediate_type and diag_immediate_exit broke diff --git a/test.sh b/test.sh index 66c4995..45d0646 100755 --- a/test.sh +++ b/test.sh @@ -12205,7 +12205,8 @@ N=$((N+1)) done -# test if option fdout in write only context issues an error +# Address options fdin and fdout were silently ignored when not applicable +# due to -u or -U option. Now these combinations are caught as errors. NAME=FDOUT_ERROR case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) @@ -12238,6 +12239,72 @@ PORT=$((PORT+1)) N=$((N+1)) +# test if failure exit code of SYSTEM invocation causes socat to also exit +# with !=0 +NAME=SYSTEM_RC +case "$TESTS" in +*%$N%*|*%functions%*|*%system%*|*%$NAME%*) +TEST="$NAME: promote failure of SYSTEM" +# run socat with SYSTEM:false and check if socat exits with !=0 +if ! eval $NUMCOND; then :; else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$TRACE $SOCAT $opts /dev/null SYSTEM:false" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" +rc0=$? +if [ $rc0 -eq 0 ]; then + $PRINTF "$FAILED\n" + echo "$CMD0" + cat "${te}0" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +else + $PRINTF "$OK\n" + numOK=$((numOK+1)) +fi +fi # NUMCOND + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + +# test if failure exit code of EXEC invocation causes socat to also exit +# with !=0 +NAME=EXEC_RC +case "$TESTS" in +*%$N%*|*%functions%*|*%exec%*|*%$NAME%*) +TEST="$NAME: promote failure of EXEC" +# run socat with EXEC:false and check if socat exits with !=0 +if ! eval $NUMCOND; then :; else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$TRACE $SOCAT $opts EXEC:false /dev/null" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" +rc0=$? +if [ $rc0 -eq 0 ]; then + $PRINTF "$FAILED\n" + echo "$CMD0" + cat "${te}0" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +else + $PRINTF "$OK\n" + numOK=$((numOK+1)) +fi +fi # NUMCOND + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + # test the so-reuseaddr option NAME=SO_REUSEADDR case "$TESTS" in diff --git a/xio-system.c b/xio-system.c index 92b7b67..d232ec3 100644 --- a/xio-system.c +++ b/xio-system.c @@ -61,12 +61,14 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts, Dup2(duptostderr, 2); } Info1("executing shell command \"%s\"", string); + errno=0; result = System(string); if (result != 0) { Warn2("system(\"%s\") returned with status %d", string, result); - Warn1("system(): %s", strerror(errno)); + if (errno != 0) + Warn1("system(): %s", strerror(errno)); } - Exit(0); /* this child process */ + Exit(result>>8); /* this child process */ } /* parent */ diff --git a/xiosigchld.c b/xiosigchld.c index a92a87a..8edb25c 100644 --- a/xiosigchld.c +++ b/xiosigchld.c @@ -130,12 +130,22 @@ void childdied(int signum) { Info2("waitpid(): child %d exited with status %d", pid, WEXITSTATUS(status)); } else { - Warn2("waitpid(): child %d exited with status %d", - pid, WEXITSTATUS(status)); + if (i == XIO_MAXSOCK) { + Info2("waitpid(): child %d exited with status %d", + pid, WEXITSTATUS(status)); + } else { + Error2("waitpid(): child %d exited with status %d", + pid, WEXITSTATUS(status)); + } } } else if (WIFSIGNALED(status)) { - Info2("waitpid(): child %d exited on signal %d", - pid, WTERMSIG(status)); + if (i == XIO_MAXSOCK) { + Info2("waitpid(): child %d exited on signal %d", + pid, WTERMSIG(status)); + } else { + Error2("waitpid(): child %d exited on signal %d", + pid, WTERMSIG(status)); + } } else if (WIFSTOPPED(status)) { Info2("waitpid(): child %d stopped on signal %d", pid, WSTOPSIG(status));