mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
some file system based addresses failed to apply file options
This commit is contained in:
parent
df152fce75
commit
d123461127
5 changed files with 435 additions and 21 deletions
5
CHANGES
5
CHANGES
|
@ -44,6 +44,11 @@ corrections:
|
||||||
fixed some typos and minor issues, including:
|
fixed some typos and minor issues, including:
|
||||||
Red Hat issue 1021967: formatting error in manual page
|
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
|
||||||
|
|
||||||
fixed bug in xio-openssl.c that prevented error handling of bad number
|
fixed bug in xio-openssl.c that prevented error handling of bad number
|
||||||
of arguments, thanks to Paulik Tamas for reporting
|
of arguments, thanks to Paulik Tamas for reporting
|
||||||
|
|
||||||
|
|
378
test.sh
378
test.sh
|
@ -52,7 +52,7 @@ esac
|
||||||
#SOCAT_EGD="egd=/dev/egd-pool"
|
#SOCAT_EGD="egd=/dev/egd-pool"
|
||||||
MISCDELAY=1
|
MISCDELAY=1
|
||||||
[ -z "$SOCAT" ] && SOCAT="./socat"
|
[ -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;
|
echo "$SOCAT does not exist" >&2; exit 1;
|
||||||
fi
|
fi
|
||||||
[ -z "$PROCAN" ] && PROCAN="./procan"
|
[ -z "$PROCAN" ] && PROCAN="./procan"
|
||||||
|
@ -165,6 +165,27 @@ DragonFly) IFCONFIG=/sbin/ifconfig ;;
|
||||||
*) IFCONFIG=/sbin/ifconfig ;;
|
*) IFCONFIG=/sbin/ifconfig ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# need output like "644"
|
||||||
|
case "$UNAME" in
|
||||||
|
Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;;
|
||||||
|
FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;;
|
||||||
|
*) fileperms() {
|
||||||
|
local p s=0 c
|
||||||
|
p="$(ls -l -L "$1" |awk '{print($1);}')"
|
||||||
|
p="${p:1:9}"
|
||||||
|
while [ "$p" ]; do c=${p:0:1}; p=${p:1}; [ "x$c" == x- ]; let "s=2*s+$?"; done
|
||||||
|
printf "%03o\n" $s;
|
||||||
|
} ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# need user (owner) of filesystem entry
|
||||||
|
case "$UNAME" in
|
||||||
|
Linux) fileuser() { stat -L --print "%U\n" "$tsock" 2>/dev/null; } ;;
|
||||||
|
FreeBSD) fileuser() { ls -l test.sh |awk '{print($3);}'; } ;;
|
||||||
|
*) fileuser() { ls -l test.sh |awk '{print($3);}'; } ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
# for some tests we need a second local IPv4 address
|
# for some tests we need a second local IPv4 address
|
||||||
case "$UNAME" in
|
case "$UNAME" in
|
||||||
Linux)
|
Linux)
|
||||||
|
@ -11725,6 +11746,361 @@ PORT=$((PORT+1))
|
||||||
N=$((N+1))
|
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
|
||||||
|
*%$N%*|*%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=$(fileperms "$tsock")
|
||||||
|
kill $pid0 2>>"$tlog"
|
||||||
|
wait
|
||||||
|
if [ "$ERRNOENT" ]; then
|
||||||
|
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
cat "$tlog"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
elif [ "$perms" != "600" ]; then
|
||||||
|
$PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
let numOK=numOK+1
|
||||||
|
fi
|
||||||
|
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
|
||||||
|
*%$N%*|*%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=$(fileperms "$tsock")
|
||||||
|
kill $pid0 2>>"$tlog"
|
||||||
|
wait
|
||||||
|
if [ "$ERRNOENT" ]; then
|
||||||
|
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
cat "$tlog"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
elif [ "$perms" != "511" ]; then
|
||||||
|
$PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
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
|
||||||
|
*%$N%*|*%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=$(fileuser "$tsock")
|
||||||
|
kill $pid0 2>>"$tlog"
|
||||||
|
wait
|
||||||
|
if [ "$ERRNOENT" ]; then
|
||||||
|
$PRINTF "${RED}no entry${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
cat "$tlog"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
elif [ "$user" != "$SUBSTUSER" ]; then
|
||||||
|
$PRINTF "${RED}user \"$user\", expected \"$SUBSTUSER\" ${NORMAL}\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "$te0"
|
||||||
|
let numFAIL=numFAIL+1
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
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
|
||||||
|
*%$N%*|*%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
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
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
|
||||||
|
*%$N%*|*%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
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
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
|
# here come tests that might affect your systems integrity. Put normal tests
|
||||||
# before this paragraph.
|
# before this paragraph.
|
||||||
|
|
|
@ -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 };
|
const struct optdesc opt_umask = { "umask", NULL, OPT_UMASK, GROUP_NAMED, PH_EARLY, TYPE_MODET, OFUNC_SPEC };
|
||||||
#endif /* WITH_NAMED */
|
#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) {
|
int applyopts_named(const char *filename, struct opt *opts, unsigned int phase) {
|
||||||
struct opt *opt;
|
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_named(path, opts, PH_EARLY);
|
||||||
|
applyopts(-1, opts, PH_EARLY);
|
||||||
if (*exists) {
|
if (*exists) {
|
||||||
applyopts_named(path, opts, PH_PREOPEN);
|
applyopts_named(path, opts, PH_PREOPEN);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: xio-pipe.c */
|
/* source: xio-pipe.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2008 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* 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 pipe type */
|
/* this file contains the source for opening addresses of pipe type */
|
||||||
|
@ -96,6 +96,7 @@ static int xioopen_fifo1(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
|
applyopts_named(pipename, opts, PH_EARLY); /* umask! */
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
|
@ -142,6 +143,8 @@ static int xioopen_fifo1(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]);
|
Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]);
|
||||||
|
applyopts_named(pipename, opts, PH_ALL);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((fd->stream.unlink_close = strdup(pipename)) == NULL) {
|
if ((fd->stream.unlink_close = strdup(pipename)) == NULL) {
|
||||||
|
|
62
xio-unix.c
62
xio-unix.c
|
@ -166,6 +166,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;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
@ -177,15 +178,27 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
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
|
/* trying to set user-early, perm-early etc. here is useless because
|
||||||
file system entry is available only past bind() call. */
|
file system entry is available only past bind() call. */
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
|
/* this may fork() */
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(xfd, xioflags,
|
xioopen_listen(xfd, xioflags,
|
||||||
(struct sockaddr *)&us, uslen,
|
(struct sockaddr *)&us, uslen,
|
||||||
|
@ -193,18 +206,15 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
!= 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 (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if (pid == Getpid()) {
|
if (pid != Getpid()) {
|
||||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
/* in a child process - do not unlink-close here! */
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
xfd->opt_unlink_close = false;
|
||||||
}
|
|
||||||
xfd->opt_unlink_close = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
@ -380,13 +390,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 */
|
/* 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 (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(name) < 0) {
|
if (Unlink(name) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
|
@ -395,12 +401,30 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
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->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM_ONE;
|
xfd->dtype = XIODATA_RECVFROM_ONE;
|
||||||
|
|
||||||
|
/* this may fork */
|
||||||
return
|
return
|
||||||
_xioopen_dgram_recvfrom(xfd, xioflags,
|
_xioopen_dgram_recvfrom(xfd, xioflags,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
|
@ -443,6 +467,8 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* 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);
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(name) < 0) {
|
if (Unlink(name) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
|
@ -451,10 +477,13 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
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 (opt_unlink_close) {
|
||||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
@ -462,6 +491,7 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
xfd->opt_unlink_close = true;
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
|
||||||
xfd->para.socket.la.soa.sa_family = pf;
|
xfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue