mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Option -S for controlling signals' logging
This commit is contained in:
parent
02483ff39e
commit
eeabf31e04
4 changed files with 123 additions and 20 deletions
4
CHANGES
4
CHANGES
|
@ -13,6 +13,10 @@ Features:
|
|||
The number of warnings has been reduced, e.g.removing a non existing
|
||||
file does in most cases no longer log a warning.
|
||||
|
||||
New option -S <mask> controls catching and logging of signals that are
|
||||
not internally used by Socat.
|
||||
Tests: SIGTERM_NOLOG SIG31_LOG
|
||||
|
||||
Corrections:
|
||||
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/
|
||||
|
|
|
@ -176,6 +176,15 @@ label(option_s)dit(bf(tt(-s)))
|
|||
option, socat() is sloppy with errors and tries to continue. Even with this
|
||||
option, socat will exit on fatals, and will abort connection attempts when
|
||||
security checks failed.
|
||||
label(option_S)dit(bf(tt(-S))tt(<signals-bitmap>))
|
||||
Changes the set of signals that are caught by socat() just for printing an
|
||||
log message. This catching is useful to get the information about the signal
|
||||
into socat()s log, but prevents core dump or other standard actions. The
|
||||
default set of these signals is SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
|
||||
SIGBUS, SIGFPE, SIGSEGV, and SIGTERM; replace this set (0x89de on Linux)
|
||||
with a bitmap (e.g., SIGFPE has value 8 and its bit is 0x0080).nl()
|
||||
Note: Signals SIGHUP, SIGINT, SIGQUIT, SIGUSR1, SIGPIPE, SIGALRM, SIGTERM, and
|
||||
SIGCHLD may be handled specially anyway.
|
||||
label(option_t)dit(bf(tt(-t))tt(<timeout>))
|
||||
When one channel has reached EOF, the write part of the other channel is shut
|
||||
down. Then, socat() waits <timeout> [link(timeval)(TYPE_TIMEVAL)] seconds
|
||||
|
|
41
socat.c
41
socat.c
|
@ -39,6 +39,7 @@ struct {
|
|||
int sniffleft; /* -1 or an FD for teeing data arriving on xfd1 */
|
||||
int sniffright; /* -1 or an FD for teeing data arriving on xfd2 */
|
||||
xiolock_t lock; /* a lock file */
|
||||
unsigned long log_sigs; /* signals to be caught just for logging */
|
||||
} socat_opts = {
|
||||
8192, /* bufsiz */
|
||||
false, /* verbose */
|
||||
|
@ -54,6 +55,7 @@ struct {
|
|||
-1, /* sniffleft */
|
||||
-1, /* sniffright */
|
||||
{ NULL, 0 }, /* lock */
|
||||
1<<SIGHUP | 1<<SIGINT | 1<<SIGQUIT | 1<<SIGILL | 1<<SIGABRT | 1<<SIGBUS | 1<<SIGFPE | 1<<SIGSEGV | 1<<SIGTERM, /* log_sigs */
|
||||
};
|
||||
|
||||
void socat_usage(FILE *fd);
|
||||
|
@ -241,6 +243,18 @@ int main(int argc, const char *argv[]) {
|
|||
break;
|
||||
case 's': if (arg1[0][2]) { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); }
|
||||
diag_set_int('e', E_FATAL); break;
|
||||
case 'S': /* do not catch signals */
|
||||
if (arg1[0][2]) {
|
||||
a = *arg1+2;
|
||||
} else {
|
||||
++arg1, --argc;
|
||||
if ((a = *arg1) == NULL) {
|
||||
Error("option -S requires an argument; use option \"-h\" for help");
|
||||
Exit(1);
|
||||
}
|
||||
}
|
||||
socat_opts.log_sigs = Strtoul(a, (char **)&a, 0, "-S");
|
||||
break;
|
||||
case 't': if (arg1[0][2]) {
|
||||
a = *arg1+2;
|
||||
} else {
|
||||
|
@ -370,19 +384,17 @@ int main(int argc, const char *argv[]) {
|
|||
|
||||
{
|
||||
struct sigaction act;
|
||||
sigfillset(&act.sa_mask);
|
||||
int i, m;
|
||||
|
||||
sigfillset(&act.sa_mask); /* while in sighandler block all signals */
|
||||
act.sa_flags = 0;
|
||||
act.sa_handler = socat_signal;
|
||||
/* not sure which signals should be caught and print a message */
|
||||
Sigaction(SIGHUP, &act, NULL);
|
||||
Sigaction(SIGINT, &act, NULL);
|
||||
Sigaction(SIGQUIT, &act, NULL);
|
||||
Sigaction(SIGILL, &act, NULL);
|
||||
Sigaction(SIGABRT, &act, NULL);
|
||||
Sigaction(SIGBUS, &act, NULL);
|
||||
Sigaction(SIGFPE, &act, NULL);
|
||||
Sigaction(SIGSEGV, &act, NULL);
|
||||
Sigaction(SIGTERM, &act, NULL);
|
||||
for (i = 0, m = 1; i < 8*sizeof(unsigned long); ++i, m <<= 1) {
|
||||
if (socat_opts.log_sigs & m) {
|
||||
Sigaction(i, &act, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
Signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
|
@ -429,7 +441,7 @@ void socat_usage(FILE *fd) {
|
|||
fputs(" -lf<logfile> log to file\n", fd);
|
||||
fputs(" -ls log to stderr (default if no other log)\n", fd);
|
||||
fputs(" -lm[facility] mixed log mode (stderr during initialization, then syslog)\n", fd);
|
||||
fputs(" -lp<progname> set the program name used for logging\n", fd);
|
||||
fputs(" -lp<progname> set the program name used for logging and vars\n", fd);
|
||||
fputs(" -lu use microseconds for logging timestamps\n", fd);
|
||||
fputs(" -lh add hostname to log messages\n", fd);
|
||||
fputs(" -v verbose text dump of data traffic\n", fd);
|
||||
|
@ -438,6 +450,7 @@ void socat_usage(FILE *fd) {
|
|||
fputs(" -R <file> raw dump of data flowing from right to left\n", fd);
|
||||
fputs(" -b<size_t> set data buffer size (8192)\n", fd);
|
||||
fputs(" -s sloppy (continue on error)\n", fd);
|
||||
fputs(" -S<sigmask> log these signals, override default\n", fd);
|
||||
fputs(" -t<timeout> wait seconds before closing second channel\n", fd);
|
||||
fputs(" -T<timeout> total inactivity timeout in seconds\n", fd);
|
||||
fputs(" -u unidirectional mode (left to right)\n", fd);
|
||||
|
@ -1593,11 +1606,7 @@ void socat_signal(int signum) {
|
|||
diag_in_handler = 1;
|
||||
Notice1("socat_signal(): handling signal %d", signum);
|
||||
switch (signum) {
|
||||
case SIGILL:
|
||||
case SIGABRT:
|
||||
case SIGBUS:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
default:
|
||||
diag_immediate_exit = 1;
|
||||
case SIGQUIT:
|
||||
case SIGPIPE:
|
||||
|
|
89
test.sh
89
test.sh
|
@ -4267,7 +4267,7 @@ case "$TESTS" in
|
|||
*%$N%*|*%functions%*|*%$NAME%*)
|
||||
if ! eval $NUMCOND; then :
|
||||
elif ! F=$(testfeats STDIO EXEC); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs STDIO EXEC); then
|
||||
|
@ -9271,7 +9271,7 @@ case "$TESTS" in
|
|||
TEST="$NAME: UDP/IPv6 multicast"
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! f=$(testfeats ip6 udp); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not available in $SOCAT${NORMAL}\n" $N
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then
|
||||
|
@ -16127,7 +16127,7 @@ TEST="$NAME: ${KEYW}-RECVFROM with fork option"
|
|||
# When the second record is stored before the first one the test succeeded.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! F=$(testfeats $FEAT STDIO SYSTEM); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then
|
||||
|
@ -16205,6 +16205,87 @@ UDP6 UDP udp4 [::1] PORT
|
|||
UNIX unix unix $td/test\$N.server -
|
||||
"
|
||||
|
||||
|
||||
# Test if option -S turns off logging of SIGTERM
|
||||
NAME=SIGTERM_NOLOG
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
|
||||
TEST="$NAME: Option -S can turn off logging of SIGTERM"
|
||||
# Start Socat with option -S 0x0000, kill it with SIGTERM
|
||||
# When no logging entry regarding this signal is there, the test succeeded
|
||||
if ! eval $NUMCOND; then :;
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
newport tcp4 # or whatever proto, or drop this line
|
||||
CMD0="$TRACE $SOCAT $opts -S 0x0000 PIPE PIPE"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"${te}0" &
|
||||
pid0=$!
|
||||
relsleep 1 # give process time to start
|
||||
kill -TERM $pid0 2>/dev/null; wait
|
||||
if ! grep -q "exiting on signal" ${te}0; then
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
if [ "$DEBUG" ]; then echo "kill -TERM <pid>" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "kill -TERM <pid>" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
# Test if option -S turns on logging of signal 31
|
||||
NAME=SIG31_LOG
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
|
||||
TEST="$NAME: Option -S can turn on logging of signal 31"
|
||||
# Start Socat with option -S 0x80000000, kill it with -31
|
||||
# When a logging entry regarding this signal is there, the test succeeded
|
||||
if ! eval $NUMCOND; then :;
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
newport tcp4 # or whatever proto, or drop this line
|
||||
CMD0="$TRACE $SOCAT $opts -S 0x80000000 PIPE PIPE"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"${te}0" &
|
||||
pid0=$!
|
||||
relsleep 1 # give process time to start
|
||||
kill -31 $pid0 2>/dev/null; wait
|
||||
if grep -q "exiting on signal" ${te}0; then
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
if [ "$DEBUG" ]; then echo "kill -31 <pid>" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "kill -31 <pid>" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
# end of common tests
|
||||
|
||||
##################################################################################
|
||||
|
@ -16355,7 +16436,7 @@ elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
|
|||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! F=$(testfeats STDIO IP4 TCP PIPE); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE); then
|
||||
|
|
Loading…
Reference in a new issue