when UNIX-LISTEN was applied to an existing file it failed as expected but removed the file

This commit is contained in:
Gerhard Rieger 2010-10-03 16:28:06 +02:00
parent 4c3d1ca49d
commit cb913fbc0c
4 changed files with 51 additions and 15 deletions

View file

@ -1,5 +1,9 @@
corrections: corrections:
when UNIX-LISTEN was applied to an existing file it failed as expected
but removed the file. Thanks to Bjoern Bosselmann for reporting this
problem
fixed a bug where socat might crash when connecting to a unix domain fixed a bug where socat might crash when connecting to a unix domain
socket using address GOPEN. Thanks to Martin Forssen for bug report and socket using address GOPEN. Thanks to Martin Forssen for bug report and
patch. patch.

32
test.sh
View file

@ -10297,7 +10297,37 @@ fi # NUMCOND
;; ;;
esac esac
N=$((N+1)) N=$((N+1))
set +vx
# test if socat keeps an existing file where it wanted to create a UNIX socket
NAME=UNIXLISTEN_KEEPFILE
case "$TESTS" in
*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*)
TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socket"
# we create a file and start socat with UNIX-LISTEN on this file. expected
# behaviour: socat exits immediately with error, but keeps the file
# up to 1.7.1.3, it removed the file
if ! eval $NUMCOND; then :; else
tf="$td/test$N.file"
te="$td/test$N.stderr"
CMD0="$SOCAT $opts -u UNIX-LISTEN:$tf /dev/null"
printf "test $F_n $TEST... " $N
rm -f "$tf"; touch "$tf"
$CMD0 >/dev/null 2>"${te}0"
rc0=$?
if [ $rc0 -ne 0 -a -f "$tf" ]; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0"
cat "${te}0"
numFAIL=$((numFAIL+1))
fi
fi # NUMCOND
;;
esac
N=$((N+1))
############################################################################### ###############################################################################

View file

@ -1,5 +1,5 @@
/* source: xio-listen.c */ /* source: xio-listen.c */
/* Copyright Gerhard Rieger 2001-2009 */ /* Copyright Gerhard Rieger 2001-2010 */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for listen socket options */ /* this file contains the source for listen socket options */
@ -299,12 +299,6 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
level = E_ERROR; level = E_ERROR;
#endif /* WITH_RETRY */ #endif /* WITH_RETRY */
#if WITH_UNIX
/* with UNIX sockets: only listening parent is allowed to remove
the socket file */
xfd->opt_unlink_close = false;
#endif /* WITH_UNIX */
break; break;
} }

View file

@ -1,5 +1,5 @@
/* source: xio-unix.c */ /* source: xio-unix.c */
/* Copyright Gerhard Rieger 2001-2009 */ /* Copyright Gerhard Rieger 2001-2010 */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of UNIX socket type */ /* this file contains the source for opening addresses of UNIX socket type */
@ -126,6 +126,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
socklen_t uslen; socklen_t uslen;
bool tight = true; bool tight = true;
struct opt *opts0 = NULL; struct opt *opts0 = NULL;
pid_t pid = Getpid();
bool opt_unlink_early = false; bool opt_unlink_early = false;
bool opt_unlink_close = true; bool opt_unlink_close = true;
int result; int result;
@ -147,12 +148,6 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
/* only for non abstract because abstract do not work in file system */ /* only for non abstract because abstract do not work in file system */
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
if (opt_unlink_close) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
}
} }
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
@ -183,6 +178,19 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
opts, opts0, pf, socktype, protocol)) opts, opts0, pf, socktype, protocol))
!= 0) != 0)
return result; return result;
/* we set this option as late as now because we should not remove an
existing entry when bind() failed */
if (!(ABSTRACT && abstract)) {
if (opt_unlink_close) {
if (pid == Getpid()) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
}
}
}
return 0; return 0;
} }
#endif /* WITH_LISTEN */ #endif /* WITH_LISTEN */