From 8fbff188e126908ee2320793ebfe69df80e707fe Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 1 Feb 2008 22:26:01 +0100 Subject: [PATCH] replaced FOPEN_MAX with FD_SETSIZE --- CHANGES | 4 ++++ VERSION | 2 +- socat.c | 14 +++++++------- test.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 778677a..cd27fab 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,10 @@ corrections: service name resolution failed due to byte order mistake (thanks to James Sainsbury for reporting this problem) + socat would hang when invoked with many file descriptors already opened + fix: replaced FOPEN_MAX with FD_SETSIZE + thanks to Daniel Lucq for reporting this problem. + corrected some print statements and variable names make uninstall did not uninstall procan diff --git a/VERSION b/VERSION index ccae800..e8ab444 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.0+execpty+servres" +"1.6.0.0+execpty+servres+fd_setsize" diff --git a/socat.c b/socat.c index 6e50a21..6971c25 100644 --- a/socat.c +++ b/socat.c @@ -1,5 +1,5 @@ /* source: socat.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the main source, including command line option parsing, general @@ -658,17 +658,17 @@ int childleftdata(xiofile_t *xfd) { /*0 FD_SET(XIO_GETRDFD(xfd), &expt);*/ } do { - retval = Select(FOPEN_MAX, &in, &out, &expt, &time0); + retval = Select(FD_SETSIZE, &in, &out, &expt, &time0); } while (retval < 0 && errno == EINTR); if (retval < 0) { #if HAVE_FDS_BITS Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s", - FOPEN_MAX, in.fds_bits[0], out.fds_bits[0], + FD_SETSIZE, in.fds_bits[0], out.fds_bits[0], expt.fds_bits[0], strerror(errno)); #else Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s", - FOPEN_MAX, in.__fds_bits[0], out.__fds_bits[0], + FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0], expt.__fds_bits[0], strerror(errno)); #endif return -1; @@ -835,7 +835,7 @@ int _socat(void) { FD_SET(XIO_GETWRFD(sock1), &out); } } - retval = Select(FOPEN_MAX, &in, &out, &expt, to); + retval = Select(FD_SETSIZE, &in, &out, &expt, to); _errno = errno; if (retval < 0 && errno == EINTR) { Info1("select(): %s", strerror(errno)); @@ -851,12 +851,12 @@ int _socat(void) { if (retval < 0) { #if HAVE_FDS_BITS Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s", - FOPEN_MAX, in.fds_bits[0], out.fds_bits[0], + FD_SETSIZE, in.fds_bits[0], out.fds_bits[0], expt.fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0, strerror(errno)); #else Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s", - FOPEN_MAX, in.__fds_bits[0], out.__fds_bits[0], + FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0], expt.__fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0, strerror(errno)); #endif diff --git a/test.sh b/test.sh index 26b2698..b94da93 100755 --- a/test.sh +++ b/test.sh @@ -7896,6 +7896,47 @@ esac N=$((N+1)) +# test: up to socat 1.6.0.0, the highest file descriptor supported in socats +# transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when +# socat was invoked with many file descriptors already opened. socat would +# just hang in the select() call. Thanks to Daniel Lucq for reporting this +# problem. +# FOPEN_MAX on different OS's: +# OS FOPEN_ ulimit ulimit FD_ +# MAX -H -n -S -n SETSIZE +# Linux 2.6: 16 1024 1024 1024 +# HP-UX 11.11: 60 2048 2048 2048 +# FreeBSD: 20 11095 11095 1024 +# Cygwin: 20 unlimit 256 64 +# AIX: 32767 65534 65534 +NAME=EXCEED_FOPEN_MAX +case "$TESTS" in +*%functions%*|*%maxfds%*|*%$NAME%*) +TEST="$NAME: more than FOPEN_MAX FDs in use" +# this test opens a number of FDs before socat is invoked. socat will have to +# allocate higher FD numbers and thus hang if it cannot handle them. +REDIR= +#set -vx +FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}') +if [ -z "$FOPEN_MAX" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N" + numCANT=$((numCANT+1)) +else +OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX +i=3; while [ "$i" -lt "$OPEN_FILES" ]; do + REDIR="$REDIR $i>&2" + i=$((i+1)) +done +#echo "$REDIR" +#testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 +#set -vx +eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T 1\"" 1 $REDIR +#set +vx +fi # could determine FOPEN_MAX +esac +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then