mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 07:22:34 +00:00
New option chdir (cd)
This commit is contained in:
parent
e5cbf2feeb
commit
6125ed4e4e
11 changed files with 301 additions and 62 deletions
4
CHANGES
4
CHANGES
|
@ -143,6 +143,10 @@ Features:
|
|||
Added option res-nsaddr that overrides /etc/resolv.conf nameserver
|
||||
address based on an undocumented resolver feature.
|
||||
|
||||
New option chdir changes the working directory of the address to the
|
||||
given path, only during the open stage.
|
||||
Tests: CHDIR_ON_CREATE CHDIR_ON_SYSTEM
|
||||
|
||||
Option umask now applies only during opening of its very address, not
|
||||
for the lifetime of the process; the original umask is restored
|
||||
afterwards.
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
"1.7.4.5+20230721"
|
||||
"1.7.4.5+"
|
||||
|
|
|
@ -1990,6 +1990,10 @@ These options may be applied to all address types. They change some process
|
|||
properties that are restored after opening the address.
|
||||
|
||||
startdit()
|
||||
label(OPTION_CHDIR)dit(bf(tt(chdir=<filename>))) dit(bf(tt(cd=<filename>)))
|
||||
Changes the working directory. After opening the address the master process
|
||||
changes back to the original working directory. Sub processes inherit the
|
||||
temporary setting.
|
||||
label(OPTION_UMASK)dit(bf(tt(umask=<mode>)))
|
||||
Sets the umask of the process to <mode> [link(mode_t)(TYPE_MODE_T)] before
|
||||
opening the address. Useful when file system entries are created or a shell
|
||||
|
|
176
test.sh
176
test.sh
|
@ -1283,7 +1283,7 @@ waitsctp4port () {
|
|||
[ "$timeout" ] || timeout=5
|
||||
while [ $timeout -gt 0 ]; do
|
||||
case "$UNAME" in
|
||||
Linux) if false && [ "$SS" ]; then
|
||||
Linux) if [ "$SS" ]; then
|
||||
l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>")
|
||||
else
|
||||
l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN')
|
||||
|
@ -7851,7 +7851,8 @@ if ! eval $NUMCOND; then :;
|
|||
else
|
||||
tf="$td/test$N.stout"
|
||||
te="$td/test$N.stderr"
|
||||
CMD="$TRACE $SOCAT $opts -d -d /dev/null pty,end-close"
|
||||
# -t must be longer than 0.1 on OpenBSD
|
||||
CMD="$TRACE $SOCAT $opts -d -d -t 0.5 /dev/null pty,end-close"
|
||||
printf "test $F_n $TEST... " $N
|
||||
# AIX reports the pty writeable for select() only when its slave side has been
|
||||
# opened, therefore we run this process in background and check its NOTICE
|
||||
|
@ -7860,7 +7861,7 @@ printf "test $F_n $TEST... " $N
|
|||
waitfile "${te}"
|
||||
psleep 0.1
|
||||
PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //')
|
||||
[ -e "$PTY" ] && cat $PTY >/dev/null
|
||||
[ -e "$PTY" ] && cat $PTY >/dev/null 2>/dev/null
|
||||
rc=$(cat "$td/test$N.rc0")
|
||||
if [ "$rc" = 0 ]; then
|
||||
$PRINTF "$OK\n"
|
||||
|
@ -17355,6 +17356,171 @@ else
|
|||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# Some of the following tests need absolute path of Socat
|
||||
case "$SOCAT" in
|
||||
/*) absSOCAT="$SOCAT" ;;
|
||||
*) absSOCAT="$PWD/$SOCAT" ;;
|
||||
esac
|
||||
|
||||
# Test the chdir option, in particular if chdir with the first address
|
||||
# (CREATE) does not affect pwd of second address, i.e. original pwd is
|
||||
# recovered
|
||||
NAME=CHDIR_ON_CREATE
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%creat%*|*%system%*|*%chdir%*|*%$NAME%*)
|
||||
TEST="$NAME: restore of pwd after CREAT with chdir option"
|
||||
# Run Socat with first address CREAT with modified chdir,
|
||||
# and second address SYSTEM (shell) with pwd command
|
||||
# Check if the file is created with modified pwd but shell has original pwd
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! F=$(testfeats CREAT SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - CREAT SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! o=$(testoptions chdir) >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tc="test$N.creat"
|
||||
tdd="test$N.d"
|
||||
tdiff="$td/test$N.diff"
|
||||
tdebug="$td/test$N.debug"
|
||||
opwd=$(pwd)
|
||||
CMD0="$TRACE $absSOCAT $opts -U CREAT:$tc,chdir=$td SYSTEM:pwd"
|
||||
printf "test $F_n $TEST... " $N
|
||||
mkdir "$td/$tdd"
|
||||
pushd "$td/$tdd" >/dev/null
|
||||
$CMD0 >/dev/null 2>"${te}0"
|
||||
rc0=$?
|
||||
popd >/dev/null
|
||||
tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
|
||||
pwd2=$(cat $tpwd/$tc </dev/null)
|
||||
echo "Original pwd: $opwd" >>$tdebug
|
||||
echo "Temporary pwd: $tpwd" >>$tdebug
|
||||
echo "Addr2 pwd: $pwd2" >>$tdebug
|
||||
if [ "$rc0" -ne 0 ]; then
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
elif [ "$tpwd" != "$td" ]; then
|
||||
$PRINTF "$FAILED (chdir failed)\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
|
||||
$PRINTF "$FAILED (bad pwd2)\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "// diff:" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
# Test the chdir option, in particular if chdir with first address
|
||||
# (SHELL) does not affect pwd of second address, i.e. original pwd is
|
||||
# recovered
|
||||
NAME=CHDIR_ON_SHELL
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%shell%*|*%system%*|*%chdir%*|*%$NAME%*)
|
||||
TEST="$NAME: restore of pwd after SYSTEM with chdir option"
|
||||
# Run Socat with first address SYSTEM:"cat >file" with chdir,
|
||||
# and second address SYSTEM (shell) with pwd command.
|
||||
# Check if the file is created with modified pwd but shell has original pwd
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! F=$(testfeats SHELL SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs SHELL SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! o=$(testoptions chdir) >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tc="test$N.creat"
|
||||
tdd="test$N.d"
|
||||
tdiff="$td/test$N.diff"
|
||||
tdebug="$td/test$N.debug"
|
||||
opwd=$(pwd)
|
||||
CMD0="$TRACE $absSOCAT $opts -U SHELL:\"cat\ >$tc\",chdir=$td SYSTEM:pwd"
|
||||
printf "test $F_n $TEST... " $N
|
||||
mkdir "$td/$tdd"
|
||||
pushd "$td/$tdd" >/dev/null
|
||||
eval "$CMD0" >/dev/null 2>"${te}0"
|
||||
rc0=$?
|
||||
popd >/dev/null
|
||||
tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
|
||||
pwd2=$(cat $tpwd/$tc </dev/null)
|
||||
echo "Original pwd: $opwd" >>$tdebug
|
||||
echo "Temporary pwd: $tpwd" >>$tdebug
|
||||
echo "Addr2 pwd: $pwd2" >>$tdebug
|
||||
if [ "$rc0" -ne 0 ]; then
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
elif [ "$tpwd" != "$td" ]; then
|
||||
$PRINTF "$FAILED (chdir failed)\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
|
||||
$PRINTF "$FAILED (bad pwd)\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "// diff:" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# Test the modified umask option, in particular if umask with first address
|
||||
|
@ -17372,7 +17538,7 @@ elif ! F=$(testfeats CREAT SYSTEM); then
|
|||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - CREAT SYSTEM); then
|
||||
elif ! A=$(testaddrs CREAT SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
|
@ -17441,7 +17607,7 @@ N=$((N+1))
|
|||
# recovered
|
||||
NAME=UMASK_ON_SYSTEM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%shell%*|*%umask%*|*%socket%*|*%$NAME%*)
|
||||
*%$N%*|*%functions%*|*%shell%*|*%system%*|*%umask%*|*%socket%*|*%$NAME%*)
|
||||
TEST="$NAME: test restore after SHELL with umask option"
|
||||
# Run Socat with first address SHELL:"cat >file" with modified umask,
|
||||
# and second address SYSTEM (shell) with umask command.
|
||||
|
|
|
@ -44,29 +44,61 @@ int xio_set_namespace(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int xio_apply_namespace(
|
||||
struct opt *opts)
|
||||
{
|
||||
int old_netfd;
|
||||
char *netns_name;
|
||||
char old_nspath[PATH_MAX];
|
||||
int rc;
|
||||
|
||||
if (retropt_string(opts, OPT_SET_NETNS, &netns_name) < 0)
|
||||
return 0;
|
||||
|
||||
/* Get path describing current namespace */
|
||||
snprintf(old_nspath, sizeof(old_nspath)-1, "/proc/"F_pid"/ns/net",
|
||||
Getpid());
|
||||
|
||||
/* Get a file descriptor to current ns for later reset */
|
||||
old_netfd = Open(old_nspath, O_RDONLY|O_CLOEXEC, 000);
|
||||
if (old_netfd < 0) {
|
||||
Error2("open(%s, O_RDONLY|O_CLOEXEC): %s",
|
||||
old_nspath, strerror(errno));
|
||||
free(netns_name);
|
||||
return -1;
|
||||
}
|
||||
if (old_netfd == 0) {
|
||||
/* 0 means not netns option, oops */
|
||||
Error1("%s(): INTERNAL", __func__);
|
||||
free(netns_name);
|
||||
Close(old_netfd);
|
||||
return -1;
|
||||
}
|
||||
rc = xio_set_namespace("netns", netns_name);
|
||||
free(netns_name);
|
||||
if (rc < 0) {
|
||||
Close(old_netfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return old_netfd;
|
||||
}
|
||||
|
||||
/* Sets the given namespace to that of process 1, this is assumed to be the
|
||||
systems default.
|
||||
Returns 0 on success, or -1 on error. */
|
||||
int xio_reset_namespace(
|
||||
const char *nstype)
|
||||
int saved_netfd)
|
||||
{
|
||||
char nspath[PATH_MAX];
|
||||
int nsfd;
|
||||
int rc;
|
||||
|
||||
snprintf(nspath, sizeof(nspath)-1, "/proc/1/ns/%s", nstype);
|
||||
Info("switching back to default namespace");
|
||||
nsfd = Open(nspath, O_RDONLY|O_CLOEXEC, 000);
|
||||
if (nsfd < 0) {
|
||||
Error2("open(%s, O_RDONLY|O_CLOEXEC): %s", nspath, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
rc = Setns(nsfd, CLONE_NEWNET);
|
||||
rc = Setns(saved_netfd, CLONE_NEWNET);
|
||||
if (rc < 0) {
|
||||
Error2("setns(%d, CLONE_NEWNET): %s", nsfd, strerror(errno));
|
||||
Close(nsfd);
|
||||
Error2("xio_reset_namespace(%d): %s", saved_netfd, strerror(errno));
|
||||
Close(saved_netfd);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
Close(nsfd);
|
||||
Close(saved_netfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ extern const struct optdesc opt_set_netns;
|
|||
extern const struct optdesc opt_reset_netns;
|
||||
|
||||
extern int xio_set_namespace(const char *nstype, const char *nsname);
|
||||
extern int xio_reset_namespace(const char *nstype);
|
||||
extern int xio_apply_namespace(struct opt *opts);
|
||||
extern int xio_reset_namespace(int saved_netfd);
|
||||
|
||||
#endif /* WITH_NAMESPACES */
|
||||
|
||||
|
|
35
xiolayer.c
35
xiolayer.c
|
@ -24,4 +24,39 @@ const struct optdesc opt_intervall = { "interval", NULL, OPT_INTERVALL, GROUP_R
|
|||
const struct optdesc opt_retry = { "retry", NULL, OPT_RETRY, GROUP_RETRY, PH_INIT, TYPE_UINT, OFUNC_EXT, XIO_OFFSETOF(retry), XIO_SIZEOF(retry) };
|
||||
#endif
|
||||
|
||||
const struct optdesc opt_chdir = { "chdir", "cd", OPT_CHDIR, GROUP_ADDR, PH_INIT, TYPE_FILENAME, OFUNC_SPEC };
|
||||
const struct optdesc opt_umask = { "umask", NULL, OPT_UMASK, GROUP_ADDR, PH_INIT, TYPE_MODET, OFUNC_SPEC };
|
||||
|
||||
|
||||
int xio_chdir(
|
||||
struct opt* opts,
|
||||
char **orig_dir)
|
||||
{
|
||||
char *tmp_dir = NULL;
|
||||
|
||||
if (retropt_string(opts, OPT_CHDIR, &tmp_dir) < 0)
|
||||
return 0;
|
||||
|
||||
if ((*orig_dir = Malloc(PATH_MAX)) == NULL) {
|
||||
free(tmp_dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getcwd(*orig_dir, PATH_MAX) == NULL) {
|
||||
Error1("getcwd(<ptr>, PATH_MAX): %s", strerror(errno));
|
||||
free(*orig_dir);
|
||||
free(tmp_dir);
|
||||
return -1;
|
||||
}
|
||||
*orig_dir = Realloc(*orig_dir, strlen(*orig_dir+1));
|
||||
|
||||
if (Chdir(tmp_dir) < 0) {
|
||||
Error2("chdir(\"%s\"): %s", tmp_dir, strerror(errno));
|
||||
free(*orig_dir);
|
||||
free(tmp_dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(tmp_dir);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ extern const struct optdesc opt_escape;
|
|||
extern const struct optdesc opt_forever;
|
||||
extern const struct optdesc opt_intervall;
|
||||
extern const struct optdesc opt_retry;
|
||||
extern const struct optdesc opt_chdir;
|
||||
extern const struct optdesc opt_umask;
|
||||
extern const struct optdesc opt_un_umask;
|
||||
|
||||
extern int xio_chdir(struct opt* opts, char **orig_dir);
|
||||
|
||||
#endif /* !defined(__xiolayer_h_included) */
|
||||
|
|
70
xioopen.c
70
xioopen.c
|
@ -622,6 +622,7 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
|
|||
const struct addrdesc *addrdesc;
|
||||
const char *modetext[4] = { "none", "read-only", "write-only", "read-write" } ;
|
||||
/* Values to be saved until xioopen() is finished */
|
||||
char *orig_dir = NULL;
|
||||
bool have_umask = false;
|
||||
mode_t orig_umask, tmp_umask;
|
||||
int result;
|
||||
|
@ -631,42 +632,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
|
|||
struct __res_state save_res;
|
||||
#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
|
||||
#if WITH_NAMESPACES
|
||||
char *temp_netns;
|
||||
int save_netfd = -1;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
/* Apply "temporary" process properties, save value for later restore */
|
||||
|
||||
if (applyopts_single(sfd, sfd->opts, PH_OFFSET) < 0)
|
||||
return -1;
|
||||
|
||||
#if WITH_NAMESPACES
|
||||
if (retropt_string(sfd->opts, OPT_SET_NETNS, &temp_netns) >= 0) {
|
||||
char nspath[PATH_MAX];
|
||||
|
||||
snprintf(nspath, sizeof(nspath)-1, "/proc/"F_pid"/ns/net",
|
||||
Getpid());
|
||||
save_netfd = Open(nspath, O_RDONLY|O_CLOEXEC, 000);
|
||||
if (save_netfd < 0) {
|
||||
Error2("open(%s, O_RDONLY|O_CLOEXEC): %s", nspath, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = xio_set_namespace("netns", temp_netns);
|
||||
free(temp_netns);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_NAMESPACES */
|
||||
|
||||
#if WITH_RESOLVE && HAVE_RESOLV_H
|
||||
if ((do_res = xio_res_init(sfd, &save_res)) < 0)
|
||||
return STAT_NORETRY;
|
||||
#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
|
||||
|
||||
addrdesc = xfd->stream.addr;
|
||||
/* Check if address supports required data directions */
|
||||
if (((xioflags+1)&XIO_ACCMODE) & ~(addrdesc->directions)) {
|
||||
Warn2("address is opened in %s mode but only supports %s", modetext[(xioflags+1)&XIO_ACCMODE], modetext[addrdesc->directions]);
|
||||
}
|
||||
|
@ -682,12 +651,31 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
|
|||
xfd->stream.flags &= (~XIO_ACCMODE);
|
||||
xfd->stream.flags |= (xioflags & XIO_ACCMODE);
|
||||
|
||||
/* Apply "temporary" process properties, save value for later restore */
|
||||
|
||||
if (applyopts_single(sfd, sfd->opts, PH_OFFSET) < 0)
|
||||
return -1;
|
||||
|
||||
#if WITH_NAMESPACES
|
||||
if ((save_netfd = xio_apply_namespace(sfd->opts)) < 0)
|
||||
return -1;
|
||||
#endif /* WITH_NAMESPACES */
|
||||
|
||||
#if HAVE_RESOLV_H
|
||||
if ((do_res = xio_res_init(sfd, &save_res)) < 0)
|
||||
return STAT_NORETRY;
|
||||
#endif /* HAVE_RESOLV_H */
|
||||
|
||||
if (xio_chdir(sfd->opts, &orig_dir) < 0)
|
||||
return STAT_NORETRY;
|
||||
|
||||
if (retropt_mode(xfd->stream.opts, OPT_UMASK, &tmp_umask) >= 0) {
|
||||
Info1("changing umask to 0%3o", tmp_umask);
|
||||
orig_umask = Umask(tmp_umask);
|
||||
have_umask = true;
|
||||
}
|
||||
|
||||
/* Call the specific xioopen function */
|
||||
result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv,
|
||||
xfd->stream.opts, xioflags, xfd,
|
||||
addrdesc);
|
||||
|
@ -698,19 +686,23 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
|
|||
Umask(orig_umask);
|
||||
}
|
||||
|
||||
if (orig_dir != NULL) {
|
||||
if (Chdir(orig_dir) < 0) {
|
||||
Error2("chdir(\"%s\"): %s", orig_dir, strerror(errno));
|
||||
free(orig_dir);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
free(orig_dir);
|
||||
}
|
||||
|
||||
#if WITH_RESOLVE && HAVE_RESOLV_H
|
||||
if (do_res)
|
||||
xio_res_restore(&save_res);
|
||||
#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
|
||||
|
||||
#if WITH_NAMESPACES
|
||||
if (save_netfd >= 0) {
|
||||
rc = Setns(save_netfd, CLONE_NEWNET);
|
||||
if (rc < 0) {
|
||||
Error2("setns(%d, CLONE_NEWNET): %s", save_netfd, strerror(errno));
|
||||
Close(save_netfd);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
if (save_netfd > 0) {
|
||||
xio_reset_namespace(save_netfd);
|
||||
}
|
||||
#endif /* WITH_NAMESPACES */
|
||||
|
||||
|
|
|
@ -314,9 +314,11 @@ const struct optname optionnames[] = {
|
|||
IF_ANY ("bytes", &opt_readbytes)
|
||||
IF_OPENSSL("cafile", &opt_openssl_cafile)
|
||||
IF_OPENSSL("capath", &opt_openssl_capath)
|
||||
IF_ANY ("cd", &opt_chdir)
|
||||
IF_OPENSSL("cert", &opt_openssl_certificate)
|
||||
IF_OPENSSL("certificate", &opt_openssl_certificate)
|
||||
IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
|
||||
IF_ANY ("chdir", &opt_chdir)
|
||||
#if WITH_LISTEN
|
||||
IF_ANY ("children-shutup", &opt_children_shutup)
|
||||
#endif
|
||||
|
|
|
@ -263,6 +263,7 @@ enum e_optcode {
|
|||
# endif
|
||||
OPT_BSDLY, /* termios.c_oflag */
|
||||
#endif
|
||||
OPT_CHDIR, /* change working directory */
|
||||
OPT_CHILDREN_SHUTUP,
|
||||
OPT_CHROOT, /* chroot() past file system access */
|
||||
OPT_CHROOT_EARLY, /* chroot() before file system access */
|
||||
|
|
Loading…
Reference in a new issue