Option -S for controlling signals' logging
diff --git a/CHANGES b/CHANGES
index 1da4617..5b019c4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,10 @@
 	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/
diff --git a/doc/socat.yo b/doc/socat.yo
index 6a6619a..175d734 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -176,6 +176,15 @@
    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
diff --git a/socat.c b/socat.c
index 6488103..98c7e7e 100644
--- a/socat.c
+++ b/socat.c
@@ -39,6 +39,7 @@
    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 @@
    -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 @@
 	 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 @@
 
    {
       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 @@
    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 @@
    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 @@
    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:
diff --git a/test.sh b/test.sh
index 0cb66b5..963d010 100755
--- a/test.sh
+++ b/test.sh
@@ -4267,7 +4267,7 @@
 *%$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 @@
 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 @@
 # 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 @@
 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 @@
     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