mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
some file system bases addresses failed to apply file options
This commit is contained in:
parent
a793c8047e
commit
ab74be65e5
5 changed files with 409 additions and 22 deletions
5
CHANGES
5
CHANGES
|
@ -48,6 +48,11 @@ corrections:
|
|||
fixed some typos and minor issues, including:
|
||||
Red Hat issue 1021967: formatting error in manual page
|
||||
|
||||
UNIX-LISTEN with fork option did not remove the socket file system entry
|
||||
when exiting. Other file system based passive address types had similar
|
||||
issues or failed to apply options umask, user e.a.
|
||||
Thanks to Lorenzo Monti for pointing me to this issue
|
||||
|
||||
porting:
|
||||
Performed changes for Fedora release 19
|
||||
|
||||
|
|
351
test.sh
351
test.sh
|
@ -52,7 +52,7 @@ esac
|
|||
#SOCAT_EGD="egd=/dev/egd-pool"
|
||||
MISCDELAY=1
|
||||
[ -z "$SOCAT" ] && SOCAT="./socat"
|
||||
if [ ! -x "$SOCAT" ]; then
|
||||
if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then
|
||||
echo "$SOCAT does not exist" >&2; exit 1;
|
||||
fi
|
||||
[ -z "$PROCAN" ] && PROCAN="./procan"
|
||||
|
@ -11302,6 +11302,355 @@ N=$((N+1))
|
|||
|
||||
|
||||
###############################################################################
|
||||
# tests: option umask with "passive" NAMED group addresses
|
||||
while read addr fileopt addropts proto diropt ADDR2; do
|
||||
if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
|
||||
# some passive (listening...) filesystem based addresses did not implement the
|
||||
# umask option
|
||||
ADDR=${addr^^*}
|
||||
ADDR_=${ADDR/-/_}
|
||||
PROTO=${proto^^*}
|
||||
if [ "$diropt" = "." ]; then diropt=; fi
|
||||
if [ "$fileopt" = "." ]; then fileopt=; fi
|
||||
if [ "$addropts" = "." ]; then addropts=; fi
|
||||
NAME=${ADDR_}_UMASK
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%$NAME%*)
|
||||
TEST="$NAME: $ADDR applies option umask"
|
||||
# start a socat process with passive/listening file system entry. Check the
|
||||
# permissions of the FS entry, then terminate the process.
|
||||
# Test succeeds when FS entry exists and has expected permissions.
|
||||
if ! eval $NUMCOND; then :; else
|
||||
if [ $ADDR = PTY ]; then set -xv; fi
|
||||
tlog="$td/test$N.log"
|
||||
te0="$td/test$N.0.stderr"
|
||||
tsock="$td/test$N.sock"
|
||||
if [ -z "$fileopt" ]; then
|
||||
CMD0="$SOCAT $opts $diropt $ADDR:$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
|
||||
else
|
||||
CMD0="$SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
|
||||
fi
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"$te0" &
|
||||
pid0=$!
|
||||
wait${proto} $tsock 1 2>"$tlog"
|
||||
ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
|
||||
perms=$(stat -L --print "%a\n" "$tsock" 2>/dev/null)
|
||||
kill $pid0 2>>"$tlog"
|
||||
wait
|
||||
if [ "$ERRNOENT" ]; then
|
||||
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numFAIL=numFAIL+1
|
||||
elif [ "$perms" != "600" ]; then
|
||||
$PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
let numFAIL=numFAIL+1
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
let numOK=numOK+1
|
||||
fi
|
||||
set +xv
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
# address fileopt addropts waitfor direction ADDR2
|
||||
create . . file -U FILE:/dev/null
|
||||
open . creat file . FILE:/dev/null
|
||||
gopen . creat file . FILE:/dev/null
|
||||
unix-listen . . unixport . FILE:/dev/null
|
||||
unix-recvfrom . . unixport . FILE:/dev/null
|
||||
unix-recv . . unixport -u FILE:/dev/null
|
||||
pipe . . file -u FILE:/dev/null
|
||||
# pty does not seem to honor umask:
|
||||
#pty link . file . PIPE
|
||||
"
|
||||
|
||||
|
||||
# tests: option perm with "passive" NAMED group addresses
|
||||
while read addr fileopt addropts proto diropt; do
|
||||
if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
|
||||
# test if passive (listening...) filesystem based addresses implement option perm
|
||||
ADDR=${addr^^*}
|
||||
ADDR_=${ADDR/-/_}
|
||||
PROTO=${proto^^*}
|
||||
if [ "$diropt" = "." ]; then diropt=; fi
|
||||
if [ "$fileopt" = "." ]; then fileopt=; fi
|
||||
if [ "$addropts" = "." ]; then addropts=; fi
|
||||
NAME=${ADDR_}_PERM
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%$NAME%*)
|
||||
TEST="$NAME: $ADDR applies option perm"
|
||||
# start a socat process with passive/listening file system entry. Check the
|
||||
# permissions of the FS entry, then terminate the process.
|
||||
# Test succeeds when FS entry exists and has expected permissions.
|
||||
if ! eval $NUMCOND; then :; else
|
||||
tlog="$td/test$N.log"
|
||||
te0="$td/test$N.0.stderr"
|
||||
tsock="$td/test$N.sock"
|
||||
# set -vx
|
||||
if [ -z "$fileopt" ]; then
|
||||
CMD0="$SOCAT $opts $diropt $ADDR:$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
|
||||
else
|
||||
CMD0="$SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
|
||||
fi
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"$te0" &
|
||||
pid0=$!
|
||||
wait${proto} $tsock 1 2>"$tlog"
|
||||
ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
|
||||
perms=$(stat -L --print "%a\n" "$tsock" 2>/dev/null)
|
||||
kill $pid0 2>>"$tlog"
|
||||
wait
|
||||
if [ "$ERRNOENT" ]; then
|
||||
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numFAIL=numFAIL+1
|
||||
elif [ "$perms" != "511" ]; then
|
||||
$PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
let numFAIL=numFAIL+1
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
let numOK=numOK+1
|
||||
fi
|
||||
set +vx
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
# address fileopt addropts waitfor direction
|
||||
create . . file -U
|
||||
open . creat file .
|
||||
gopen . creat file .
|
||||
unix-listen . . unixport .
|
||||
unix-recvfrom . . unixport .
|
||||
unix-recv . . unixport -u
|
||||
pipe . . file -u
|
||||
pty link . file .
|
||||
"
|
||||
|
||||
|
||||
# tests: option user with "passive" NAMED group addresses
|
||||
while read addr fileopt addropts proto diropt; do
|
||||
if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
|
||||
# test if passive (listening...) filesystem based addresses implement option user
|
||||
ADDR=${addr^^*}
|
||||
ADDR_=${ADDR/-/_}
|
||||
PROTO=${proto^^*}
|
||||
if [ "$diropt" = "." ]; then diropt=; fi
|
||||
if [ "$fileopt" = "." ]; then fileopt=; fi
|
||||
if [ "$addropts" = "." ]; then addropts=; fi
|
||||
NAME=${ADDR_}_USER
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%root%*|*%$NAME%*)
|
||||
TEST="$NAME: $ADDR applies option user"
|
||||
# start a socat process with passive/listening file system entry with user option.
|
||||
# Check the owner of the FS entry, then terminate the process.
|
||||
# Test succeeds when FS entry exists and has expected owner.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
else
|
||||
tlog="$td/test$N.log"
|
||||
te0="$td/test$N.0.stderr"
|
||||
tsock="$td/test$N.sock"
|
||||
# set -vx
|
||||
if [ -z "$fileopt" ]; then
|
||||
CMD0="$SOCAT $opts $diropt $ADDR:$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
|
||||
else
|
||||
CMD0="$SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
|
||||
fi
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"$te0" &
|
||||
pid0=$!
|
||||
wait${proto} $tsock 1 2>"$tlog"
|
||||
ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
|
||||
user=$(stat -L --print "%U\n" "$tsock" 2>/dev/null)
|
||||
kill $pid0 2>>"$tlog"
|
||||
wait
|
||||
if [ "$ERRNOENT" ]; then
|
||||
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numFAIL=numFAIL+1
|
||||
elif [ "$user" != "$SUBSTUSER" ]; then
|
||||
$PRINTF "${RED}user \"$user\", expected \"$SUBSTUSER\" ${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
let numFAIL=numFAIL+1
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
let numOK=numOK+1
|
||||
fi
|
||||
set +vx
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
# address fileopt addropts waitfor direction
|
||||
create . . file -U
|
||||
open . creat file .
|
||||
gopen . creat file .
|
||||
unix-listen . . unixport .
|
||||
unix-recvfrom . . unixport .
|
||||
unix-recv . . unixport -u
|
||||
pipe . . file -u
|
||||
pty link . file .
|
||||
"
|
||||
|
||||
|
||||
# tests: is "passive" filesystem entry removed at the end? (without fork)
|
||||
while read addr fileopt addropts proto diropt crit ADDR2; do
|
||||
if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
|
||||
# some passive (listening...) filesystem based addresses did not remove the file
|
||||
# system entry at the end
|
||||
ADDR=${addr^^*}
|
||||
ADDR_=${ADDR/-/_}
|
||||
PROTO=${proto^^*}
|
||||
if [ "$diropt" = "." ]; then diropt=; fi
|
||||
if [ "$fileopt" = "." ]; then fileopt=; fi
|
||||
if [ "$addropts" = "." ]; then addropts=; fi
|
||||
# $ADDR removes the file system entry when the process is terminated
|
||||
NAME=${ADDR_}_REMOVE
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*)
|
||||
TEST="$NAME: $ADDR removes socket entry when terminated during accept"
|
||||
# start a socat process with listening unix domain socket etc. Terminate the
|
||||
# process and check if the file system socket entry still exists.
|
||||
# Test succeeds when entry does not exist.
|
||||
if ! eval $NUMCOND; then :; else
|
||||
tlog="$td/test$N.log"
|
||||
te0="$td/test$N.0.stderr"
|
||||
tsock="$td/test$N.sock"
|
||||
if [ -z "$fileopt" ]; then
|
||||
CMD0="$SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2"
|
||||
else
|
||||
CMD0="$SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2"
|
||||
fi
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"$te0" &
|
||||
pid0=$!
|
||||
wait${proto} "$crit" $tsock 1 2>"$tlog"
|
||||
kill $pid0 2>>"$tlog"
|
||||
rc1=$?
|
||||
wait >>"$tlog"
|
||||
if [ $rc1 != 0 ]; then
|
||||
$PRINTF "${YELLOW}setup failed${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numCANT=numCANT+1
|
||||
elif ! [ $crit $tsock ]; then
|
||||
$PRINTF "$OK\n"
|
||||
let numOK=numOK+1
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numFAIL=numFAIL+1
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
# address fileopt addropts waitfor direction crit ADDR2
|
||||
unix-listen . . unixport . -e FILE:/dev/null
|
||||
unix-recvfrom . . unixport . -e FILE:/dev/null
|
||||
unix-recv . . unixport -u -e FILE:/dev/null
|
||||
pipe . . file -u -e FILE:/dev/null
|
||||
pty link . file . -L PIPE
|
||||
"
|
||||
|
||||
|
||||
# tests: is "passive" filesystem entry removed at the end? (with fork)
|
||||
while read addr fileopt addropts proto diropt crit ADDR2; do
|
||||
if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
|
||||
# some passive (listening...) filesystem based addresses with fork did not remove
|
||||
# the file system entry at the end
|
||||
ADDR=${addr^^*}
|
||||
ADDR_=${ADDR/-/_}
|
||||
PROTO=${proto^^*}
|
||||
if [ "$diropt" = "." ]; then diropt=; fi
|
||||
if [ "$fileopt" = "." ]; then fileopt=; fi
|
||||
if [ "$addropts" = "." ]; then addropts=; fi
|
||||
# $ADDR with fork removes the file system entry when the process is terminated
|
||||
NAME=${ADDR_}_REMOVE_FORK
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*)
|
||||
TEST="$NAME: $ADDR with fork removes socket entry when terminated during accept"
|
||||
# start a socat process with listening unix domain socket etc and option fork.
|
||||
# Terminate the process and check if the file system socket entry still exists.
|
||||
# Test succeeds when entry does not exist.
|
||||
if ! eval $NUMCOND; then :; else
|
||||
tlog="$td/test$N.log"
|
||||
te0="$td/test$N.0.stderr"
|
||||
tsock="$td/test$N.sock"
|
||||
if [ -z "$fileopt" ]; then
|
||||
CMD0="$SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2"
|
||||
else
|
||||
CMD0="$SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2"
|
||||
fi
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"$te0" &
|
||||
pid0=$!
|
||||
wait${proto} "$crit" $tsock 1 2>"$tlog"
|
||||
kill $pid0 2>>"$tlog"
|
||||
rc1=$?
|
||||
wait
|
||||
if [ $rc1 != 0 ]; then
|
||||
$PRINTF "${YELLOW}setup failed${NORMAL}\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numCANT=numCANT+1
|
||||
elif ! [ $crit $tsock ]; then
|
||||
$PRINTF "$OK\n"
|
||||
let numOK=numOK+1
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "$te0"
|
||||
cat "$tlog"
|
||||
let numFAIL=numFAIL+1
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
# address fileopt addropts waitfor direction crit ADDR2
|
||||
unix-listen . . unixport . -e FILE:/dev/null
|
||||
unix-recvfrom . . unixport . -e FILE:/dev/null
|
||||
"
|
||||
|
||||
|
||||
##################################################################################
|
||||
#=================================================================================
|
||||
# here come tests that might affect your systems integrity. Put normal tests
|
||||
# before this paragraph.
|
||||
# tests must be explicitely selected by roottough or name (not number)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: xio-named.c */
|
||||
/* Copyright Gerhard Rieger 2001-2011 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file contains the source for filesystem entry functions */
|
||||
|
@ -24,7 +24,7 @@ const struct optdesc opt_unlink_close = { "unlink-close", NULL, OPT_UNLINK_CLOS
|
|||
const struct optdesc opt_umask = { "umask", NULL, OPT_UMASK, GROUP_NAMED, PH_EARLY, TYPE_MODET, OFUNC_SPEC };
|
||||
#endif /* WITH_NAMED */
|
||||
|
||||
/* applies to fd all options belonging to phase */
|
||||
/* applies to filesystem entry all options belonging to phase */
|
||||
int applyopts_named(const char *filename, struct opt *opts, unsigned int phase) {
|
||||
struct opt *opt;
|
||||
|
||||
|
@ -137,8 +137,8 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
|||
}
|
||||
}
|
||||
|
||||
applyopts(-1, opts, PH_EARLY);
|
||||
applyopts_named(path, opts, PH_EARLY);
|
||||
applyopts(-1, opts, PH_EARLY);
|
||||
if (*exists) {
|
||||
applyopts_named(path, opts, PH_PREOPEN);
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: xio-pipe.c */
|
||||
/* Copyright Gerhard Rieger 2001-2008 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file contains the source for opening addresses of pipe type */
|
||||
|
@ -100,6 +100,7 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
|
|||
applyopts(-1, opts, PH_INIT);
|
||||
|
||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||
applyopts_named(pipename, opts, PH_EARLY); /* umask! */
|
||||
applyopts(-1, opts, PH_EARLY);
|
||||
|
||||
if (opt_unlink_early) {
|
||||
|
@ -146,6 +147,8 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
|
|||
}
|
||||
#endif
|
||||
Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]);
|
||||
applyopts_named(pipename, opts, PH_ALL);
|
||||
|
||||
}
|
||||
if (opt_unlink_close) {
|
||||
if ((fd->stream.unlink_close = strdup(pipename)) == NULL) {
|
||||
|
|
64
xio-unix.c
64
xio-unix.c
|
@ -152,6 +152,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||
|
||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||
applyopts(-1, opts, PH_INIT);
|
||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||
applyopts(-1, opts, PH_EARLY);
|
||||
|
||||
if (!(ABSTRACT && abstract)) {
|
||||
|
@ -163,15 +164,27 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct stat buf;
|
||||
if (Lstat(name, &buf) == 0) {
|
||||
Error1("\"%s\" exists", name);
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
}
|
||||
if (opt_unlink_close) {
|
||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||
Error1("strdup(\"%s\"): out of memory", name);
|
||||
}
|
||||
xfd->opt_unlink_close = true;
|
||||
}
|
||||
|
||||
/* trying to set user-early, perm-early etc. here is useless because
|
||||
file system entry is available only past bind() call. */
|
||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||
}
|
||||
|
||||
opts0 = copyopts(opts, GROUP_ALL);
|
||||
|
||||
/* this may fork() */
|
||||
if ((result =
|
||||
xioopen_listen(xfd, xioflags,
|
||||
(struct sockaddr *)&us, uslen,
|
||||
|
@ -179,18 +192,15 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||
!= 0)
|
||||
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;
|
||||
if (pid != Getpid()) {
|
||||
/* in a child process - do not unlink-close here! */
|
||||
xfd->opt_unlink_close = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_LISTEN */
|
||||
|
@ -347,13 +357,9 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|||
/* 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_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 (!(ABSTRACT && abstract)) {
|
||||
if (opt_unlink_early) {
|
||||
if (Unlink(name) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
|
@ -362,12 +368,30 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct stat buf;
|
||||
if (Lstat(name, &buf) == 0) {
|
||||
Error1("\"%s\" exists", name);
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
}
|
||||
if (opt_unlink_close) {
|
||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||
Error1("strdup(\"%s\"): out of memory", name);
|
||||
}
|
||||
xfd->opt_unlink_close = true;
|
||||
}
|
||||
|
||||
/* trying to set user-early, perm-early etc. here is useless because
|
||||
file system entry is available only past bind() call. */
|
||||
}
|
||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||
|
||||
xfd->para.socket.la.soa.sa_family = pf;
|
||||
|
||||
xfd->dtype = XIODATA_RECVFROM_ONE;
|
||||
|
||||
/* this may fork */
|
||||
return
|
||||
_xioopen_dgram_recvfrom(xfd, xioflags,
|
||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||
|
@ -410,6 +434,8 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
|||
if (!(ABSTRACT && abstract)) {
|
||||
/* 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_CLOSE, &opt_unlink_close);
|
||||
|
||||
if (opt_unlink_early) {
|
||||
if (Unlink(name) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
|
@ -418,10 +444,13 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
|||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct stat buf;
|
||||
if (Lstat(name, &buf) == 0) {
|
||||
Error1("\"%s\" exists", name);
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -429,6 +458,7 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
|||
xfd->opt_unlink_close = true;
|
||||
}
|
||||
}
|
||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||
|
||||
xfd->para.socket.la.soa.sa_family = pf;
|
||||
|
||||
|
|
Loading…
Reference in a new issue