mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
fixed a bug where sub processes would become zombies because the master process caught SIGCHLD but did not wait()
This commit is contained in:
parent
1f5165b765
commit
3b3b004ff8
4 changed files with 84 additions and 1 deletions
5
CHANGES
5
CHANGES
|
@ -22,6 +22,11 @@ corrections:
|
|||
ABSTRACT-CONNECT, ABSTRACT-CLIENT, SOCKSA, SOCKS4A
|
||||
(thanks to Fernanda G Weiden for reporting this problem)
|
||||
|
||||
fixed a bug where sub processes would become zombies because the master
|
||||
process caught SIGCHLD but did not wait(). this affected addresses
|
||||
UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, ABSTRACT-RECVFROM
|
||||
(thanks to Evan Borgstrom for reporting this problem)
|
||||
|
||||
corrected some print statements and variable names
|
||||
|
||||
make uninstall did not uninstall procan
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
"1.6.0.0+execpty+servres+fd_setsize+udp_sigchld1"
|
||||
"1.6.0.0+execpty+servres+fd_setsize+udp_sigchld"
|
||||
|
|
50
test.sh
50
test.sh
|
@ -8029,6 +8029,56 @@ PORT=$((PORT+1))
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
# there was a bug with udp-recvfrom and fork: terminating sub processes became
|
||||
# zombies because the master process did caught SIGCHLD but did not wait()
|
||||
NAME=UDP4RECVFROM_SIGCHLD
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
|
||||
TEST="$NAME: test if UDP4-RECVFROM child becomes zombie"
|
||||
# idea: run a udp-recvfrom process with fork and -T. Sent it one packet, so a
|
||||
# sub process is forked off. Make some transfer and wait until the -T timeout
|
||||
# is over. Now check for the child process: if it is zombie the test failed.
|
||||
# Correct is that child process terminated
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
tsl=$PORT
|
||||
ts="$LOCALHOST:$tsl"
|
||||
da=$(date)
|
||||
CMD1="$SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE"
|
||||
CMD2="$SOCAT $opts - UDP4-SENDTO:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid1=$!
|
||||
waitudp4port $tsl 1
|
||||
echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
rc2=$?
|
||||
sleep 1
|
||||
#read -p ">"
|
||||
l="$(childprocess $pid1)"
|
||||
kill $pid1 2>/dev/null; wait
|
||||
if [ $rc2 -ne 0 ]; then
|
||||
$PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM
|
||||
numCANT=$((numCANT+1))
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAMM
|
||||
numCANT=$((numCANT+1))
|
||||
elif $(isdefunct "$l"); then
|
||||
$PRINTF "$FAILED: $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
echo "$CMD2"
|
||||
cat "${te}1" "${te}2"
|
||||
numFAIL=$((numFAIL+1))
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
|
||||
numOK=$((numOK+1))
|
||||
fi ;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
||||
|
||||
if [ "$numFAIL" -gt 0 ]; then
|
||||
|
|
28
xio-socket.c
28
xio-socket.c
|
@ -512,9 +512,37 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
|||
static pid_t xio_waitingfor;
|
||||
static bool xio_hashappened;
|
||||
void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) {
|
||||
pid_t pid;
|
||||
int _errno;
|
||||
int status = 0;
|
||||
bool wassig = false;
|
||||
Debug5("xiosigaction_hasread(%d, {%d,%d,%d,"F_pid"}, )",
|
||||
signum, siginfo->si_signo, siginfo->si_errno, siginfo->si_code,
|
||||
siginfo->si_pid);
|
||||
_errno = errno;
|
||||
do {
|
||||
pid = Waitpid(-1, &status, WNOHANG);
|
||||
if (pid == 0) {
|
||||
Msg(wassig?E_INFO:E_WARN,
|
||||
"waitpid(-1, {}, WNOHANG): no child has exited");
|
||||
Info("childdied() finished");
|
||||
errno = _errno;
|
||||
return;
|
||||
} else if (pid < 0 && errno == ECHILD) {
|
||||
Msg1(wassig?E_INFO:E_WARN,
|
||||
"waitpid(-1, {}, WNOHANG): %s", strerror(errno));
|
||||
Info("childdied() finished");
|
||||
errno = _errno;
|
||||
return;
|
||||
}
|
||||
wassig = true;
|
||||
if (pid < 0) {
|
||||
Warn2("waitpid(-1, {%d}, WNOHANG): %s", status, strerror(errno));
|
||||
Info("childdied() finished");
|
||||
errno = _errno;
|
||||
return;
|
||||
}
|
||||
} while (1);
|
||||
if (xio_waitingfor == siginfo->si_pid) {
|
||||
xio_hashappened = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue