mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
New option children-shutup
This commit is contained in:
parent
fe4444a70b
commit
8c9b185890
18 changed files with 128 additions and 23 deletions
6
CHANGES
6
CHANGES
|
@ -53,6 +53,10 @@ Features:
|
||||||
Socat now installs as socat1 and is referenced by symbolic link socat,
|
Socat now installs as socat1 and is referenced by symbolic link socat,
|
||||||
same with man page (socat1.1 by socat.1)
|
same with man page (socat1.1 by socat.1)
|
||||||
|
|
||||||
|
New option children-shutup[=1|2...] decreases severity of log
|
||||||
|
messages in LISTEN and CONNECT type sub processes.
|
||||||
|
Test: CHILDREN_SHUTUP
|
||||||
|
|
||||||
Corrections:
|
Corrections:
|
||||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||||
0, its last sent data might have been lost depending on timing of read/
|
0, its last sent data might have been lost depending on timing of read/
|
||||||
|
@ -76,7 +80,7 @@ Corrections:
|
||||||
|
|
||||||
In previous Socat versions errors on shutdown() were ignored (info
|
In previous Socat versions errors on shutdown() were ignored (info
|
||||||
level).
|
level).
|
||||||
Now Socat handles EPIPE and ECONNRESET as error to indicate possible
|
Now Socat handles EPIPE and ECONNRESET as errors to indicate possible
|
||||||
failure of data transfer.
|
failure of data transfer.
|
||||||
|
|
||||||
Coding:
|
Coding:
|
||||||
|
|
20
doc/socat.yo
20
doc/socat.yo
|
@ -1628,6 +1628,8 @@ label(OPTION_COOL_WRITE)dit(bf(tt(cool-write[=<bool>])))
|
||||||
abort the connection. Use this option only with option
|
abort the connection. Use this option only with option
|
||||||
link(fork)(OPTION_FORK) because otherwise it might cause socat() to exit
|
link(fork)(OPTION_FORK) because otherwise it might cause socat() to exit
|
||||||
with code 0 even on failure.nl()
|
with code 0 even on failure.nl()
|
||||||
|
This option is deprecated, consider using
|
||||||
|
link(option children-shutup)(OPTION_CHILDRED_SHUTUP) instead.
|
||||||
label(OPTION_END_CLOSE)dit(bf(tt(end-close[=<bool>])))
|
label(OPTION_END_CLOSE)dit(bf(tt(end-close[=<bool>])))
|
||||||
Changes the (address dependent) method of ending a connection to just close
|
Changes the (address dependent) method of ending a connection to just close
|
||||||
the file descriptors. This is useful when the connection is to be reused by
|
the file descriptors. This is useful when the connection is to be reused by
|
||||||
|
@ -2514,16 +2516,15 @@ label(OPTION_BACKLOG)dit(bf(tt(backlog=<count>)))
|
||||||
label(OPTION_ACCEPT_TIMEOUT)dit(bf(tt(accept-timeout=<seconds>)))
|
label(OPTION_ACCEPT_TIMEOUT)dit(bf(tt(accept-timeout=<seconds>)))
|
||||||
End waiting for a connection after <seconds> [link(timeval)(TYPE_TIMEVAL)]
|
End waiting for a connection after <seconds> [link(timeval)(TYPE_TIMEVAL)]
|
||||||
with error status.
|
with error status.
|
||||||
label(OPTION_MAX_CHILDREN)dit(bf(tt(max-children=<count>)))
|
|
||||||
Limits the number of concurrent child processes [link(int)(TYPE_INT)].
|
|
||||||
Default is no limit.
|
|
||||||
enddit()
|
enddit()
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
|
||||||
label(GROUP_CHILD)em(bf(CHILD option group))
|
label(GROUP_CHILD)em(bf(CHILD option group))
|
||||||
|
|
||||||
Options for addresses with multiple connections via child processes.
|
Addresses of LISTEN and CONNECT type take the
|
||||||
|
link(fork)(OPTION_FORK) option to handle multiple connections via child
|
||||||
|
processes.
|
||||||
startdit()
|
startdit()
|
||||||
label(OPTION_FORK)dit(bf(tt(fork)))
|
label(OPTION_FORK)dit(bf(tt(fork)))
|
||||||
After establishing a connection, handles its channel in a child process and
|
After establishing a connection, handles its channel in a child process and
|
||||||
|
@ -2537,6 +2538,17 @@ label(OPTION_FORK)dit(bf(tt(fork)))
|
||||||
inherited by the child process.nl()
|
inherited by the child process.nl()
|
||||||
On some operating systems (e.g. FreeBSD) this option does not work for
|
On some operating systems (e.g. FreeBSD) this option does not work for
|
||||||
UDP-LISTEN addresses.nl()
|
UDP-LISTEN addresses.nl()
|
||||||
|
label(OPTION_MAX_CHILDREN)dit(bf(tt(max-children=<count>)))
|
||||||
|
Limits the number of concurrent child processes [link(int)(TYPE_INT)].
|
||||||
|
Default is no limit.
|
||||||
|
label(OPTION_CHILDRED_SHUTUP)dit(bf(tt(children-shutup[=1|2|..])))
|
||||||
|
Decreases the severity of log messages produced by child processes. For
|
||||||
|
example, with value 1 notices are logged as info (or dropped depending on
|
||||||
|
link(option -dX)(option_d)), and errors are logged as warnings but still
|
||||||
|
cause termination of the child process.nl()
|
||||||
|
This option is intended to reduce logging of high volume servers or
|
||||||
|
proxies.nl()
|
||||||
|
This option succeeds link(option cool-write)(OPTION_COOL_WRITE).
|
||||||
enddit()
|
enddit()
|
||||||
|
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
|
25
error.c
25
error.c
|
@ -29,6 +29,7 @@ int syslevel[] = {
|
||||||
struct diag_opts {
|
struct diag_opts {
|
||||||
const char *progname;
|
const char *progname;
|
||||||
int msglevel;
|
int msglevel;
|
||||||
|
int shutup; /* decrease msglevel by this value */
|
||||||
int exitlevel;
|
int exitlevel;
|
||||||
int syslog;
|
int syslog;
|
||||||
FILE *logfile;
|
FILE *logfile;
|
||||||
|
@ -45,7 +46,7 @@ static void _diag_exit(int status);
|
||||||
|
|
||||||
|
|
||||||
struct diag_opts diagopts =
|
struct diag_opts diagopts =
|
||||||
{ NULL, E_WARN, E_ERROR, 0, NULL, LOG_DAEMON, false, 0, false, NULL, true } ;
|
{ NULL, E_WARN, 0, E_ERROR, 0, NULL, LOG_DAEMON, false, 0, false, NULL, true } ;
|
||||||
|
|
||||||
static void msg2(
|
static void msg2(
|
||||||
#if HAVE_CLOCK_GETTIME
|
#if HAVE_CLOCK_GETTIME
|
||||||
|
@ -215,6 +216,10 @@ void diag_set_int(char what, int arg) {
|
||||||
diagopts.hostname = strdup(ubuf.nodename);
|
diagopts.hostname = strdup(ubuf.nodename);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
diagopts.shutup = arg;
|
||||||
|
diagopts.exitlevel -= arg;
|
||||||
|
break;
|
||||||
default: msg(E_ERROR, "unknown diagnostic option %c", what);
|
default: msg(E_ERROR, "unknown diagnostic option %c", what);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +288,12 @@ void msg(int level, const char *format, ...) {
|
||||||
diag_flush();
|
diag_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level < diagopts.msglevel) { return; }
|
level -= diagopts.shutup; /* decrease severity of messages? */
|
||||||
|
|
||||||
|
/* Just ignore this call when level too low for both logging and exiting */
|
||||||
|
if (level < diagopts.msglevel && level < diagopts.exitlevel)
|
||||||
|
return;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
|
|
||||||
/* we do only a minimum in the outer parts which may run in a signal handler
|
/* we do only a minimum in the outer parts which may run in a signal handler
|
||||||
|
@ -299,7 +309,10 @@ void msg(int level, const char *format, ...) {
|
||||||
#endif
|
#endif
|
||||||
diag_dgram.level = level;
|
diag_dgram.level = level;
|
||||||
diag_dgram.exitcode = diagopts.exitstatus;
|
diag_dgram.exitcode = diagopts.exitstatus;
|
||||||
vsnprintf_r(diag_dgram.text, sizeof(diag_dgram.text), format, ap);
|
if (level >= diagopts.msglevel)
|
||||||
|
vsnprintf_r(diag_dgram.text, sizeof(diag_dgram.text), format, ap);
|
||||||
|
else
|
||||||
|
diag_dgram.text[0] = '\0';
|
||||||
if (diagopts.signalsafe && diag_in_handler && !diag_immediate_msg) {
|
if (diagopts.signalsafe && diag_in_handler && !diag_immediate_msg) {
|
||||||
send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN + strlen(diag_dgram.text)+1,
|
send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN + strlen(diag_dgram.text)+1,
|
||||||
0 /* for canonical reasons */
|
0 /* for canonical reasons */
|
||||||
|
@ -337,9 +350,10 @@ void msg2(
|
||||||
struct tm struct_tm;
|
struct tm struct_tm;
|
||||||
#endif
|
#endif
|
||||||
#define MSGLEN 512
|
#define MSGLEN 512
|
||||||
char buff[MSGLEN+2], *bufp = buff, *syslp;
|
char buff[MSGLEN+2], *bufp = buff, *syslp = NULL;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
|
|
||||||
|
if (text[0] != '\0') {
|
||||||
#if HAVE_CLOCK_GETTIME
|
#if HAVE_CLOCK_GETTIME
|
||||||
epoch = now->tv_sec;
|
epoch = now->tv_sec;
|
||||||
#elif HAVE_PROTOTYPE_LIB_gettimeofday
|
#elif HAVE_PROTOTYPE_LIB_gettimeofday
|
||||||
|
@ -391,8 +405,9 @@ void msg2(
|
||||||
bufp = strchr(bufp, '\0');
|
bufp = strchr(bufp, '\0');
|
||||||
strcpy(bufp, "\n");
|
strcpy(bufp, "\n");
|
||||||
_msg(level, buff, syslp);
|
_msg(level, buff, syslp);
|
||||||
|
}
|
||||||
if (level >= diagopts.exitlevel) {
|
if (level >= diagopts.exitlevel) {
|
||||||
if (E_NOTICE >= diagopts.msglevel) {
|
if (E_NOTICE >= diagopts.msglevel && text[0] != '\0') {
|
||||||
if ((syslp - buff) + 16 > MSGLEN+1)
|
if ((syslp - buff) + 16 > MSGLEN+1)
|
||||||
syslp = buff + MSGLEN - 15;
|
syslp = buff + MSGLEN - 15;
|
||||||
snprintf_r(syslp, 16, "N exit(%d)\n", exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1));
|
snprintf_r(syslp, 16, "N exit(%d)\n", exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1));
|
||||||
|
|
61
test.sh
61
test.sh
|
@ -15521,6 +15521,67 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# Test the children-shutup option
|
||||||
|
NAME=CHILDREN_SHUTUP
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: test the children-shutup option"
|
||||||
|
# Run a UNIX domain listening server with options fork and children-shutup, and
|
||||||
|
# an TCP client to invalid port that will fail.
|
||||||
|
# Connect to the server and check if it logs the connect failure as warning.
|
||||||
|
if ! eval $NUMCOND; then :;
|
||||||
|
elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! o=$(testoptions fork children-shutup) >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
newport tcp4
|
||||||
|
ts="$td/test$N.sock"
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,fork,children-shutup TCP4:localhost:$PORT"
|
||||||
|
CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null UNIX-CONNECT:$ts"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
|
pid0=$!
|
||||||
|
waitunixport $ts 1
|
||||||
|
$CMD1 2>"${te}1"
|
||||||
|
rc1=$?
|
||||||
|
kill $pid0 2>/dev/null; wait
|
||||||
|
relsleep 1 # child process might need more time
|
||||||
|
if grep -q " W connect" ${te}0; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "${te}0" >&2
|
||||||
|
echo "$CMD1"
|
||||||
|
cat "${te}1" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
namesFAIL="$namesFAIL $NAME"
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
# end of common tests
|
# end of common tests
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
|
|
@ -110,7 +110,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
level = E_WARN; /* most users won't expect a problem here,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (xfd->forever || --xfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&xfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
/***** LISTEN options *****/
|
/***** LISTEN options *****/
|
||||||
const struct optdesc opt_backlog = { "backlog", NULL, OPT_BACKLOG, GROUP_LISTEN, PH_LISTEN, TYPE_INT, OFUNC_SPEC };
|
const struct optdesc opt_backlog = { "backlog", NULL, OPT_BACKLOG, GROUP_LISTEN, PH_LISTEN, TYPE_INT, OFUNC_SPEC };
|
||||||
const struct optdesc opt_fork = { "fork", NULL, OPT_FORK, GROUP_CHILD, PH_PASTACCEPT, TYPE_BOOL, OFUNC_SPEC };
|
const struct optdesc opt_fork = { "fork", NULL, OPT_FORK, GROUP_CHILD, PH_PASTACCEPT, TYPE_BOOL, OFUNC_SPEC };
|
||||||
const struct optdesc opt_max_children = { "max-children", NULL, OPT_MAX_CHILDREN, GROUP_CHILD, PH_PASTACCEPT, TYPE_INT, OFUNC_SPEC };
|
const struct optdesc opt_max_children = { "max-children", NULL, OPT_MAX_CHILDREN, GROUP_CHILD, PH_PASTACCEPT, TYPE_INT, OFUNC_SPEC };
|
||||||
|
const struct optdesc opt_children_shutup = { "children-shutup", "child-shutup", OPT_CHILDREN_SHUTUP, GROUP_CHILD, PH_PASTACCEPT, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.shutup) };
|
||||||
/**/
|
/**/
|
||||||
#if (WITH_UDP || WITH_TCP)
|
#if (WITH_UDP || WITH_TCP)
|
||||||
const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_RANGE, PH_ACCEPT, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_RANGE, PH_ACCEPT, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
@ -343,7 +344,10 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
||||||
sigaddset(&mask_sigchld, SIGCHLD);
|
sigaddset(&mask_sigchld, SIGCHLD);
|
||||||
Sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);
|
Sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);
|
||||||
|
|
||||||
if ((pid = xio_fork(false, level==E_ERROR?level:E_WARN)) < 0) {
|
if ((pid =
|
||||||
|
xio_fork(false, level==E_ERROR?level:E_WARN,
|
||||||
|
xfd->para.socket.shutup))
|
||||||
|
< 0) {
|
||||||
Close(xfd->fd);
|
Close(xfd->fd);
|
||||||
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
|
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
extern const struct optdesc opt_backlog;
|
extern const struct optdesc opt_backlog;
|
||||||
extern const struct optdesc opt_fork;
|
extern const struct optdesc opt_fork;
|
||||||
extern const struct optdesc opt_max_children;
|
extern const struct optdesc opt_max_children;
|
||||||
|
extern const struct optdesc opt_children_shutup;
|
||||||
extern const struct optdesc opt_range;
|
extern const struct optdesc opt_range;
|
||||||
extern const struct optdesc opt_accept_timeout;
|
extern const struct optdesc opt_accept_timeout;
|
||||||
|
|
||||||
|
|
|
@ -409,7 +409,7 @@ static int
|
||||||
if (xfd->forever || xfd->retry) {
|
if (xfd->forever || xfd->retry) {
|
||||||
level = E_WARN;
|
level = E_WARN;
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (xfd->forever || --xfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&xfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
|
|
||||||
if (withfork) {
|
if (withfork) {
|
||||||
Socketpair(PF_UNIX, SOCK_STREAM, 0, trigger);
|
Socketpair(PF_UNIX, SOCK_STREAM, 0, trigger);
|
||||||
pid = xio_fork(true, E_ERROR);
|
pid = xio_fork(true, E_ERROR, 0);
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
if (xfd->forever || xfd->retry) {
|
if (xfd->forever || xfd->retry) {
|
||||||
level = E_WARN;
|
level = E_WARN;
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (xfd->forever || --xfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&xfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -993,7 +993,7 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
--xfd->retry;
|
--xfd->retry;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (xfd->forever || xfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
|
@ -1287,7 +1287,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
Error1("socketpair(PF_UNIX, SOCK_STREAM, 0, ...): %s", strerror(errno));
|
Error1("socketpair(PF_UNIX, SOCK_STREAM, 0, ...): %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pid = xio_fork(false, level)) < 0) {
|
if ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
Close(trigger[0]);
|
Close(trigger[0]);
|
||||||
Close(trigger[1]);
|
Close(trigger[1]);
|
||||||
Close(xfd->fd);
|
Close(xfd->fd);
|
||||||
|
|
|
@ -175,7 +175,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
level = E_WARN; /* most users won't expect a problem here,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (xfd->forever || --xfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&xfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -214,7 +214,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)));
|
||||||
|
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid = xio_fork(false, E_ERROR);
|
pid = xio_fork(false, E_ERROR, sfd->para.socket.shutup);
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,7 +315,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pid = xio_fork(false, level)) < 0) {
|
while ((pid = xio_fork(false, level, xfd->para.socket.shutup)) < 0) {
|
||||||
--xfd->retry;
|
--xfd->retry;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (xfd->forever || xfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
|
|
4
xio.h
4
xio.h
|
@ -223,6 +223,7 @@ typedef struct single {
|
||||||
#if _WITH_IP4 || _WITH_IP6
|
#if _WITH_IP4 || _WITH_IP6
|
||||||
struct para_ip ip;
|
struct para_ip ip;
|
||||||
#endif /* _WITH_IP4 || _WITH_IP6 */
|
#endif /* _WITH_IP4 || _WITH_IP6 */
|
||||||
|
int shutup;
|
||||||
/* up to here, keep consistent copy in openssl part !!! */
|
/* up to here, keep consistent copy in openssl part !!! */
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
struct {
|
struct {
|
||||||
|
@ -263,6 +264,7 @@ typedef struct single {
|
||||||
#if _WITH_IP4 || _WITH_IP6
|
#if _WITH_IP4 || _WITH_IP6
|
||||||
struct para_ip ip;
|
struct para_ip ip;
|
||||||
#endif /* _WITH_IP4 || _WITH_IP6 */
|
#endif /* _WITH_IP4 || _WITH_IP6 */
|
||||||
|
int shutup;
|
||||||
/* end of the para.socket structure copy */
|
/* end of the para.socket structure copy */
|
||||||
SSL_CTX* ctx; /* for freeing on close */
|
SSL_CTX* ctx; /* for freeing on close */
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
|
@ -440,7 +442,7 @@ extern int num_child;
|
||||||
|
|
||||||
extern int xioinitialize(void);
|
extern int xioinitialize(void);
|
||||||
extern int xioinitialize2(void);
|
extern int xioinitialize2(void);
|
||||||
extern pid_t xio_fork(bool subchild, int level);
|
extern pid_t xio_fork(bool subchild, int level, int shutup);
|
||||||
extern int xio_forked_inchild(void);
|
extern int xio_forked_inchild(void);
|
||||||
extern int xiosetopt(char what, const char *arg);
|
extern int xiosetopt(char what, const char *arg);
|
||||||
extern int xioinqopt(char what, char *arg, size_t n);
|
extern int xioinqopt(char what, char *arg, size_t n);
|
||||||
|
|
|
@ -205,7 +205,10 @@ int xio_forked_inchild(void) {
|
||||||
/* subchild != 0 means that the current process is already a child process of
|
/* subchild != 0 means that the current process is already a child process of
|
||||||
the master process and thus the new sub child process should not set the
|
the master process and thus the new sub child process should not set the
|
||||||
SOCAT_PID variable */
|
SOCAT_PID variable */
|
||||||
pid_t xio_fork(bool subchild, int level) {
|
pid_t xio_fork(bool subchild,
|
||||||
|
int level, /* log level */
|
||||||
|
int shutup) /* decrease log level in child process */
|
||||||
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
const char *forkwaitstring;
|
const char *forkwaitstring;
|
||||||
int forkwaitsecs = 0;
|
int forkwaitsecs = 0;
|
||||||
|
@ -240,6 +243,7 @@ pid_t xio_fork(bool subchild, int level) {
|
||||||
if (xio_forked_inchild() != 0) {
|
if (xio_forked_inchild() != 0) {
|
||||||
Exit(1);
|
Exit(1);
|
||||||
}
|
}
|
||||||
|
diag_set_int('u', shutup);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,7 @@ const struct optname optionnames[] = {
|
||||||
IF_OPENSSL("cert", &opt_openssl_certificate)
|
IF_OPENSSL("cert", &opt_openssl_certificate)
|
||||||
IF_OPENSSL("certificate", &opt_openssl_certificate)
|
IF_OPENSSL("certificate", &opt_openssl_certificate)
|
||||||
IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
|
IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
|
||||||
|
IF_ANY ("children-shutup", &opt_children_shutup)
|
||||||
IF_ANY ("chroot", &opt_chroot)
|
IF_ANY ("chroot", &opt_chroot)
|
||||||
IF_ANY ("chroot-early", &opt_chroot_early)
|
IF_ANY ("chroot-early", &opt_chroot_early)
|
||||||
/*IF_TERMIOS("cibaud", &opt_cibaud)*/
|
/*IF_TERMIOS("cibaud", &opt_cibaud)*/
|
||||||
|
|
|
@ -247,6 +247,7 @@ enum e_optcode {
|
||||||
# endif
|
# endif
|
||||||
OPT_BSDLY, /* termios.c_oflag */
|
OPT_BSDLY, /* termios.c_oflag */
|
||||||
#endif
|
#endif
|
||||||
|
OPT_CHILDREN_SHUTUP,
|
||||||
OPT_CHROOT, /* chroot() past file system access */
|
OPT_CHROOT, /* chroot() past file system access */
|
||||||
OPT_CHROOT_EARLY, /* chroot() before file system access */
|
OPT_CHROOT_EARLY, /* chroot() before file system access */
|
||||||
/*OPT_CIBAUD,*/ /* termios.c_cflag */
|
/*OPT_CIBAUD,*/ /* termios.c_cflag */
|
||||||
|
|
Loading…
Reference in a new issue