From 2af0495cc6534a08d0783a1613d6c9a488ab97e6 Mon Sep 17 00:00:00 2001
From: Gerhard Rieger <gerhard@dest-unreach.org>
Date: Mon, 12 Jan 2015 21:46:16 +0100
Subject: [PATCH] Made code async-signal-safe

---
 CHANGES       |   19 +
 DEVELOPMENT   |   16 +
 Makefile.in   |    8 +-
 VERSION       |    2 +-
 compat.h      |    4 +
 config.h.in   |    6 +
 configure.in  |    5 +
 error.c       |  283 ++++++++++----
 error.h       |   34 +-
 hostan.c      |   20 +-
 procan_main.c |    8 +-
 snprinterr.c  |   85 ++++
 snprinterr.h  |   10 +
 socat.c       |   58 +--
 sslcls.c      |    6 +-
 sycls.c       |   67 +++-
 sysincludes.h |    4 +-
 test.sh       | 1022 +++++++++++++++++++++++++------------------------
 vsnprintf_r.c |  569 +++++++++++++++++++++++++++
 vsnprintf_r.h |   11 +
 xio-socket.c  |   31 +-
 xioexit.c     |    4 +
 xioshutdown.c |   15 +-
 xiosigchld.c  |   22 +-
 xiosignal.c   |   25 +-
 25 files changed, 1708 insertions(+), 626 deletions(-)
 create mode 100644 snprinterr.c
 create mode 100644 snprinterr.h
 create mode 100644 vsnprintf_r.c
 create mode 100644 vsnprintf_r.h

diff --git a/CHANGES b/CHANGES
index d42b470..7671566 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,23 @@
 
+security:
+	(CVE Id pending)
+	Fixed problems with signal handling caused by use of not async signal
+	safe functions in signal handlers that could freeze socat, allowing
+	denial of service attacks.
+	Many changes in signal handling and the diagnostic messages system were
+	applied to make the code async signal safe but still provide detailled
+	logging from signal handlers:
+	Coded function vsnprintf_r() as async signal safe incomplete substitute
+	of libc vsnprintf()
+	Coded function snprinterr() to replace %m in strings with a system error
+	message
+	Instead of gettimeofday() use clock_gettime() when available
+	Pass Diagnostic messages from signal handler per unix socket to the main
+	program flow
+	Use sigaction() instead of signal() for better control
+	Turn off nested signal handler invocations
+	Thanks to Peter Lobsinger for reporting and explaining this issue.
+
 ####################### V 1.7.2.4:
 
 corrections:
diff --git a/DEVELOPMENT b/DEVELOPMENT
index 4817956..99a82c6 100644
--- a/DEVELOPMENT
+++ b/DEVELOPMENT
@@ -204,3 +204,19 @@ PH_PREFORK,	PH_FORK,	PH_PASTFORK	# (all before/after?)
 PH_LATE						# chroot
 PH_LATE2					# su, su-d.2
 PH_PREEXEC,	PH_EXEC				# (all before)
+
+===============================================================================
+// Up to 1.7.2.4 socat used non async signal safe system and library calls in signal handlers, mostly for logging purposes. This problem was fixed in release 1.7.3.0 with the following concepts:
+
+Signal handlers set on entry and unset on return the diag_in_handler global variable. The logging system, when this variable is set, queues the text message together with errno and exit info in a UNIX datagram socket. When invoked with unset diag_in_handler it first checks if there are messages in that queue and prints them first.
+
+A async signal safe but minimal version of vsnprintf, named vsnprintf_r, was written so no value arguments need to be queued.
+
+Because strerror is not async signal safe a new function snprinterr was written that replaces the (glibc compatible) %m format with strerror output. The original errno is passed in the message queue, snprinterr is called when dequeuing messages outside of signal handler.
+
+// List of signal handlers in socat
+socat.c:socat_signal (generic, just logs and maybe exits)
+xioshutdown.c:signal_kill_pid (SIGALRM, kill child process)
+xiosigchld.c:childdied (SIGCHLD: get info, log; possibly close channel)
+xiosignal.c:socatsignalpass: cascades signal to channel child processes; w/ options sighup,sigint,sigquit
+xio-socket.c:xiosigaction_hasread: SIGUSR1,SIGCHLD, tells parent that datagram has been consumed
diff --git a/Makefile.in b/Makefile.in
index c560de6..2d5053e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -54,13 +54,13 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \
 	xio-pty.c xio-openssl.c xio-streams.c\
 	xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c
 XIOOBJS = $(XIOSRCS:.c=.o)
-UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c @FILAN@ @SYCLS@ @SSLCLS@
+UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c vsnprintf_r.c snprinterr.c @FILAN@ @SYCLS@ @SSLCLS@
 UTLOBJS = $(UTLSRCS:.c=.o)
 CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c
 OFILES = $(CFILES:.c=.o)
 PROGS = socat procan filan
 
-HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \
+HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h vsnprintf_r.h snprinterr.h compat.h \
 	xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \
 	xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \
 	xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \
@@ -114,12 +114,12 @@ depend: $(CFILES) $(HFILES)
 socat: socat.o libxio.a
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS)
 
-PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o
+PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o vsnprintf_r.o snprinterr.o
 procan: $(PROCAN_OBJS)
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS)
 
 filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o vsnprintf_r.o snprinterr.o $(CLIBS)
 
 libxio.a: $(XIOOBJS) $(UTLOBJS)
 	$(AR) r $@ $(XIOOBJS) $(UTLOBJS)
diff --git a/VERSION b/VERSION
index fbf4ea2..078d108 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-"1.7.2.4"
+"1.7.2.4+sigfix"
diff --git a/compat.h b/compat.h
index d172840..541d3d8 100644
--- a/compat.h
+++ b/compat.h
@@ -31,6 +31,10 @@
 
 /* substitute some features that might be missing on some platforms */
 
+#if !HAVE_TYPE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#endif
+
 #ifndef SHUT_RD
 #  define SHUT_RD 0
 #endif
diff --git a/config.h.in b/config.h.in
index d91ac8f..99310f0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -131,6 +131,9 @@
 /* Define if you have the ftruncate64 function */
 #undef HAVE_FTRUNCATE64
 
+/* Define if you have the clock_gettime function */
+#undef HAVE_CLOCK_GETTIME
+
 /* Define if you have the strtoll function */
 #undef HAVE_STRTOLL
 
@@ -418,6 +421,9 @@
 /* Define if you have the long long type */
 #undef HAVE_TYPE_LONGLONG
 
+/* is sig_atomic_t declared */
+#undef HAVE_TYPE_SIG_ATOMIC_T
+
 /* is socklen_t already typedef'd? */
 #undef HAVE_TYPE_SOCKLEN
 
diff --git a/configure.in b/configure.in
index 549f929..05f9b67 100644
--- a/configure.in
+++ b/configure.in
@@ -764,6 +764,8 @@ if test $sc_cv_type_longlong = yes; then
 fi
 AC_MSG_RESULT($sc_cv_type_longlong)
 
+AC_CHECK_TYPE(sig_atomic_t,AC_DEFINE(HAVE_TYPE_SIG_ATOMIC_T),,[#include "sysincludes.h"])
+
 # following builtin macro does not check unistd.h and sys/socket.h where
 # socklen_t might be defined
 #AC_CHECK_TYPE(socklen_t, int)
@@ -1316,6 +1318,9 @@ AC_CHECK_LIB(bsd, openpty,
 AC_CHECK_LIB(util, openpty,
   [LIBS="-lutil $LIBS"; AC_DEFINE(HAVE_OPENPTY)])
 
+AC_CHECK_LIB(rt, clock_gettime,
+		 [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_CLOCK_GETTIME)])
+
 dnl Search for flock()
 # with Linux it's in libc, with AIX in libbsd
 AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK),
diff --git a/error.c b/error.c
index b1ee304..1770d50 100644
--- a/error.c
+++ b/error.c
@@ -1,30 +1,21 @@
 /* source: error.c */
-/* Copyright Gerhard Rieger 2001-2011 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 /* the logging subsystem */
 
 #include "config.h"
+#include "sysincludes.h"
 
-#include <stdarg.h>
-#include <stdlib.h>
-#include <errno.h>
-#if HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
-#include <sys/utsname.h>
-#include <time.h>	/* time_t, strftime() */
-#include <sys/time.h>	/* gettimeofday() */
-#include <stdio.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #include "mytypes.h"
 #include "compat.h"
 #include "utils.h"
+#include "vsnprintf_r.h"
+#include "snprinterr.h"
 
 #include "error.h"
+#include "sysincludes.h"
+#include "sycls.h"
 
 /* translate MSG level to SYSLOG level */
 int syslevel[] = {
@@ -49,11 +40,27 @@ struct diag_opts {
 } ;
 
 
+static void _diag_exit(int status);
+
+
 struct diag_opts diagopts =
   { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0 } ;
 
+static void msg2(
+#if HAVE_CLOCK_GETTIME
+		 struct timespec *now,
+#elif HAVE_GETTIMEOFDAY
+		 struct timeval *now,
+#else
+		 time_t *now,
+#endif
+		 int level, int exitcode, int handler, const char *text);
 static void _msg(int level, const char *buff, const char *syslp);
 
+sig_atomic_t diag_in_handler;	/* !=0 indicates to msg() that in signal handler */
+sig_atomic_t diag_immediate_msg;	/* !=0 prints messages even from within signal handler instead of deferring them */
+sig_atomic_t diag_immediate_exit;	/* !=0 calls exit() from diag_exit() even when in signal handler. For system() */
+
 static struct wordent facilitynames[] = {
    {"auth",     (void *)LOG_AUTH},
 #ifdef LOG_AUTHPRIV
@@ -87,15 +94,38 @@ static struct wordent facilitynames[] = {
    {"uucp",     (void *)LOG_UUCP}
 } ;
 
+/* serialize message for sending from signal handlers */
+struct sermsg {
+   int severity;
+#if HAVE_CLOCK_GETTIME
+   struct timespec ts;
+#else
+   struct timeval tv;
+#endif
+} ;
 
 static int diaginitialized;
+static int diag_sock_send = -1;
+static int diag_sock_recv = -1;
+static int diag_msg_avail = 0;	/* !=0: messages from within signal handler may be waiting */
+
+
 static int diag_init(void) {
+   int handlersocks[2];
+
    if (diaginitialized) {
       return 0;
    }
    diaginitialized = 1;
    /* gcc with GNU libc refuses to set this in the initializer */
    diagopts.logfile = stderr;
+   if (socketpair(AF_UNIX, SOCK_DGRAM, 0, handlersocks) < 0) {
+      diag_sock_send = -1;
+      diag_sock_recv = -1;
+      return -1;
+   }
+   diag_sock_send = handlersocks[1];
+   diag_sock_recv = handlersocks[0];
    return 0;
 }
 #define DIAG_INIT ((void)(diaginitialized || diag_init()))
@@ -180,67 +210,104 @@ const char *diag_get_string(char what) {
    return NULL;
 }
 
+
 /* Linux and AIX syslog format:
 Oct  4 17:10:37 hostname socat[52798]: D signal(13, 1)
 */
 void msg(int level, const char *format, ...) {
-#if HAVE_GETTIMEOFDAY || 1
-   struct timeval now;
-   int result;
-   time_t nowt;
-#else /* !HAVE_GETTIMEOFDAY */
-   time_t now;
-#endif /* !HAVE_GETTIMEOFDAY */
+   struct diag_dgram diag_dgram;
+   va_list ap;
+
+   /* does not perform a system call if nothing todo, thanks diag_msg_avail */
+
+   diag_dgram._errno = errno;	/* keep for passing from signal handler to sock.
+				   reason is that strerror is definitely not
+				   async-signal-safe */
+   DIAG_INIT;
+
+   /* in normal program flow (not in signal handler) */
+   /* first flush the queue of datagrams from the socket */
+   if (diag_msg_avail && !diag_in_handler) {
+      diag_msg_avail = 0;	/* _before_ flush to prevent inconsistent state when signal occurs inbetween */
+      diag_flush();
+   }
+
+   if (level < diagopts.msglevel)  { va_end(ap); return; }
+   va_start(ap, format);
+
+   /* we do only a minimum in the outer parts which may run in a signal handler
+      these are: get actual time, level, serialized message  and write them to socket
+   */
+   diag_dgram.op = DIAG_OP_MSG;
+#if HAVE_CLOCK_GETTIME
+   clock_gettime(CLOCK_REALTIME, &diag_dgram.now);
+#elif HAVE_GETTIMEOFDAY
+   gettimeofday(&diag_dgram.now, NULL);
+#else
+   diag_dgram.now = time(NULL);
+#endif
+   diag_dgram.level = level;
+   diag_dgram.exitcode = diagopts.exitstatus;
+   vsnprintf_r(diag_dgram.text, sizeof(diag_dgram.text), format, ap);
+   if (diag_in_handler && !diag_immediate_msg) {
+      send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN + strlen(diag_dgram.text)+1, MSG_DONTWAIT|MSG_NOSIGNAL);
+      diag_msg_avail = 1;
+      va_end(ap);
+      return;
+   }
+
+   msg2(&diag_dgram.now, diag_dgram.level, diagopts.exitstatus, 0, diag_dgram.text);
+   va_end(ap); return;
+}
+
+void msg2(
+#if HAVE_CLOCK_GETTIME
+	  struct timespec *now,
+#elif HAVE_GETTIMEOFDAY
+	  struct timeval *now,
+#else
+	  time_t *now,
+#endif
+	  int level,		/* E_INFO... */
+	  int exitcode,		/* on exit use this exit code */
+	  int handler,		/* message comes from signal handler */
+	  const char *text) {
+   time_t epoch;
+   unsigned long micros;
 #if HAVE_STRFTIME
    struct tm struct_tm;
 #endif
 #define BUFLEN 512
    char buff[BUFLEN], *bufp, *syslp;
    size_t bytes;
-   va_list ap;
 
-   DIAG_INIT;
-   if (level < diagopts.msglevel)  return;
-   va_start(ap, format);
-#if HAVE_GETTIMEOFDAY || 1
-   result = gettimeofday(&now, NULL);
-   if (result < 0) {
-      /* invoking msg() might create endless recursion; by hand instead */
-      sprintf(buff, "cannot read time:   %s["F_pid"] E %s",
-	      diagopts.progname, getpid(), strerror(errno));
-      _msg(LOG_ERR, buff, strstr(buff, " E "+1));
-      strcpy(buff, "unknown time        ");  bytes = 20;
-   } else {
-      nowt = now.tv_sec;
-#if HAVE_STRFTIME
-      if (diagopts.micros) {
- 	 bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime_r(&nowt, &struct_tm));
-	 bytes += sprintf(buff+19, "."F_tv_usec" ", now.tv_usec);
-      } else {
-	 bytes =
-	    strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&nowt, &struct_tm));
-      }
+#if HAVE_CLOCK_GETTIME
+   epoch = now->tv_sec;
+#elif HAVE_GETTIMEOFDAY
+   epoch = now->tv_sec;
 #else
-      strcpy(buff, ctime(&nowt));
-      bytes = strlen(buff);
+   epoch = *now;
 #endif
-   }
-#else /* !HAVE_GETTIMEOFDAY */
-   now = time(NULL);  if (now == (time_t)-1) {
-      /* invoking msg() might create endless recursion; by hand instead */
-      sprintf(buff, "cannot read time:   %s["F_pid"] E %s",
-	      diagopts.progname, getpid(), strerror(errno));
-      _msg(LOG_ERR, buff, strstr(buff, " E "+1));
-      strcpy(buff, "unknown time        ");  bytes = 20;
-   } else {
 #if HAVE_STRFTIME
-      bytes = strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&now, &struct_tm));
+   bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime_r(&epoch, &struct_tm));
+   buff[bytes] = '\0';
 #else
-      strcpy(buff, ctime(&now));
-      bytes = strlen(buff);
+   bytes = snprintf(buff, 11, F_time, epoch);
 #endif
+   if (diagopts.micros) {
+#if HAVE_CLOCK_GETTIME
+      micros = now->tv_nsec/1000;
+#elif HAVE_GETTIMEOFDAY
+      micros = now->tv_usec;
+#else
+      micros = 0;
+#endif
+      bytes += sprintf(buff+19, ".%06lu ", micros);
+   } else {
+      buff[19] = ' '; buff[20] = '\0';
    }
-#endif /* !HAVE_GETTIMEOFDAY */
+   bytes = strlen(buff);
+
    bufp = buff + bytes;
    if (diagopts.withhostname) {
       bytes = sprintf(bufp, "%s ", diagopts.hostname), bufp+=bytes;
@@ -249,19 +316,20 @@ void msg(int level, const char *format, ...) {
    bufp += bytes;
    syslp = bufp;
    *bufp++ = "DINWEF"[level];
+#if 0 /* only for debugging socat */
+   if (handler)  bufp[-1] = tolower(bufp[-1]); /* for debugging, low chars indicate messages from signal handlers */
+#endif
    *bufp++ = ' ';
-   vsnprintf(bufp, BUFLEN-(bufp-buff)-1, format, ap);
+   strncpy(bufp, text, BUFLEN-(bufp-buff)-1);
    strcat(bufp, "\n");
    _msg(level, buff, syslp);
    if (level >= diagopts.exitlevel) {
-      va_end(ap);
       if (E_NOTICE >= diagopts.msglevel) {
-	 sprintf(syslp, "N exit(1)\n");
+	 snprintf_r(syslp, 16, "N exit(%d)\n", exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1));
 	 _msg(E_NOTICE, buff, syslp);
       }
-      exit(diagopts.exitstatus ? diagopts.exitstatus : 1);
+      exit(exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1));
    }
-   va_end(ap);
 }
 
 
@@ -276,6 +344,44 @@ static void _msg(int level, const char *buff, const char *syslp) {
 }
 
 
+/* handle the messages in the queue */
+void diag_flush(void) {
+   struct diag_dgram recv_dgram;
+   char exitmsg[20];
+   while (recv(diag_sock_recv, &recv_dgram, sizeof(recv_dgram)-1, MSG_DONTWAIT) > 0) {
+      recv_dgram.text[TEXTLEN-1] = '\0';
+      switch (recv_dgram.op) {
+      case DIAG_OP_EXIT:
+	 /* we want the actual time, not when this dgram was sent */
+#if HAVE_CLOCK_GETTIME
+	 clock_gettime(CLOCK_REALTIME, &recv_dgram.now);
+#elif HAVE_GETTIMEOFDAY
+	 gettimeofday(&recv_dgram.now, NULL);
+#else
+	 recv_dgram.now = time(NULL);
+#endif
+	 if (E_NOTICE >= diagopts.msglevel) {
+	    snprintf_r(exitmsg, sizeof(exitmsg), "exit(%d)", recv_dgram.exitcode?recv_dgram.exitcode:1);
+	    msg2(&recv_dgram.now, E_NOTICE, recv_dgram.exitcode?recv_dgram.exitcode:1, 1, exitmsg);
+	 }
+	 exit(recv_dgram.exitcode?recv_dgram.exitcode:1);
+      case DIAG_OP_MSG:
+	 if (recv_dgram._errno) {
+	    /* there might be a %m control in the string (glibc compatible,
+	       replace with strerror(...errno) ) */
+	    char text[TEXTLEN];
+	    errno = recv_dgram._errno;
+	    snprinterr(text, TEXTLEN, recv_dgram.text);
+	    msg2(&recv_dgram.now, recv_dgram.level, recv_dgram.exitcode, 1, text);
+	 } else {
+	    msg2(&recv_dgram.now, recv_dgram.level, recv_dgram.exitcode, 1, recv_dgram.text);
+	 }
+	 break;
+      }
+   }
+}
+
+
 /* use a new log output file descriptor that is dup'ed from the current one.
    this is useful when socat logs to stderr but fd 2 should be redirected to
    serve other purposes */
@@ -295,3 +401,52 @@ int diag_dup(void) {
    }
    return newfd;
 }
+
+
+/* this function is kind of async-signal-safe exit(). When invoked from signal
+   handler it defers exit. */
+void diag_exit(int status) {
+   struct diag_dgram diag_dgram;
+
+   if (diag_in_handler && !diag_immediate_exit) {
+      diag_dgram.op = DIAG_OP_EXIT;
+      diag_dgram.exitcode = status;
+      send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN, MSG_DONTWAIT|MSG_NOSIGNAL);
+      return;
+   }
+   _diag_exit(status);
+}
+
+static void _diag_exit(int status) {
+   Exit(status);
+}
+
+
+/* a function that appears to the application like select() but that also
+   monitors the diag socket diag_sock_recv and processes its messages.
+   Do not call from within a signal handler. */
+int diag_select(int nfds, fd_set *readfds, fd_set *writefds,
+		 fd_set *exceptfds, struct timeval *timeout) {
+   int result;
+   fd_set save_readfds, save_writefds, save_exceptfds;
+
+   if (readfds)   { memcpy(&save_readfds,   readfds,   sizeof(*readfds)); }
+   if (writefds)  { memcpy(&save_writefds,  writefds,  sizeof(*writefds)); }
+   if (exceptfds) { memcpy(&save_exceptfds, exceptfds, sizeof(*exceptfds)); }
+
+   while (1) {
+      FD_SET(diag_sock_recv, readfds);
+      result = Select(nfds, readfds, writefds,
+		       exceptfds, timeout);
+     if (!FD_ISSET(diag_sock_recv, readfds)) {
+	 /* select terminated not due to diag_sock_recv, normalt continuation */
+	 break;
+      }
+      diag_flush();
+      if (readfds)   { memcpy(readfds,   &save_readfds,   sizeof(*readfds)); }
+      if (writefds)  { memcpy(writefds,  &save_writefds,  sizeof(*writefds)); }
+      if (exceptfds) { memcpy(exceptfds, &save_exceptfds, sizeof(*exceptfds)); }
+   }
+   return result;
+}
+
diff --git a/error.h b/error.h
index 385738c..0c5f2c4 100644
--- a/error.h
+++ b/error.h
@@ -1,5 +1,5 @@
 /* source: error.h */
-/* Copyright Gerhard Rieger 2001-2008 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 #ifndef __error_h_included
@@ -13,6 +13,7 @@
 #define E_ERROR  4	/* errors */
 #define E_FATAL  5	/* emergency abort */
 
+#define F_strerror "%m"	/* a pseudo format, replaced by strerror(errno) */
 
 /* here are the macros for diag invocation; use WITH_MSGLEVEL to specify the
    lowest priority that is compiled into your program */
@@ -204,6 +205,33 @@
 #endif /* !(WITH_MSGLEVEL <= E_FATAL) */
 
 
+enum diag_op {
+   DIAG_OP_MSG,		/* a diagnostic message */
+   DIAG_OP_EXIT,	/* exit the program */
+} ;
+
+/* datagram for communication between outer msg() call from signal handler to
+   inner msg() call in normal flow */
+#  define TEXTLEN 480
+struct diag_dgram {
+   enum diag_op op;
+#if HAVE_CLOCK_GETTIME
+   struct timespec now;
+#elif HAVE_GETTIMEOFDAY
+   struct timeval now;
+#else
+   time_t now;
+#endif
+   int level;		/* E_FATAL, ... E_DEBUG */
+   int _errno;		/* for glibc %m format */
+   int exitcode;	/* if exiting take this num */
+   char text[TEXTLEN];
+} ;
+
+extern sig_atomic_t diag_in_handler;
+extern int diag_immediate_msg;
+extern int diag_immediate_exit;
+
 extern void diag_set(char what, const char *arg);
 extern void diag_set_int(char what, int arg);
 extern int diag_get_int(char what);
@@ -211,5 +239,9 @@ extern const char *diag_get_string(char what);
 extern int diag_dup(void);
 extern int diag_dup2(int newfd);
 extern void msg(int level, const char *format, ...);
+extern void diag_flush(void);
+extern void diag_exit(int status);
+extern int diag_select(int nfds, fd_set *readfds, fd_set *writefds,
+		       fd_set *exceptfds, struct timeval *timeout);
 
 #endif /* !defined(__error_h_included) */
diff --git a/hostan.c b/hostan.c
index 5957c29..d1e9bf5 100644
--- a/hostan.c
+++ b/hostan.c
@@ -1,5 +1,5 @@
 /* source: hostan.c */
-/* Copyright Gerhard Rieger 2006-2011 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 /* the subroutine hostan makes a "HOST ANalysis". It gathers information
@@ -17,9 +17,27 @@
 
 #include "hostan.h"
 
+#include "error.h"
+
 static int iffan(FILE *outfile);
 
 int hostan(FILE *outfile) {
+   fprintf(outfile, "\nC TYPE SIZES\n");
+   fprintf(outfile, "sizeof(char)      = %u\n", (unsigned int)sizeof(char));
+   fprintf(outfile, "sizeof(short)     = %u\n", (unsigned int)sizeof(short));
+   fprintf(outfile, "sizeof(int)       = %u\n", (unsigned int)sizeof(int));
+   fprintf(outfile, "sizeof(long)      = %u\n", (unsigned int)sizeof(long));
+#if HAVE_TYPE_LONGLONG
+   fprintf(outfile, "sizeof(long long) = %u\n", (unsigned int)sizeof(long long));
+#endif
+   fprintf(outfile, "sizeof(size_t)    = %u\n", (unsigned int)sizeof(size_t));
+#include <sys/time.h>	/* select(); OpenBSD: struct timespec */
+   fprintf(outfile, "sizeof(struct timespec)      = %u\n", (unsigned int)sizeof(struct timespec));
+   fprintf(outfile, "sizeof(struct diag_dgram)      = %u\n", (unsigned int)sizeof(struct diag_dgram));
+   fprintf(outfile, "((struct diag_dgram *)0)->op-((struct diag_dgram *)0)     = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->op)-(char *)((struct diag_dgram *)0)));
+   fprintf(outfile, "((struct diag_dgram *)0)->now-((struct diag_dgram *)0)     = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->now)-(char *)((struct diag_dgram *)0)));
+   fprintf(outfile, "((struct diag_dgram *)0)->exitcode-((struct diag_dgram *)0)     = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->exitcode)-(char *)((struct diag_dgram *)0)));
+   fprintf(outfile, "((struct diag_dgram *)0)->text-((struct diag_dgram *)0)     = %u\n", (unsigned int)((((struct diag_dgram *)0)->text)-(char *)((struct diag_dgram *)0)));
 #if _WITH_SOCKET
    fprintf(outfile, "\nIP INTERFACES\n");
    iffan(outfile);
diff --git a/procan_main.c b/procan_main.c
index b482306..edff24a 100644
--- a/procan_main.c
+++ b/procan_main.c
@@ -1,12 +1,18 @@
 /* source: procan_main.c */
-/* Copyright Gerhard Rieger 2001-2008 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 const char copyright[] = "procan by Gerhard Rieger - send bug reports to socat@dest-unreach.org";
 
+#include <signal.h>	/* sig_atomic_t for error.h */
+#include <time.h>	/* struct timespec for error.h */
 #include <stdlib.h>	/* strtoul() */
 #include <string.h>
 #include <stdio.h>
+#include "config.h"
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>	/* select(), fdset on FreeBSD */
+#endif
 #include "mytypes.h"
 #include "error.h"
 #include "procan.h"
diff --git a/snprinterr.c b/snprinterr.c
new file mode 100644
index 0000000..c064e56
--- /dev/null
+++ b/snprinterr.c
@@ -0,0 +1,85 @@
+/* snprinterr.c */
+/* Copyright Gerhard Rieger */
+
+/* a function similar to vsnprintf() but it just handles %m */
+
+#include "config.h"
+
+#include <stddef.h>	/* ptrdiff_t */
+#include <ctype.h>	/* isdigit() */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#include <sys/utsname.h>
+#include <time.h>	/* time_t, strftime() */
+#include <sys/time.h>	/* gettimeofday() */
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "snprinterr.h"
+
+#define HAVE_STRERROR_R 0
+/* replace %m in format with actual strerror() message, write result to *str.
+   keep other % formats unchanged!
+   writes at most size chars including the terminating \0 to *str
+   returns the number of bytes in the output without terminating \0
+   result is always \0 terminated except when size==0
+ */
+int snprinterr(char *str, size_t size, const char *format) {
+   char c;
+   int full = 0;	/* 1 means: there is no space left in * str for more data or \0 */
+   int count = 0;
+   if (size == 0)  return 0;
+   if (count >= size)  full = 1;
+   while (c = *format++) {
+      if (c == '%') {
+	 c = *format++;
+	 switch (c) {
+	 case '\0':
+	    ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
+	    break;
+	 default:
+	    ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
+	    ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
+	    break;
+	 case 'm':
+	    {
+#if HAVE_STRERROR_R
+#              define BUFLEN 64
+	       char buf[BUFLEN] = "";
+#endif /* HAVE_STRERROR_R */
+	       char *bufp;
+#if !HAVE_STRERROR_R
+	       bufp = strerror(errno);
+#else
+	       /* there are two versions floating around... */
+#  if 1	/* GNU version */
+	       bufp = strerror_r(errno, buf, BUFLEN);
+#  else	/* standard version */
+	       strerror_r(errno, buf, BUFLEN);
+	       bufp = buf;
+#  endif
+#endif /* HAVE_STRERROR_R */
+	       while ((c = *bufp++) != '\0') {
+		  ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
+	       }
+	    }
+	    c = ' ';	/* not \0 ! */
+	    break;
+	 }
+	 if (c == '\0')  break;
+      } else {
+	 ++count; if (!full) { (*str++ = c); if (count+1 >= size)  full = 1; }
+      }
+   }
+   *str++ = '\0';	/* always write terminating \0 */
+   return count;
+#undef BUFLEN
+}
+
diff --git a/snprinterr.h b/snprinterr.h
new file mode 100644
index 0000000..1fc72ed
--- /dev/null
+++ b/snprinterr.h
@@ -0,0 +1,10 @@
+/* source: snprinterr.h */
+/* Copyright Gerhard Rieger */
+/* Published under the GNU General Public License V.2, see file COPYING */
+
+#ifndef __snprinterr_h_included
+#define __snprinterr_h_included 1
+
+int snprinterr(char *str, size_t size, const char *format);
+
+#endif /* !defined(__snprinterr_h_included) */
diff --git a/socat.c b/socat.c
index 5062914..c9b5952 100644
--- a/socat.c
+++ b/socat.c
@@ -1,5 +1,5 @@
 /* source: socat.c */
-/* Copyright Gerhard Rieger 2001-2010 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 /* this is the main source, including command line option parsing, general
@@ -285,18 +285,23 @@ int main(int argc, const char *argv[]) {
    }
 #endif /* WITH_MSGLEVEL <= E_DEBUG */
 
-   /* not sure what signal should print a message */
-   Signal(SIGHUP, socat_signal);
-   Signal(SIGINT, socat_signal);
-   Signal(SIGQUIT, socat_signal);
-   Signal(SIGILL, socat_signal);
-   /* SIGABRT for assert; catching caused endless recursion on assert in libc
-      (tzfile.c:498: __tzfile_compute: Assertion 'num_types == 1' failed.) */
-   /*Signal(SIGABRT, socat_signal);*/
-   Signal(SIGBUS, socat_signal);
-   Signal(SIGFPE, socat_signal);
-   Signal(SIGSEGV, socat_signal);
-   Signal(SIGTERM, socat_signal);
+   {
+      struct sigaction act;
+      sigfillset(&act.sa_mask);
+      act.sa_flags = 0;
+      act.sa_handler = socat_signal;
+      /* not sure which signals should be cauhgt 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);
+   }
+   Signal(SIGPIPE, SIG_IGN);
 
    /* set xio hooks */
    xiohook_newchild = &socat_newchild;
@@ -546,12 +551,6 @@ int closing = 0;	/* 0..no eof yet, 1..first eof just occurred,
 int socat(const char *address1, const char *address2) {
    int mayexec;
 
-#if 1
-   if (Signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
-      Warn1("signal(SIGPIPE, SIG_IGN): %s", strerror(errno));
-   }
-#endif
-
    if (socat_opts.lefttoright) {
       if ((sock1 = xioopen(address1, XIO_RDONLY|XIO_MAYFORK|XIO_MAYCHILD|XIO_MAYCONVERT)) == NULL) {
 	 return -1;
@@ -680,7 +679,9 @@ int childleftdata(xiofile_t *xfd) {
 	 in.revents = 0;
       }
       do {
+	 int _errno;
 	 retval = xiopoll(&in, 1, &timeout);
+	 _errno = errno; diag_flush(); errno = _errno;	/* just in case it's not debug level and Msg() not been called */
       } while (retval < 0 && errno == EINTR);
 
       if (retval < 0) {
@@ -1405,6 +1406,10 @@ int cv_newline(unsigned char **buff, ssize_t *bufsiz,
 }
 
 void socat_signal(int signum) {
+   int _errno;
+   _errno = errno;
+   diag_in_handler = 1;
+   Notice1("socat_signal(): handling signal %d", signum);
    switch (signum) {
    case SIGQUIT:
    case SIGILL:
@@ -1423,7 +1428,11 @@ void socat_signal(int signum) {
    case SIGINT:
       Notice1("exiting on signal %d", signum); break;
    }
-   Exit(128+signum);
+   //Exit(128+signum);
+   Notice1("socat_signal(): finishing signal %d", signum);
+   diag_exit(128+signum);	/*!!! internal cleanup + _exit() */
+   diag_in_handler = 0;
+   errno = _errno;
 }
 
 /* this is the callback when the child of an address died */
@@ -1478,8 +1487,13 @@ static void socat_unlock(void) {
    if (!havelock)  return;
    if (socat_opts.lock.lockfile) {
       if (Unlink(socat_opts.lock.lockfile) < 0) {
-	 Warn2("unlink(\"%s\"): %s",
-	       socat_opts.lock.lockfile, strerror(errno));
+	 if (!diag_in_handler) {
+	    Warn2("unlink(\"%s\"): %s",
+	          socat_opts.lock.lockfile, strerror(errno));
+	 } else {
+	    Warn1("unlink(\"%s\"): "F_strerror,
+	          socat_opts.lock.lockfile);
+	 }
       } else {
 	 Info1("released lock \"%s\"", socat_opts.lock.lockfile);
       }
diff --git a/sslcls.c b/sslcls.c
index 9fe7fb8..7391abc 100644
--- a/sslcls.c
+++ b/sslcls.c
@@ -1,5 +1,5 @@
 /* source: sslcls.c */
-/* Copyright Gerhard Rieger 2001-2011 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 /* explicit system call and C library trace function, for those who miss strace
@@ -123,8 +123,8 @@ int sycSSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
 				     const char *CApath) {
    int result;
    Debug7("SSL_CTX_load_verify_locations(%p, %s%s%s, %s%s%s)", ctx,
-	  CAfile?"\"":"", CAfile?CAfile:NULL, CAfile?"\"":"",
-	  CApath?"\"":"", CApath?CApath:NULL, CApath?"\"":"");
+	  CAfile?"\"":"", CAfile?CAfile:"", CAfile?"\"":"",
+	  CApath?"\"":"", CApath?CApath:"", CApath?"\"":"");
    result = SSL_CTX_load_verify_locations(ctx, CAfile, CApath);
    Debug1("SSL_CTX_load_verify_locations() -> %d", result);
    return result;
diff --git a/sycls.c b/sycls.c
index 4c38d89..c87237d 100644
--- a/sycls.c
+++ b/sycls.c
@@ -36,9 +36,11 @@ mode_t Umask(mode_t mask) {
 
 int Open(const char *pathname, int flags, mode_t mode) {
    int result, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug3("open(\"%s\", 0%o, 0%03o)", pathname, flags, mode);
    result = open(pathname, flags, mode);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Info4("open(\"%s\", 0%o, 0%03o) -> %d", pathname, flags, mode, result);
    errno = _errno;
    return result;
@@ -516,9 +518,11 @@ int Pipe(int filedes[2]) {
 ssize_t Read(int fd, void *buf, size_t count) {
    ssize_t result;
    int _errno;
+   if (!diag_in_handler) diag_flush();
    Debug3("read(%d, %p, "F_Zu")", fd, buf, count);
    result = read(fd, buf, count);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("read -> "F_Zd, result);
    errno = _errno;
    return result;
@@ -527,9 +531,11 @@ ssize_t Read(int fd, void *buf, size_t count) {
 ssize_t Write(int fd, const void *buf, size_t count) {
    ssize_t result;
    int _errno;
+   if (!diag_in_handler) diag_flush();
    Debug3("write(%d, %p, "F_Zu")", fd, buf, count);
    result = write(fd, buf, count);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("write -> "F_Zd, result);
    errno = _errno;
    return result;
@@ -537,8 +543,10 @@ ssize_t Write(int fd, const void *buf, size_t count) {
 
 int Fcntl(int fd, int cmd) {
    int result, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug2("fcntl(%d, %d)", fd, cmd);
    result = fcntl(fd, cmd);
+   if (!diag_in_handler) diag_flush();
    _errno = errno;
    Debug1("fcntl() -> %d", result);
    errno = _errno;
@@ -547,9 +555,11 @@ int Fcntl(int fd, int cmd) {
 
 int Fcntl_l(int fd, int cmd, long arg) {
    int result, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug3("fcntl(%d, %d, %ld)", fd, cmd, arg);
    result = fcntl(fd, cmd, arg);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("fcntl() -> %d", result);
    errno = _errno;
    return result;
@@ -557,10 +567,12 @@ int Fcntl_l(int fd, int cmd, long arg) {
 
 int Fcntl_lock(int fd, int cmd, struct flock *l) {
    int result, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug7("fcntl(%d, %d, {type=%hd,whence=%hd,start="F_off",len="F_off",pid="F_pid"})",
 	  fd, cmd, l->l_type, l->l_whence, l->l_start, l->l_len, l->l_pid);
    result = fcntl(fd, cmd, l);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("fcntl() -> %d", result);
    errno = _errno;
    return result;
@@ -591,9 +603,11 @@ int Ftruncate64(int fd, off64_t length) {
 #if HAVE_FLOCK
 int Flock(int fd, int operation) {
    int retval, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug2("flock(%d, %d)", fd, operation);
    retval = flock(fd, operation);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("flock() -> %d", retval);
    errno = _errno;
    return retval;
@@ -602,6 +616,7 @@ int Flock(int fd, int operation) {
 
 int Ioctl(int d, int request, void *argp) {
    int retval, _errno;
+   if (!diag_in_handler) diag_flush();
    if (argp > (void *)0x10000) {	/* fuzzy...*/
       Debug4("ioctl(%d, 0x%x, %p{%lu})", d, request, argp, *(unsigned long *)argp);
    } else {
@@ -609,6 +624,7 @@ int Ioctl(int d, int request, void *argp) {
    }
    retval = ioctl(d, request, argp);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("ioctl() -> %d", retval);
    errno = _errno;
    return retval;
@@ -707,7 +723,8 @@ int Chmod(const char *path, mode_t mode) {
 #if HAVE_POLL
 /* we only show the first struct pollfd; hope this is enough for most cases. */
 int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
-   int result;
+   int _errno, result;
+   if (!diag_in_handler) diag_flush();
    if (nfds == 4) {
       Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, %u, %d)",
 	      ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events,
@@ -717,12 +734,15 @@ int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
       Debug4("poll({%d,0x%02hx,}, , %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout);
    }
    result = poll(ufds, nfds, timeout);
+   _errno = errno;
+   if (!diag_in_handler) diag_flush();
    if (nfds == 4) {
       Debug5("poll(, {,,0x%02hx}{,,0x%02hx}{,,0x%02hx}{,,0x%02hx}) -> %d",
 	     ufds[0].revents, ufds[1].revents, ufds[2].revents, ufds[3].revents, result);
    } else {
       Debug2("poll(, {,,0x%02hx}) -> %d", ufds[0].revents, result);
    }
+   errno = _errno;
    return result;
 }
 #endif /* HAVE_POLL */
@@ -732,34 +752,38 @@ int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
 int Select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 	   struct timeval *timeout) {
    int result, _errno;
+   if (!diag_in_handler) diag_flush();
 #if HAVE_FDS_BITS
    Debug7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu."F_tv_usec")",
-	  n, readfds->fds_bits[0], writefds->fds_bits[0],
-	  exceptfds->fds_bits[0],
+	  n, readfds?readfds->fds_bits[0]:0, writefds?writefds->fds_bits[0]:0,
+	  exceptfds?exceptfds->fds_bits[0]:0,
 	  timeout?"&":"NULL/", timeout?timeout->tv_sec:0,
 	  timeout?timeout->tv_usec:0);
 #else
    Debug7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu.%06u)",
-	  n, readfds->__fds_bits[0], writefds->__fds_bits[0],
-	  exceptfds->__fds_bits[0],
+	  n, readfds?readfds->__fds_bits[0]:0, writefds?writefds->__fds_bits[0]:0,
+	  exceptfds?exceptfds->__fds_bits[0]:0,
 	  timeout?"&":"NULL/", timeout?timeout->tv_sec:0,
 	  timeout?timeout->tv_usec:0);
 #endif
    result = select(n, readfds, writefds, exceptfds, timeout);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
 #if HAVE_FDS_BITS
    Debug7("select -> (, 0x%lx, 0x%lx, 0x%lx, %s%lu."F_tv_usec"), %d",
-	  readfds->fds_bits[0], writefds->fds_bits[0], exceptfds->fds_bits[0],
+	  readfds?readfds->fds_bits[0]:0, writefds?writefds->fds_bits[0]:0,
+	  exceptfds?exceptfds->fds_bits[0]:0,
 	  timeout?"&":"NULL/", timeout?timeout->tv_sec:0,
 	  timeout?timeout->tv_usec:0, result);
 #else
    Debug7("select -> (, 0x%lx, 0x%lx, 0x%lx, %s%lu.%06u), %d",
-	  readfds->__fds_bits[0], writefds->__fds_bits[0],
-	  exceptfds->__fds_bits[0],
+	  readfds?readfds->__fds_bits[0]:0, writefds?writefds->__fds_bits[0]:0,
+	  exceptfds?exceptfds->__fds_bits[0]:0,
 	  timeout?"&":"NULL/", timeout?timeout->tv_sec:0,
 	  timeout?timeout->tv_usec:0, result);
 #endif
    errno = _errno;
+
    return result;
 }
 
@@ -777,9 +801,11 @@ pid_t Fork(void) {
 pid_t Waitpid(pid_t pid, int *status, int options) {
    int _errno;
    pid_t retval;
+   if (!diag_in_handler) diag_flush();
    Debug3("waitpid("F_pid", %p, %d)", pid, status, options);
    retval = waitpid(pid, status, options);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug2("waitpid(, {%d}, ) -> "F_pid, *status, retval);
    errno = _errno;
    return retval;
@@ -868,7 +894,9 @@ int Execvp(const char *file, char *const argv[]) {
 int System(const char *string) {
    int result, _errno;
    Debug1("system(\"%s\")", string);
+   diag_immediate_exit = 1;
    result = system(string);
+   diag_immediate_exit = 0;
    _errno = errno;
    Debug1("system() -> %d", result);
    errno = _errno;
@@ -917,6 +945,7 @@ int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) {
    int result, _errno;
    char infobuff[256];
 
+   if (!diag_in_handler) diag_flush();
    /*sockaddr_info(serv_addr, infobuff, sizeof(infobuff));
    Debug3("connect(%d, %s, "F_Zd")", sockfd, infobuff, addrlen);*/
 #if 0
@@ -939,6 +968,7 @@ int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) {
 #endif
    result = connect(sockfd, serv_addr, addrlen);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("connect() -> %d", result);
    errno = _errno;
    return result;
@@ -961,10 +991,17 @@ int Listen(int s, int backlog) {
 /* don't forget to handle EINTR when using Accept() ! */
 int Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
    int result, _errno;
-
+   fd_set accept_s;
+   if (!diag_in_handler) diag_flush();
+   FD_ZERO(&accept_s);
+   FD_SET(s, &accept_s);
+   if (diag_select(s+1, &accept_s, NULL, NULL, NULL) < 0) {
+      return -1;
+   }
    Debug3("accept(%d, %p, %p)", s, addr, addrlen);
    result = accept(s, addr, addrlen);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    if (result >= 0) {
       char infobuff[256];
       sockaddr_info(addr, *addrlen, infobuff, sizeof(infobuff));
@@ -1051,9 +1088,11 @@ int Setsockopt(int s, int level, int optname, const void *optval, int optlen) {
 #if _WITH_SOCKET
 int Recv(int s, void *buf, size_t len, int flags) {
    int retval, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug4("recv(%d, %p, "F_Zu", %d)", s, buf, len, flags);
    retval = recv(s, buf, len, flags);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("recv() -> %d", retval);
    errno = _errno;
    return retval;
@@ -1065,10 +1104,12 @@ int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from,
 	     socklen_t *fromlen) {
    int retval, _errno;
    char infobuff[256];
+   if (!diag_in_handler) diag_flush();
    Debug6("recvfrom(%d, %p, "F_Zu", %d, %p, "F_socklen")",
 	  s, buf, len, flags, from, *fromlen);
    retval = recvfrom(s, buf, len, flags, from, fromlen);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    if (from) {
       Debug4("recvfrom(,,,, {%d,%s}, "F_socklen") -> %d",
 	     from->sa_family,
@@ -1085,6 +1126,7 @@ int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from,
 #if _WITH_SOCKET
 int Recvmsg(int s, struct msghdr *msgh, int flags) {
    int retval, _errno;
+   if (!diag_in_handler) diag_flush();
    char infobuff[256];
 #if defined(HAVE_STRUCT_MSGHDR_MSGCONTROL) && defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) && defined(HAVE_STRUCT_MSGHDR_MSGFLAGS)
    Debug10("recvmsg(%d, %p{%p,%u,%p,"F_Zu",%p,"F_Zu",%d}, %d)", s, msgh,
@@ -1097,6 +1139,7 @@ int Recvmsg(int s, struct msghdr *msgh, int flags) {
 #endif
    retval = recvmsg(s, msgh, flags);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
 #if defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN)
    Debug5("recvmsg(, {%s,%u,,"F_Zu",,"F_Zu",}, ) -> %d",
 	  msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL",
@@ -1116,10 +1159,12 @@ int Recvmsg(int s, struct msghdr *msgh, int flags) {
 #if _WITH_SOCKET
 int Send(int s, const void *mesg, size_t len, int flags) {
    int retval, _errno;
+   if (!diag_in_handler) diag_flush();
    Debug5("send(%d, %p[%08x...], "F_Zu", %d)",
 	  s, mesg, ntohl(*(unsigned long *)mesg), len, flags);
    retval = send(s, mesg, len, flags);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("send() -> %d", retval);
    errno = _errno;
    return retval;
@@ -1132,11 +1177,13 @@ int Sendto(int s, const void *mesg, size_t len, int flags,
    int retval, _errno;
    char infobuff[256];
 
+   if (!diag_in_handler) diag_flush();
    sockaddr_info(to, tolen, infobuff, sizeof(infobuff));
    Debug7("sendto(%d, %p[%08x...], "F_Zu", %d, {%s}, %d)",
 	  s, mesg, htonl(*(unsigned long *)mesg), len, flags, infobuff, tolen);
    retval = sendto(s, mesg, len, flags, to, tolen);
    _errno = errno;
+   if (!diag_in_handler) diag_flush();
    Debug1("sendto() -> %d", retval);
    errno = _errno;
    return retval;
@@ -1163,6 +1210,7 @@ unsigned int Sleep(unsigned int seconds) {
    return retval;
 }
 
+/* obsolete by POSIX.1-2001 */
 void Usleep(unsigned long usec) {
    Debug1("usleep(%lu)", usec);
    usleep(usec);
@@ -1451,6 +1499,7 @@ int Atexit(void (*func)(void)) {
 
 
 void Exit(int status) {
+   if (!diag_in_handler) diag_flush();
    Debug1("exit(%d)", status);
    exit(status);
 }
diff --git a/sysincludes.h b/sysincludes.h
index 07be96d..c70a708 100644
--- a/sysincludes.h
+++ b/sysincludes.h
@@ -1,5 +1,5 @@
 /* source: sysincludes.h */
-/* Copyright Gerhard Rieger 2001-2011 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 #ifndef __sysincludes_h_included
@@ -26,7 +26,7 @@
 #include <syslog.h>	/* openlog(), syslog(), closelog() */
 #endif
 #include <signal.h>	/* signal(), SIGPIPE, SIG_IGN */
-#include <time.h>	/* struct timeval, strftime() */
+#include <time.h>	/* struct timeval, strftime(), clock_gettime() */
 #if 0
 #include <sys/timeb.h>	/* struct timeb */
 #endif
diff --git a/test.sh b/test.sh
index 7a4a731..6c9beec 100755
--- a/test.sh
+++ b/test.sh
@@ -7,8 +7,8 @@
 
 # this script uses functions; you need a shell that supports them
 
-# you can pass general options to socat via $OPTS
-
+# you can pass general options to socat: export OPTS="-d -d -d -d -lu"
+# you can eg strace socat with: export TRACE="strace -v -tt -ff -D -x -s 1024 -o /tmp/$USER/socat.strace"
 #set -vx
 
 val_t=0.1
@@ -1545,19 +1545,19 @@ testecho () {
     local tdiff="$td/test$N.diff"
     local da="test$N $(date) $RANDOM"
     if ! eval $NUMCOND; then :; else
-    #local cmd="$SOCAT $opts $arg1 $arg2"
+    #local cmd="$TRACE $SOCAT $opts $arg1 $arg2"
     #$ECHO "testing $title (test $N)... \c"
     $PRINTF "test $F_n %s... " $N "$title"
     #echo "$da" |$cmd >"$tf" 2>"$te"
-    (psleep $T; echo "$da"; psleep $T) |($SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") &
+    (psleep $T; echo "$da"; psleep $T) |($TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") &
     export rc1=$!
     #sleep 5 && kill $rc1 2>/dev/null &
 #    rc2=$!
     wait $rc1
 #    kill $rc2 2>/dev/null
     if [ "$(cat "$td/test$N.rc")" != 0 ]; then
-	$PRINTF "$FAILED: $SOCAT:\n"
-	echo "$SOCAT $opts $arg1 $arg2"
+	$PRINTF "$FAILED: $TRACE $SOCAT:\n"
+	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
 	numFAIL=$((numFAIL+1))
 	listFAIL="$listFAIL $N"
@@ -1567,7 +1567,7 @@ testecho () {
 	numOK=$((numOK+1))
     else
 	$PRINTF "$FAILED:\n"
-	echo "$SOCAT $opts $arg1 $arg2"
+	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
 	echo diff:
 	cat "$tdiff"
@@ -1575,7 +1575,7 @@ testecho () {
 	listFAIL="$listFAIL $N"
     fi
     fi # NUMCOND
-set +vx
+#set +vx
 }
 
 # test if call to od and throughput of data works - with graceful shutdown and
@@ -1596,10 +1596,10 @@ testod () {
     echo "$dain" |$OD_C >"$tr"
 #    local daout="$(echo "$dain" |$OD_C)"
     $PRINTF "test $F_n %s... " $num "$title"
-    (psleep $T; echo "$dain"; psleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"
+    (psleep $T; echo "$dain"; psleep $T) |$TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"
     if [ "$?" != 0 ]; then
-	$PRINTF "$FAILED: $SOCAT:\n"
-	echo "$SOCAT $opts $arg1 $arg2"
+	$PRINTF "$FAILED: $TRACE $SOCAT:\n"
+	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
 	numFAIL=$((numFAIL+1))
 	listFAIL="$listFAIL $num"
@@ -1610,7 +1610,7 @@ testod () {
 	numOK=$((numOK+1))
     else
 	$PRINTF "$FAILED: diff:\n"
-	echo "$SOCAT $opts $arg1 $arg2"
+	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
 	cat "$tdiff"
 	numFAIL=$((numFAIL+1))
@@ -1625,7 +1625,7 @@ testaddrs () {
     local a A;
     for a in $@; do
 	A=$(echo "$a" |tr 'a-z-' 'A-Z_')
-	if $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then
+	if $TRACE $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then
 	    shift
 	    continue
 	fi
@@ -1641,7 +1641,7 @@ testoptions () {
     local a A;
     for a in $@; do
 	A=$(echo "$a" |tr 'a-z' 'A-Z')
-	if $SOCAT -??? |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then
+	if $TRACE $SOCAT -??? |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then
 	    shift
 	    continue
 	fi
@@ -1695,7 +1695,7 @@ isdefunct () {
 # check if UNIX socket protocol is available on host
 runsunix () {
     return 0;
-    $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" &
+    $TRACE $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1761,7 +1761,7 @@ runsip6 () {
 runstcp4 () {
     return 0;
 #    PORT="$1"
-    $SOCAT /dev/null TCP4-LISTEN:$PORT 2>"$td/tcp4.stderr" &
+    $TRACE $SOCAT $opts /dev/null TCP4-LISTEN:$PORT 2>"$td/tcp4.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1774,7 +1774,7 @@ runstcp4 () {
 runstcp6 () {
     return 0;
 #    PORT="$1"
-    $SOCAT /dev/null TCP6-LISTEN:$PORT 2>"$td/tcp6.stderr" &
+    $TRACE $SOCAT $opts /dev/null TCP6-LISTEN:$PORT 2>"$td/tcp6.stderr" &
     pid=$!
     kill "$pid" 2>/dev/null
     wait
@@ -1786,7 +1786,7 @@ runstcp6 () {
 runsudp4 () {
     return 0;
 #    PORT="$1"
-    $SOCAT /dev/null UDP4-LISTEN:$PORT 2>"$td/udp4.stderr" &
+    $TRACE $SOCAT $opts /dev/null UDP4-LISTEN:$PORT 2>"$td/udp4.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1799,7 +1799,7 @@ runsudp4 () {
 runsudp6 () {
     return 0;
 #    PORT="$1"
-    $SOCAT /dev/null UDP6-LISTEN:$PORT 2>"$td/udp6.stderr" &
+    $TRACE $SOCAT $opts /dev/null UDP6-LISTEN:$PORT 2>"$td/udp6.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1811,7 +1811,7 @@ runsudp6 () {
 # check if SCTP on IPv4 is available on host
 runssctp4 () {
 #    PORT="$1"
-    $SOCAT /dev/null SCTP4-LISTEN:$PORT 2>"$td/sctp4.stderr" &
+    $TRACE $SOCAT $opts /dev/null SCTP4-LISTEN:$PORT 2>"$td/sctp4.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1823,7 +1823,7 @@ runssctp4 () {
 # check if SCTP on IPv6 is available on host
 runssctp6 () {
     #PORT="$1"
-    $SOCAT /dev/null SCTP6-LISTEN:$PORT 2>"$td/sctp6.stderr" &
+    $TRACE $SOCAT $opts /dev/null SCTP6-LISTEN:$PORT 2>"$td/sctp6.stderr" &
     pid=$!
     usleep $MICROS
     kill "$pid" 2>/dev/null
@@ -1945,6 +1945,7 @@ waittcp4port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
@@ -1964,13 +1965,17 @@ waittcp4port () {
 	DragonFly)  l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
  	*)       l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -1980,7 +1985,8 @@ waitudp4port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
-    [ "$logic" ] || logic=1
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
+     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
 	case "$UNAME" in
@@ -1999,13 +2005,17 @@ waitudp4port () {
 	DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
  	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2015,7 +2025,8 @@ waitsctp4port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
-    [ "$logic" ] || logic=1
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
+     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
 	case "$UNAME" in
@@ -2033,13 +2044,17 @@ waitsctp4port () {
 #	CYGWIN*) l=$(netstat -an -p TCP |grep '^  TCP    [0-9.]*:'$port' .* LISTENING') ;;
  	*)       l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2049,6 +2064,7 @@ waittcp6port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
@@ -2064,13 +2080,18 @@ waittcp6port () {
 	DragonFly)  l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
  	*)       l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    echo set ${vx}vx >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2080,6 +2101,7 @@ waitudp6port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
@@ -2096,13 +2118,17 @@ waitudp6port () {
 	DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
  	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2113,6 +2139,7 @@ waitsctp6port () {
     local logic="$2"	# 0..wait until free; 1..wait until listening
     local timeout="$3"
     local l
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
     [ "$logic" ] || logic=1
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
@@ -2126,13 +2153,17 @@ waitsctp6port () {
 #	#OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp6       0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
  	*)       l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
 	esac
-	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
-	  \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
 	sleep 1
 	timeout=$((timeout-1))
     done
 
     $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2149,12 +2180,14 @@ waitfile () {
     local logic="$2"	# 0..wait until gone; 1..wait until exists (default);
 			# 2..wait until not empty
     local timeout="$3"
+    local vx=+; case $- in *vx*) set +vx; vx=-; esac	# no tracing here
     [ "$logic" ] || logic=1
     [ "$logic" -eq 2 ] && crit=-s
     [ "$timeout" ] || timeout=5
     while [ $timeout -gt 0 ]; do
 	if [ \( \( $logic -ne 0 \) -a $crit "$file" \) -o \
 	    \( \( $logic -eq 0 \) -a ! $crit "$file" \) ]; then
+	    set ${vx}vx
 	    return 0
 	fi
 	sleep 1
@@ -2162,6 +2195,7 @@ waitfile () {
     done
 
     echo "file $file timed out" >&2
+    set ${vx}vx
     return 1
 }
 
@@ -2614,15 +2648,15 @@ te="$td/test$N.stderr"
 ts="$td/test$N.socket"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UNIX-LISTEN:$ts PIPE"
-CMD2="$SOCAT $opts -!!- UNIX-CONNECT:$ts"
+CMD1="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
+CMD2="$TRACE $SOCAT $opts -!!- UNIX-CONNECT:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 </dev/null >$tf 2>"${te}1" &
 bg=$!	# background process id
 waitfile "$ts"
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "$te"
@@ -2655,15 +2689,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -2688,6 +2722,7 @@ fi # NUMCOND
 N=$((N+1))
 
 
+#et -xv
 NAME=TCP6
 case "$TESTS" in
 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*)
@@ -2703,15 +2738,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "$te"
@@ -2732,6 +2767,7 @@ fi
 esac
 PORT=$((PORT+1))
 N=$((N+1))
+#set +vx
 
 
 NAME=TCPX4
@@ -2752,15 +2788,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP-listen:$tsl,pf=ip4,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP:$ts"
+CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,pf=ip4,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "$te"
@@ -2801,15 +2837,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP-listen:$tsl,pf=ip6,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP:$ts"
+CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,pf=ip6,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "$te"
@@ -2855,15 +2891,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,reuseaddr PIPE"
-CMD2="$SOCAT $opts STDIN!!STDOUT TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -2885,6 +2921,7 @@ esac
 PORT=$((PORT+1))
 N=$((N+1))
 
+#set -vx
 # TCP6-LISTEN may also listen for IPv4 connections. Test if option
 # ipv6-v6only=1 turns off this behaviour.
 NAME=IPV6ONLY1
@@ -2908,8 +2945,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP6-listen:$tsl,ipv6-v6only=1,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,ipv6-v6only=1,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
@@ -2929,11 +2966,13 @@ else
    $PRINTF "$OK\n"
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid; wait
+wait
 fi
 esac
 PORT=$((PORT+1))
 N=$((N+1))
+#set +vx
 
 NAME=ENV_LISTEN_4
 case "$TESTS" in
@@ -2956,15 +2995,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -2980,7 +3019,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 fi
 esac
 PORT=$((PORT+1))
@@ -3004,15 +3043,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3028,7 +3067,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 fi
 esac
 PORT=$((PORT+1))
@@ -3055,15 +3094,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -4 TCP-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts -4 TCP-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3079,7 +3118,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 fi
 esac
 PORT=$((PORT+1))
@@ -3103,15 +3142,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -6 TCP-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD1="$TRACE $SOCAT $opts -6 TCP-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3127,7 +3166,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 wait
 fi # feats
 esac
@@ -3155,15 +3194,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -6 TCP-listen:$tsl,pf=ip4,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts -6 TCP-listen:$tsl,pf=ip4,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3179,7 +3218,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 fi
 esac
 PORT=$((PORT+1))
@@ -3203,15 +3242,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -4 TCP-listen:$tsl,pf=ip6,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD1="$TRACE $SOCAT $opts -4 TCP-listen:$tsl,pf=ip6,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
 printf "test $F_n $TEST... " $N
 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3227,7 +3266,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
+kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
 esac
 PORT=$((PORT+1))
@@ -3245,8 +3284,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="$LOCALHOST:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP4-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts - UDP4:$ts"
+CMD1="$TRACE $SOCAT $opts UDP4-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -3255,7 +3294,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3296,8 +3335,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="$LOCALHOST6:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts - UDP6:$ts"
+CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -3306,7 +3345,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -3339,11 +3378,11 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 echo "$da" >$tf1
-CMD="$SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-"
+CMD="$TRACE $SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-"
 printf "test $F_n $TEST... " $N
 $CMD >"$tf2" 2>"$te"
 if [ $? -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
    numFAIL=$((numFAIL+1))
@@ -3373,7 +3412,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf"
+CMD="$TRACE $SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf"
 printf "test $F_n $TEST... " $N
 #mknod $tp p	# no mknod p on FreeBSD
 mkfifo $tp
@@ -3382,7 +3421,7 @@ $CMD >$tf 2>"$te" &
 bg=$!	# background process id
 usleep $MICROS
 if [ ! -p "$tp" ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     numFAIL=$((numFAIL+1))
@@ -3392,10 +3431,10 @@ else
 echo "$da" >"$tp" & export pid=$!; (sleep 1; kill $pid 2>/dev/null) &
 # Solaris needs more time:
 sleep 1
-kill "$bg" 2>/dev/null
+kill "$bg" 2>/dev/null; wait
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     if [ -s "$te" ]; then
-	$PRINTF "$FAILED: $SOCAT:\n"
+	$PRINTF "$FAILED: $TRACE $SOCAT:\n"
 	echo "$CMD"
 	cat "$te"
     else
@@ -3427,9 +3466,9 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da1="test$N $(date) $RANDOM"
 #establish a listening unix socket in background
-SRV="$SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
+SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
 #make a connection
-CMD="$SOCAT $opts - $ts"
+CMD="$TRACE $SOCAT $opts - $ts"
 $PRINTF "test $F_n $TEST... " $N
 eval "$SRV 2>${te}s &"
 pids=$!
@@ -3476,9 +3515,9 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da1="test$N $(date) $RANDOM"
 #establish a receiving unix socket in background
-SRV="$SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create"
+SRV="$TRACE $SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create"
 #make a connection
-CMD="$SOCAT $opts -u - $ts"
+CMD="$TRACE $SOCAT $opts -u - $ts"
 $PRINTF "test $F_n $TEST... " $N
 eval "$SRV 2>${te}s &"
 pids=$!
@@ -3507,8 +3546,7 @@ else
    if [ -n "$debug" ]; then cat $te; fi
    numOK=$((numOK+1))
 fi # !(rc -ne 0)
-kill "$pids" 2>/dev/null
-wait
+kill "$pids" 2>/dev/null; wait
 fi ;; # NUMCOND
 esac
 N=$((N+1))
@@ -3525,7 +3563,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT $opts -u file:\"$ti\",ignoreeof -"
+CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -"
 printf "test $F_n $TEST... " $N
 touch "$ti"
 $CMD >"$tf" 2>"$te" &
@@ -3533,7 +3571,7 @@ bg=$!
 usleep 500000
 echo "$da" >>"$ti"
 sleep 1
-kill $bg 2>/dev/null
+kill $bg 2>/dev/null; wait
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
@@ -3544,7 +3582,6 @@ else
    if [ -n "$debug" ]; then cat $te; fi
    numOK=$((numOK+1))
 fi
-wait
 fi ;; # NUMCOND
 esac
 N=$((N+1))
@@ -3558,11 +3595,11 @@ TEST="$NAME: exec against address with ignoreeof"
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
-CMD="$SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof"
+CMD="$TRACE $SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof"
 printf "test $F_n $TEST... " $N
 $CMD >"$tf" 2>"$te"
 if [ -s "$te" ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     numFAIL=$((numFAIL+1))
@@ -3591,8 +3628,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts pty,link=$tt pipe"
-CMD2="$SOCAT $opts - $tt,$PTYOPTS2"
+CMD1="$TRACE $SOCAT $opts pty,link=$tt pipe"
+CMD2="$TRACE $SOCAT $opts - $tt,$PTYOPTS2"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid=$!	# background process id
@@ -3603,7 +3640,7 @@ rc2=$!
 #sleep 5 && kill $rc2 2>/dev/null &
 wait $rc2
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     sleep 1
     echo "$CMD2"
@@ -3617,8 +3654,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
-wait
+kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -3634,12 +3670,12 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT -u $opts - open:$ff,append,o-trunc"
+CMD="$TRACE $SOCAT -u $opts - open:$ff,append,o-trunc"
 printf "test $F_n $TEST... " $N
 rm -f $ff; $ECHO "prefix-\c" >$ff
 if ! echo "$da" |$CMD >$tf 2>"$te" ||
     ! echo "$da" |diff - $ff >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
@@ -3665,12 +3701,12 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT -u $opts - open:$ff,append,ftruncate=0"
+CMD="$TRACE $SOCAT -u $opts - open:$ff,append,ftruncate=0"
 printf "test $F_n $TEST... " $N
 rm -f $ff; $ECHO "prefix-\c" >$ff
 if ! echo "$da" |$CMD >$tf 2>"$te" ||
     ! echo "$da" |diff - $ff >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
@@ -3702,7 +3738,7 @@ if ! eval $NUMCOND; then :; else
 TEST="$NAME: child process default properties"
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
-CMD="$SOCAT $opts -u exec:$PROCAN -"
+CMD="$TRACE $SOCAT $opts -u exec:$PROCAN -"
 printf "test $F_n $TEST... " $N
 $CMD >$tf 2>$te
 MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
@@ -3734,7 +3770,7 @@ TEST="$NAME: child process with setsid"
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
-CMD="$SOCAT $opts -u exec:$PROCAN,setsid -"
+CMD="$TRACE $SOCAT $opts -u exec:$PROCAN,setsid -"
 printf "test $F_n $TEST... " $N
 $CMD >$tf 2>$te
 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
@@ -3767,7 +3803,7 @@ TEST="$NAME: main process with setsid"
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
-CMD="$SOCAT $opts -U -,setsid exec:$PROCAN"
+CMD="$TRACE $SOCAT $opts -U -,setsid exec:$PROCAN"
 printf "test $F_n $TEST... " $N
 $CMD >$tf 2>$te
 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
@@ -3813,9 +3849,9 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts exec:'openssl s_server -accept "$PORT" -quiet -cert testsrv.pem' pipe"
-#! CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts exec:'openssl s_server -accept "$PORT" -quiet -cert testsrv.pem' pipe"
+#! CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
@@ -3823,7 +3859,7 @@ pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -3836,8 +3872,7 @@ else
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
    numOK=$((numOK+1))
 fi
-kill $pid 2>/dev/null
-wait
+kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
 esac
 PORT=$((PORT+1))
@@ -3861,15 +3896,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -3906,15 +3941,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp6port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -3964,15 +3999,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'"
-CMD="$SOCAT -T1 $opts - $TESTADDR"
+CMD2="$TRACE $SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'"
+CMD="$TRACE $SOCAT -T1 $opts - $TESTADDR"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 $WAITCMD
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4026,15 +4061,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=1,cafile=testsrv.crt,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=1,cafile=testsrv.crt,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4072,15 +4107,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4121,15 +4156,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4174,8 +4209,8 @@ else
     success=yes
     for srccompr in '' compress=auto compress=none; do
         for dstcompr in '' compress=auto compress=none; do
-            CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr pipe"
-            CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr"
+            CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr pipe"
+            CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr"
             eval "$CMD2 2>\"${te}1\" &"
             pid=$! # background process id
             waittcp4port $PORT
@@ -4188,7 +4223,7 @@ else
         done
     done
     if test -z "$success"; then
-        $PRINTF "$FAILED: $SOCAT:\n"
+        $PRINTF "$FAILED: $TRACE $SOCAT:\n"
         echo "$CMD2 &"
         echo "$CMD"
         cat "${te}1"
@@ -4224,15 +4259,15 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # we have a normal tcp echo listening - so the socks header must appear in answer
-CMD2="$SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4echo.sh\""
-CMD="$SOCAT $opts - socks4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
+CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4echo.sh\""
+CMD="$TRACE $SOCAT $opts - socks4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT 1
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4269,15 +4304,15 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # we have a normal tcp echo listening - so the socks header must appear in answer
-CMD2="$SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4echo.sh\""
-CMD="$SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody"
+CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4echo.sh\""
+CMD="$TRACE $SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp6port $PORT 1
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4315,15 +4350,15 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # we have a normal tcp echo listening - so the socks header must appear in answer
-CMD2="$SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\""
-CMD="$SOCAT $opts - socks4a:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
+CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\""
+CMD="$TRACE $SOCAT $opts - socks4a:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT 1
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4360,15 +4395,15 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # we have a normal tcp echo listening - so the socks header must appear in answer
-CMD2="$SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\""
-CMD="$SOCAT $opts - socks4a:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody"
+CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\""
+CMD="$TRACE $SOCAT $opts - socks4a:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp6port $PORT 1
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4406,16 +4441,16 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-#CMD2="$SOCAT tcp4-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
-CMD2="$SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\""
-CMD="$SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
+#CMD2="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
+CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\""
+CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}2\" &"
 pid=$!	# background process id
 waittcp4port $PORT 1
 echo "$da" |$CMD >"$tf" 2>"${te}1"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4452,16 +4487,16 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-#CMD2="$SOCAT $opts tcp6-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
-CMD2="$SOCAT $opts tcp6-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\""
-CMD="$SOCAT $opts - proxy:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT"
+#CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
+CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\""
+CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}2\" &"
 pid=$!	# background process id
 waittcp6port $PORT 1
 echo "$da" |$CMD >"$tf" 2>"${te}1"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4493,8 +4528,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr exec:$CAT,nofork"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr exec:$CAT,nofork"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 #$CMD1 >"$tf" 2>"${te}1" &
 $CMD1 >/dev/null 2>"${te}1" &
@@ -4502,7 +4537,7 @@ waittcp4port $tsl
 #usleep $MICROS
 echo "$da" |$CMD2 >"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -4558,9 +4593,9 @@ N=$((N+1))
 #tsl=65534
 #ts="127.0.0.1:$tsl"
 #da="test$N $(date) $RANDOM"
-#$SOCAT UDP-listen:$tsl PIPE &
+#$TRACE $SOCAT UDP-listen:$tsl PIPE &
 #sleep 2
-#echo "$da" |$SOCAT stdin!!stdout UDP:$ts >"$tf"
+#echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf"
 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
 #   $ECHO "... test $N succeeded"
 #   numOK=$((numOK+1))
@@ -4579,7 +4614,7 @@ N=$((N+1))
 #tp="$td/pipe$N"
 #da="test$N $(date) $RANDOM"
 #rm -f "$tf.tmp"
-#echo "$da" |$SOCAT - FILE:$tf.tmp,ignoreeof >"$tf"
+#echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf"
 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
 #   $ECHO "... test $N succeeded"
 #   numOK=$((numOK+1))
@@ -4602,15 +4637,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-CMD2="$SOCAT $opts -T 1 tcp4-listen:$PORT,reuseaddr pipe"
-CMD="$SOCAT $opts - tcp4-connect:$LOCALHOST:$PORT"
+CMD2="$TRACE $SOCAT $opts -T 1 tcp4-listen:$PORT,reuseaddr pipe"
+CMD="$TRACE $SOCAT $opts - tcp4-connect:$LOCALHOST:$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>${te}1 &"
 pid=$!	# background process id
 waittcp4port $PORT 1
 (echo "$da"; sleep 2; echo X) |$CMD >"$tf" 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4643,7 +4678,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT $opts -T 2 -u file:\"$ti\",ignoreeof -"
+CMD="$TRACE $SOCAT $opts -T 2 -u file:\"$ti\",ignoreeof -"
 printf "test $F_n $TEST... " $N
 touch "$ti"
 $CMD >"$tf" 2>"$te" &
@@ -4655,7 +4690,7 @@ echo X >>"$ti"
 sleep 1
 kill $bg 2>/dev/null
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     cat "$te"
     cat "$tdiff"
@@ -4686,16 +4721,16 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-#CMD2="$SOCAT $opts tcp-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
-CMD2="$SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh -w 2\""
-CMD="$SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
+#CMD2="$TRACE $SOCAT $opts tcp-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
+CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh -w 2\""
+CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT 1
 echo "$da" |$CMD >"$tf" 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -4726,8 +4761,8 @@ te="$td/test$N.stderr"
 ff="$td/file$N"
 printf "test $F_n $TEST... " $N
 >"$ff"
-#$SOCAT $opts -u /dev/null -,setlk <"$ff"  2>"$te"
-CMD="$SOCAT $opts -u /dev/null -,setlk"
+#$TRACE $SOCAT $opts -u /dev/null -,setlk <"$ff"  2>"$te"
+CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk"
 $CMD <"$ff"  2>"$te"
 if [ "$?" -eq 0 ]; then
     $PRINTF "$OK\n"
@@ -4846,7 +4881,7 @@ tr="$td/test$N.ref"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # the feature that we really want to test is in the readline.sh script:
-CMD="$SOCAT $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig"
+CMD="$TRACE $SOCAT $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig"
 #echo "$CMD" >"$ts"
 #chmod a+x "$ts"
 printf "test $F_n $TEST... " $N
@@ -4855,7 +4890,7 @@ mkfifo "$tpi"
 touch "$tpo"
 #
 # during development of this test, the following command line succeeded:
-# (sleep 1; $ECHO "user\n\c"; sleep 1; $ECHO "password\c"; sleep 1; $ECHO "\n\c"; sleep 1; $ECHO "test 1\n\c"; sleep 1; $ECHO "\003\c"; sleep 1; $ECHO "test 2\n\c"; sleep 1; $ECHO "exit\n\c"; sleep 1) |$SOCAT -d -d -d -d -lf/tmp/gerhard/debug1 -v -x - exec:'./readline.sh ./readline-test.sh',pty,ctty,setsid,raw,echo=0,isig
+# (sleep 1; $ECHO "user\n\c"; sleep 1; $ECHO "password\c"; sleep 1; $ECHO "\n\c"; sleep 1; $ECHO "test 1\n\c"; sleep 1; $ECHO "\003\c"; sleep 1; $ECHO "test 2\n\c"; sleep 1; $ECHO "exit\n\c"; sleep 1) |$TRACE $SOCAT -d -d -d -d -lf/tmp/gerhard/debug1 -v -x - exec:'./readline.sh ./readline-test.sh',pty,ctty,setsid,raw,echo=0,isig
 #
 PATH=${SOCAT%socat}:$PATH eval "$CMD 2>$te &"
 pid=$!	# background process id
@@ -4896,7 +4931,7 @@ EOF
 #0 if ! sed 's/.*'"$($ECHO '\r\c')"'/</g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then
 wait
 if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
@@ -4927,13 +4962,13 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 # this is the server in the protected network that we want to reach
-CMD1="$SOCAT -lpserver $opts tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo"
+CMD1="$TRACE $SOCAT -lpserver $opts tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo"
 # this is the double client in the protected network
-CMD2="$SOCAT -lp2client $opts tcp4:$LOCALHOST:$((PORT+1)),retry=10,interval=1 tcp4:$LOCALHOST:$PORT"
+CMD2="$TRACE $SOCAT -lp2client $opts tcp4:$LOCALHOST:$((PORT+1)),retry=10,interval=1 tcp4:$LOCALHOST:$PORT"
 # this is the double server in the outside network
-CMD3="$SOCAT -lp2server $opts tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST"
+CMD3="$TRACE $SOCAT -lp2server $opts tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST"
 # this is the outside client that wants to use the protected server
-CMD4="$SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$((PORT+2))"
+CMD4="$TRACE $SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$((PORT+2))"
 printf "test $F_n $TEST... " $N
 eval "$CMD1 2>${te}1 &"
 pid1=$!
@@ -4946,13 +4981,13 @@ waittcp4port $((PORT+2)) 1
 sleep 1
 echo "$da" |$CMD4 >$tf 2>"${te}4"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2 &"
     echo "$CMD3 &"
     echo "$CMD4"
     cat "${te}1" "${te}2" "${te}3" "${te}4"
-    echo "$tdiff"
+    cat "$tdiff"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
 else
@@ -4987,18 +5022,18 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 # this is the server in the protected network that we want to reach
-CMD1="$SOCAT $opts -lpserver tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo"
+CMD1="$TRACE $SOCAT $opts -lpserver tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo"
 # this is the proxy in the protected network that provides a way out
-CMD2="$SOCAT $opts -lpproxy tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh"
+CMD2="$TRACE $SOCAT $opts -lpproxy tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh"
 # this is our proxy connect wrapper in the protected network
-CMD3="$SOCAT $opts -lpwrapper tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve"
+CMD3="$TRACE $SOCAT $opts -lpwrapper tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve"
 # this is our double client in the protected network using SSL
-#CMD4="$SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT"
-CMD4="$SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT"
+#CMD4="$TRACE $SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT"
+CMD4="$TRACE $SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT"
 # this is the double server in the outside network
-CMD5="$SOCAT $opts -lp2server -t1 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt"
+CMD5="$TRACE $SOCAT $opts -lp2server -t1 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt"
 # this is the outside client that wants to use the protected server
-CMD6="$SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$((PORT+4))"
+CMD6="$TRACE $SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$((PORT+4))"
 printf "test $F_n $TEST... " $N
 eval "$CMD1 2>${te}1 &"
 pid1=$!
@@ -5019,7 +5054,7 @@ eval "$CMD4 2>${te}4 &"
 pid4=$!
 wait $pid6
 if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     cat "${te}1"
     echo "$CMD2 &"
@@ -5075,19 +5110,19 @@ da1="test$N.1 $(date) $RANDOM"
 da2="test$N.2 $(date) $RANDOM"
 da3="test$N.3 $(date) $RANDOM"
 # this is the server in the protected network that we want to reach
-CMD1="$SOCAT $opts -lpserver -t1 tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST,fork echo"
+CMD1="$TRACE $SOCAT $opts -lpserver -t1 tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST,fork echo"
 # this is the proxy in the protected network that provides a way out
 # note: the proxy.sh script starts one or two more socat processes without
 # setting the program name 
-CMD2="$SOCAT $opts -lpproxy -t1 tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh"
+CMD2="$TRACE $SOCAT $opts -lpproxy -t1 tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh"
 # this is our proxy connect wrapper in the protected network
-CMD3="$SOCAT $opts -lpwrapper -t3 tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve"
+CMD3="$TRACE $SOCAT $opts -lpwrapper -t3 tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve"
 # this is our double client in the protected network using SSL
-CMD4="$SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$((PORT+2)),retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT,forever,interval=0.1"
+CMD4="$TRACE $SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$((PORT+2)),retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT,forever,interval=0.1"
 # this is the double server in the outside network
-CMD5="$SOCAT $opts -lp2server -t4 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST,backlog=3,fork ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,interval=0.5"
+CMD5="$TRACE $SOCAT $opts -lp2server -t4 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST,backlog=3,fork ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,interval=0.5"
 # this is the outside client that wants to use the protected server
-CMD6="$SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$((PORT+4)),retry=3"
+CMD6="$TRACE $SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$((PORT+4)),retry=3"
 printf "test $F_n $TEST... " $N
 # start the intranet infrastructure
 eval "$CMD1 2>\"${te}1\" &"
@@ -5121,7 +5156,7 @@ wait $pid6_1 $pid6_2 $pid6_3
 if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then
   # FAILED only when none of the three transfers succeeded
   if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     cat "${te}1"
     echo "$CMD2 &"
@@ -5190,26 +5225,26 @@ testserversec () {
 #set -vx
     # first: without security
     # start server
-    $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" &
+    $TRACE $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" &
     spid=$!
     if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
 	kill $spid 2>/dev/null
 	$PRINTF "$NO_RESULT (ph.1 server not working):\n"
-	echo "$SOCAT $opts \"$arg1,$secopt0\" echo &"
+	echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
 	cat "${te}1"
 	numCANT=$((numCANT+1))
 	wait; return
     fi
     # now use client
-    (echo "$da"; sleep $T) |$SOCAT $opts - "$arg2" >"$tf" 2>"${te}2"
+    (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}2"
     stat="$?"
     kill $spid 2>/dev/null
-    #killall $SOCAT 2>/dev/null
+    #killall $TRACE $SOCAT 2>/dev/null
     if [ "$stat" != 0 ]; then
-	$PRINTF "$NO_RESULT (ph.1 function fails): $SOCAT:\n"
-	echo "$SOCAT $opts \"$arg1,$secopt0\" echo &"
+	$PRINTF "$NO_RESULT (ph.1 function fails): $TRACE $SOCAT:\n"
+	echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
 	cat "${te}1"
-	echo "$SOCAT $opts - \"$arg2\""
+	echo "$TRACE $SOCAT $opts - \"$arg2\""
 	cat "${te}2"
 	numCANT=$((numCANT+1))
 	wait; return
@@ -5217,9 +5252,9 @@ testserversec () {
 	:	# function without security is ok, go on
     else
 	$PRINTF "$NO_RESULT (ph.1 function fails): diff:\n"
-	echo "$SOCAT $opts $arg1,$secopt0 echo &"
+	echo "$TRACE $SOCAT $opts $arg1,$secopt0 echo &"
 	cat "${te}1"
-	echo "$SOCAT $opts - $arg2"
+	echo "$TRACE $SOCAT $opts - $arg2"
 	cat "${te}2"
 	cat "$tdiff1"
 	numCANT=$((numCANT+1))
@@ -5241,7 +5276,7 @@ testserversec () {
     *)    arg="$arg1,$secopt1" ;;
     esac
     # start server
-    CMD3="$SOCAT $opts $arg echo"
+    CMD3="$TRACE $SOCAT $opts $arg echo"
     $CMD3 2>"${te}3" &
     spid=$!
     if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
@@ -5255,11 +5290,12 @@ testserversec () {
     fi
     # now use client
     da="test$N.2 $(date) $RANDOM"
-    (echo "$da"; sleep $T) |$SOCAT $opts - "$arg2" >"$tf" 2>"${te}4"
+    (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}4"
     stat=$?
-    kill $spid 2>/dev/null
+    kill $spid
+    #kill $spid 2>/dev/null
 #set +vx
-    #killall $SOCAT 2>/dev/null
+    #killall $TRACE $SOCAT 2>/dev/null
     if [ "$stat" != 0 ]; then
 	result=-1;	# socat had error
     elif [ ! -s "$tf" ]; then
@@ -5271,31 +5307,31 @@ testserversec () {
     fi
     if [ X$result != X$expect ]; then
 	case X$result in
-	X-1) $PRINTF "$NO_RESULT (ph.2 client error): $SOCAT:\n"
-	    echo "$SOCAT $opts $arg echo"
+	X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n"
+	    echo "$TRACE $SOCAT $opts $arg echo"
 	    cat "${te}3"
-	    echo "$SOCAT $opts - $arg2"
+	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    numCANT=$((numCANT+1)) ;;
 	X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n"
-	    echo "$SOCAT $opts $arg echo"
+	    echo "$TRACE $SOCAT $opts $arg echo"
 	    cat "${te}3"
-	    echo "$SOCAT $opts - $arg2"
+	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
 	    numCANT=$((numCANT+1)) ;;
 	X1) $PRINTF "$FAILED: SECURITY BROKEN\n"
-	    echo "$SOCAT $opts $arg echo"
+	    echo "$TRACE $SOCAT $opts $arg echo"
 	    cat "${te}3"
-	    echo "$SOCAT $opts - $arg2"
+	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
 	    numFAIL=$((numFAIL+1))
 	    listFAIL="$listFAIL $N" ;;
 	X2) $PRINTF "$FAILED: diff:\n"
-	    echo "$SOCAT $opts $arg echo"
+	    echo "$TRACE $SOCAT $opts $arg echo"
 	    cat "${te}3"
-	    echo "$SOCAT $opts - $arg2"
+	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
 	    numFAIL=$((numFAIL+1))
@@ -5857,7 +5893,7 @@ ts="$td/test$N.socket"
 te1="$td/test$N.stderr1"	# socat
 te2="$td/test$N.stderr2"	# filan
 printf "test $F_n $TEST... " $N
-$SOCAT unix-l:"$ts" /dev/null </dev/null 2>"$te1" &
+$TRACE $SOCAT $opts UNIX-LISTEN:"$ts" /dev/null </dev/null 2>"$te1" &
 spid=$!
 waitfile "$ts" 1
 type=$($FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print($2);}')
@@ -5895,17 +5931,17 @@ testptywaitslave () {
     local da="test$N $(date) $RANDOM"
 printf "test $F_n $TEST... " $N
 # first generate a pty, then a socket
-($SOCAT $opts -lpsocat1 pty,$PTYTYPE,pty-wait-slave,link="$tp" unix-listen:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null &
+($TRACE $SOCAT $opts -lpsocat1 pty,$PTYTYPE,pty-wait-slave,link="$tp" unix-listen:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null &
 pid=$!
 waitfile "$tp"
 # if pty was non-blocking, the socket is active, and socat1 will term
-$SOCAT $opts -T 10 -lpsocat2 file:/dev/null unix-connect:"$ts" 2>"$te2"
+$TRACE $SOCAT $opts -T 10 -lpsocat2 file:/dev/null unix-connect:"$ts" 2>"$te2"
 # if pty is blocking, first socat is still active and we get a connection now
-#((echo "$da"; sleep 2) |$SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
-( (waitfile "$ts"; echo "$da"; sleep 1) |$SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
+#((echo "$da"; sleep 2) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
+( (waitfile "$ts"; echo "$da"; sleep 1) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
 waitfile "$ts"
 # but we need an echoer on the socket
-$SOCAT $opts -lpsocat4 unix:"$ts" echo 2>"$te4"
+$TRACE $SOCAT $opts -lpsocat4 unix:"$ts" echo 2>"$te4"
 # now $tf file should contain $da
 #kill $pid 2>/dev/null
 wait
@@ -5985,8 +6021,8 @@ te2="$td/test$N.stderr2"
 tk2="$td/test$N.kill2"
 $PRINTF "test $F_n $TEST... " $N
 # first, try to make socat hang and see if it can be killed
-#$SOCAT $opts - tcp:$HANGIP:1 >"$te1" 2>&1 </dev/null &
-CMD="$SOCAT $opts - tcp:$HANGIP:1"
+#$TRACE $SOCAT $opts - tcp:$HANGIP:1 >"$te1" 2>&1 </dev/null &
+CMD="$TRACE $SOCAT $opts - tcp:$HANGIP:1"
 $CMD >"$te1" 2>&1 </dev/null &
 pid1=$!
 sleep 2
@@ -5995,7 +6031,7 @@ if ! kill $pid1 2>"$tk1"; then
     numCANT=$((numCANT+1))
 else
 # second, set connect-timeout and see if socat exits before kill
-$SOCAT $opts - tcp:$HANGIP:1,connect-timeout=1.0 >"$te2" 2>&1 </dev/null &
+$TRACE $SOCAT $opts - tcp:$HANGIP:1,connect-timeout=1.0 >"$te2" 2>&1 </dev/null &
 pid2=$!
 sleep 2
 if kill $pid2 2>"$tk2"; then
@@ -6032,15 +6068,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts STDIO TCP4:$ts,connect-timeout=1"
+CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts STDIO TCP4:$ts,connect-timeout=1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -6080,8 +6116,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
 $PRINTF "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
@@ -6130,7 +6166,7 @@ signum () {
 for signam in TERM ILL; do
 NAME=EXITCODESIG$signam
 case "$TESTS" in
-*%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%pty%*|*%signal%*|*%$NAME%*)
 TEST="$NAME: exit status when dying on SIG$signam"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testaddrs pty); then
@@ -6144,7 +6180,7 @@ tp="$td/test$N.pid"
 $PRINTF "test $F_n $TEST... " $N
 (sleep 1; kill -"$SIG" "$(cat "$tpp")") &
 # a simple "system:echo $PPID..." does not work on NetBSD, OpenBSD
-#$SOCAT $opts echo system:'exec /bin/bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$?
+#$TRACE $SOCAT $opts echo SYSTEM:'exec /bin/bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$?
 tsh="$td/test$N.sh"
 cat <<EOF >"$tsh"
 #! /bin/bash
@@ -6153,7 +6189,10 @@ echo \$\$ >"$tp"
 read x
 EOF
 chmod a+x "$tsh"
-$SOCAT $opts echo system:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$?
+#$TRACE $SOCAT $opts echo SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$?
+CMD="$TRACE $SOCAT $opts ECHO SYSTEM:\"exec\\\ \\\"$tsh\\\"\",pty,setsid,nofork"
+$TRACE $SOCAT $opts ECHO SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"
+stat=$?
 sleep 1; kill -INT $(cat $tp)
 wait
 if [ "$stat" -eq $((128+$SIG)) ]; then
@@ -6161,6 +6200,7 @@ if [ "$stat" -eq $((128+$SIG)) ]; then
    numOK=$((numOK+1))
 else
     $PRINTF "$FAILED\n"
+    echo "$CMD"
     cat "$te"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
@@ -6189,7 +6229,7 @@ te="$td/test$N.err"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
 # the feature that we really want to test is in the readline.sh script:
-CMD="$SOCAT $opts -u open:$ti,readbytes=100 -"
+CMD="$TRACE $SOCAT $opts -u open:$ti,readbytes=100 -"
 printf "test $F_n $TEST... " $N
 rm -f "$tf" "$ti" "$to"
 #
@@ -6200,7 +6240,7 @@ AAAAAAAAAAAAAAAAAAAAAAAA" >"$tr"	# 100 bytes
 cat "$tr" "$tr" >"$ti"			# 200 bytes
 $CMD >"$to" 2>"$te"
 if ! diff "$tr" "$to" >"$tdiff" 2>&1; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
@@ -6228,9 +6268,9 @@ da1="test$N $(date) $RANDOM"
 da2="test$N $(date) $RANDOM"
 #establish a listening and forking udp socket in background
 #processes hang forever without -T
-SRV="$SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE"
+SRV="$TRACE $SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE"
 #make a first and a second connection
-CLI="$SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT"
+CLI="$TRACE $SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT"
 $PRINTF "test $F_n $TEST... " $N
 eval "$SRV 2>${te}s &"
 pids=$!
@@ -6325,9 +6365,9 @@ esac
 echo -e "$da1a\n$da2\n$da1b" >"$tref"
 # establish a listening and forking listen socket in background
 # UDP processes hang forever without -T
-CMD0="$SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,fork PIPE"
+CMD0="$TRACE $SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,fork PIPE"
 # make a first and a second connection
-CMD1="$SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca"
+CMD1="$TRACE $SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca"
 $PRINTF "test $F_n $TEST... " $N
 eval "$CMD0 2>${te}0 &"
 pid0=$!
@@ -6363,7 +6403,7 @@ SCTP4 $LOCALHOST PORT
 SCTP6 $LOCALHOST6 PORT
 UNIX FILE ,
 "
-set +vx
+#set +vx
 
 
 NAME=UNIXTOSTREAM
@@ -6377,9 +6417,9 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da1="test$N $(date) $RANDOM"
 #establish a listening unix socket in background
-SRV="$SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
+SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
 #make a connection
-CLI="$SOCAT $opts -lpclient - UNIX:\"$ts\""
+CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts\""
 $PRINTF "test $F_n $TEST... " $N
 eval "$SRV 2>${te}s &"
 pids=$!
@@ -6421,10 +6461,10 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da1="test$N $(date) $RANDOM"
 #establish a receiving unix datagram socket in background
-SRV="$SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE"
+SRV="$TRACE $SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE"
 #make a connection
-CLI="$SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\""
-#CLI="$SOCAT $opts -lpclient - UNIX:\"$ts1\""
+CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\""
+#CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\""
 $PRINTF "test $F_n $TEST... " $N
 eval "$SRV 2>${te}s &"
 pids=$!
@@ -6513,17 +6553,17 @@ tdiff="$td/test$N.diff"
 # if they are scanned incorrectly, socat will see an "unknown option"
 dain='(,)[,]{,}","([),])hugo'
 daout='(,)[,]{,},([),])hugo'
-"$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te"
+$TRACE "$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te"
 rc=$?
 echo "$daout" |diff "$tf" - >"$tdiff"
 if [ "$rc" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
-    echo "$SOCAT" -u "exec:echo $da" -
+    $PRINTF "$FAILED:\n"
+    echo "$TRACE $SOCAT" -u "exec:echo $da" -
     cat "$te"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
 elif [ -s "$tdiff" ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED:\n"
     echo diff:
     cat "$tdiff"
     if [ -n "$debug" ]; then cat $te; fi
@@ -6570,15 +6610,15 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -6619,8 +6659,8 @@ ts1="$ts1a:$ts1p"
 ts2p=$PORT; PORT=$((PORT+1))
 ts2="127.0.0.1:$ts2p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
-CMD2="$SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2"
+CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -6629,7 +6669,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2="$?"
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -6675,14 +6715,14 @@ ts1="$tsa:$ts1p"
 ts2p=$PORT; PORT=$((PORT+1))
 ts2="$tsa:$ts2p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
-CMD2="$SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2"
+CMD1="$TRACE $SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 waitudp6port $ts1p 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -6723,8 +6763,8 @@ ts1="$ts1a:$ts1p"
 ts2a="$SECONDADDR"
 ts2="$ts2a:$ts2p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
-CMD2="$SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a"
+CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
+CMD2="$TRACE $SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1=$!
@@ -6733,7 +6773,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null;  wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -6776,14 +6816,14 @@ tsa="[::1]"
 ts1="$tsa:$ts1p"
 ts2="$tsa"
 da="test$N $(date) $RANDOM"
-#CMD1="$SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
-CMD2="$SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2"
+#CMD1="$TRACE $SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
+CMD2="$TRACE $SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2"
 printf "test $F_n $TEST... " $N
 #$CMD1 2>"${te}1" &
 waitip6proto $ts1p 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
 #   echo "$CMD1 &"
 #   cat "${te}1"
    echo "$CMD2"
@@ -6817,8 +6857,8 @@ tdiff="$td/test$N.diff"
 ts1="$td/test$N.socket1"
 ts2="$td/test$N.socket2"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE"
-CMD2="$SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2"
+CMD1="$TRACE $SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -6827,7 +6867,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill "$pid1" 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -6862,8 +6902,8 @@ ts1p=$PORT; PORT=$((PORT+1))
 ts1a="127.0.0.1"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -"
-CMD2="$SOCAT $opts -u - UDP4-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -6874,7 +6914,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -6917,8 +6957,8 @@ ts1p=$PORT; PORT=$((PORT+1))
 ts1a="[::1]"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -"
-CMD2="$SOCAT $opts -u - UDP6-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - UDP6-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -6929,7 +6969,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -6967,8 +7007,8 @@ ts1p=$PROTO; PROTO=$((PROTO+1))
 ts1a="127.0.0.1"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -"
-CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -6979,7 +7019,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -7020,8 +7060,8 @@ ts1p=$PROTO; PROTO=$((PROTO+1))
 ts1a="[::1]"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -"
-CMD2="$SOCAT $opts -u - IP6-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - IP6-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -7031,7 +7071,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -7064,8 +7104,8 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 ts1="$ts"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -"
-CMD2="$SOCAT $opts -u - UNIX-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -7075,7 +7115,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -7600,7 +7640,7 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 $PRINTF "test $F_n $TEST... " $N
-CMD="$SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null"
+CMD="$TRACE $SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null"
 # generate a file
 touch "${tf}1"
 sleep 1
@@ -7619,7 +7659,7 @@ else
 # check which file has a later atime stamp
 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
 then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD"
    cat "$te"
     numFAIL=$((numFAIL+1))
@@ -7653,7 +7693,7 @@ tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 $PRINTF "test $F_n $TEST... " $N
 touch ${tf}1
-CMD="$SOCAT $opts -u -,o-noatime /dev/null <${tf}1"
+CMD="$TRACE $SOCAT $opts -u -,o-noatime /dev/null <${tf}1"
 # generate a file, len >= 1
 touch "${tf}1"
 sleep 1
@@ -7672,7 +7712,7 @@ else
 # check which file has a later atime stamp
 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
 then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD"
    cat "$te"
     numFAIL=$((numFAIL+1))
@@ -7707,8 +7747,8 @@ tdiff="$td/test$N.diff"
 ts1="$ts"
 da="test$N $(date) $RANDOM"
 $PRINTF "test $F_n $TEST... " $N
-CMD0="$SOCAT $opts -u /dev/null create:\"${tf}1\""
-CMD="$SOCAT $opts -u /dev/null create:\"${tf}1\",ext2-noatime"
+CMD0="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\""
+CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",ext2-noatime"
 # check if this is a capable FS; lsattr does other things on AIX, thus socat
 $CMD0 2>"${te}0"
 if [ $? -ne 0 ]; then
@@ -7733,7 +7773,7 @@ cat "${tf}1" >/dev/null
 #if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |awk '{print($8);}') != "${tf}2" ];
 if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |sed "s|.*\\($td.*\\)|\1|g") != "${tf}2" ];
 then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD"
    cat "$te"
     numFAIL=$((numFAIL+1))
@@ -7766,8 +7806,8 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 # a reader that will terminate after 1 byte
-CMD1="$SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
-CMD="$SOCAT $opts -u - file:\"$ti\",cool-write"
+CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
+CMD="$TRACE $SOCAT $opts -u - file:\"$ti\",cool-write"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 bg=$!	# background process id
@@ -7776,7 +7816,7 @@ sleep 1
 rc=$?
 kill $bg 2>/dev/null; wait
 if [ $rc -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     cat "$te"
     numFAIL=$((numFAIL+1))
@@ -7815,8 +7855,8 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 # a reader that will terminate after 1 byte
-CMD1="$SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
-CMD="$SOCAT $opts -,cool-write pipe >\"$ti\""
+CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
+CMD="$TRACE $SOCAT $opts -,cool-write pipe >\"$ti\""
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 bg=$!	# background process id
@@ -7825,7 +7865,7 @@ sleep 1
 rc=$?
 kill $bg 2>/dev/null; wait
 if [ $rc -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     cat "$te"
     numFAIL=$((numFAIL+1))
@@ -7852,9 +7892,9 @@ p1=$PORT; PORT=$((PORT+1))
 p2=$PORT
 da1a="$(date) $RANDOM"
 da1b="$(date) $RANDOM"
-CMD1="$SOCAT $opts -u - TCP4-CONNECT:$LOCALHOST:$p1"
-CMD="$SOCAT $opts -U TCP4:$LOCALHOST:$p2,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,reuseaddr,fork"
-CMD3="$SOCAT $opts -u TCP4-LISTEN:$p2,reuseaddr,bind=$LOCALHOST -"
+CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$LOCALHOST:$p1"
+CMD="$TRACE $SOCAT $opts -U TCP4:$LOCALHOST:$p2,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,reuseaddr,fork"
+CMD3="$TRACE $SOCAT $opts -u TCP4-LISTEN:$p2,reuseaddr,bind=$LOCALHOST -"
 printf "test $F_n $TEST... " $N
 $CMD3 >"$tf" 2>"${te}3" &
 pid3=$!
@@ -7869,7 +7909,7 @@ sleep 1
 kill "$pid3" "$pid2" 2>/dev/null
 wait
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1a" "${te}1b" "${te}2" "${te}3"
@@ -7903,8 +7943,8 @@ ts="$td/test$N.sock"
 tdiff="$td/test$N.diff"
 da1a="$(date) $RANDOM"
 da1b="$(date) $RANDOM"
-CMD1="$SOCAT $opts - UNIX-CONNECT:$ts"
-CMD="$SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork"
+CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$ts"
+CMD="$TRACE $SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork"
 printf "test $F_n $TEST... " $N
 $CMD 2>"${te}2" &
 pid2=$!
@@ -7916,7 +7956,7 @@ echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf"
 kill "$pid2" 2>/dev/null
 wait
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1a" "${te}1b" "${te}2"
@@ -7950,7 +7990,7 @@ if ! eval $NUMCOND; then :;
  else
 tf="$td/test$N.stout"
 te="$td/test$N.stderr"
-CMD="$SOCAT $opts /dev/null pty,end-close"
+CMD="$TRACE $SOCAT $opts /dev/null pty,end-close"
 printf "test $F_n $TEST... " $N
 $CMD 2>"${te}"
 rc=$?
@@ -7985,8 +8025,8 @@ tf="$td/test$N.stout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts -u UDP-RECV:$PORT,null-eof CREAT:$tf"
-CMD1="$SOCAT $opts -u - UDP-SENDTO:127.0.0.1:$PORT,shut-null"
+CMD0="$TRACE $SOCAT $opts -u UDP-RECV:$PORT,null-eof CREAT:$tf"
+CMD1="$TRACE $SOCAT $opts -u - UDP-SENDTO:127.0.0.1:$PORT,shut-null"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -8041,8 +8081,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="$LOCALHOST6:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr,bind=$LOCALHOST6 PIPE"
-CMD2="$SOCAT $opts - UDP6:$ts"
+CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr,bind=$LOCALHOST6 PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -8051,7 +8091,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
@@ -8090,14 +8130,14 @@ tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 ha="$td/hosts.allow"
 $ECHO "test : ALL : allow" >"$ha"
-CMD1="$SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,hosts-allow=$ha,tcpwrap=test pipe"
-CMD2="$SOCAT $opts - TCP:$LOCALHOST:$PORT"
+CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,hosts-allow=$ha,tcpwrap=test pipe"
+CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 waittcp4port $PORT
 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8139,8 +8179,8 @@ ha="$td/hosts.allow"
 hd="$td/hosts.deny"
 $ECHO "socat : [::1] : allow" >"$ha"
 $ECHO "ALL : ALL : deny" >"$hd"
-CMD1="$SOCAT $opts TCP6-LISTEN:$PORT,reuseaddr,tcpwrap-etc=$td,tcpwrappers=socat pipe"
-CMD2="$SOCAT $opts - TCP6:[::1]:$PORT"
+CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT,reuseaddr,tcpwrap-etc=$td,tcpwrappers=socat pipe"
+CMD2="$TRACE $SOCAT $opts - TCP6:[::1]:$PORT"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1=$!
@@ -8148,7 +8188,7 @@ waittcp6port $PORT
 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
 kill $pid1 2>/dev/null; wait
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8189,9 +8229,9 @@ ts1="$BCADDR:$ts1p"
 ts2p=$PORT; PORT=$((PORT+1))
 ts2="$BCIFADDR:$ts2p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE"
-#CMD2="$SOCAT $opts - UDP4-BROADCAST:$ts1"
-CMD2="$SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast"
+CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE"
+#CMD2="$TRACE $SOCAT $opts - UDP4-BROADCAST:$ts1"
+CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -8200,7 +8240,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2="$?"
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1"
@@ -8255,9 +8295,9 @@ da="test$N $(date) $RANDOM XXXX"
 sh="$td/test$N-sed.sh"
 echo 'sed s/XXXX/YYYY/' >"$sh"
 chmod a+x "$sh"
-CMD1="$SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast exec:$sh"
-#CMD2="$SOCAT $opts - IP4-BROADCAST:$ts1"
-CMD2="$SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast"
+CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast exec:$sh"
+#CMD2="$TRACE $SOCAT $opts - IP4-BROADCAST:$ts1"
+CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -8266,7 +8306,7 @@ echo "$da" |$CMD2 2>>"${te}2" |grep -v XXXX >>"$tf"
 rc2="$?"
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1"
@@ -8320,8 +8360,8 @@ ts1p=$PORT; PORT=$((PORT+1))
 ts1a="$SECONDADDR"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
-CMD2="$SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
+CMD1="$TRACE $SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
+CMD2="$TRACE $SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1"  >"${tf}" &
 pid1="$!"
@@ -8331,7 +8371,7 @@ rc2="$?"
 usleep $MICROS
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8371,8 +8411,8 @@ ts1p=$PROTO
 ts1a="$SECONDADDR"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
-CMD2="$SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
+CMD1="$TRACE $SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
+CMD2="$TRACE $SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1"  >"${tf}" &
 pid1="$!"
@@ -8384,7 +8424,7 @@ rc2="$?"
 sleep 1
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8423,8 +8463,8 @@ ts1p=$PORT; PORT=$((PORT+1))
 if1="$MCINTERFACE"
 ts1a="[::1]"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT -u $opts UDP6-RECV:$ts1p,reuseaddr,ipv6-join-group=[ff02::2]:$if1 -"
-CMD2="$SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a"
+CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,reuseaddr,ipv6-join-group=[ff02::2]:$if1 -"
+CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1"  >"${tf}" &
 pid1="$!"
@@ -8434,7 +8474,7 @@ rc2="$?"
 usleep $MICROS
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8470,9 +8510,9 @@ ts1="$ts1a:$ts1p"
 ts2p=$PORT; PORT=$((PORT+1))
 ts2="$BCIFADDR:$ts2p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
-#CMD2="$SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
-CMD2="$SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
+CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
+#CMD2="$TRACE $SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
+CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -8481,7 +8521,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2="$?"
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1"
@@ -8525,9 +8565,9 @@ ts1p=$PROTO
 ts1a="$SECONDADDR"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
-#CMD2="$SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
-CMD2="$SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
+CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
+#CMD2="$TRACE $SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
+CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -8537,7 +8577,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2="$?"
 kill "$pid1" 2>/dev/null; wait;
 if [ "$rc2" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1"
@@ -8586,9 +8626,9 @@ tl="$td/test$N.lock"
 da="test$N $(date) $RANDOM"
 dalen=$((${#da}+1))
 TUNNET=10.255.255
-CMD1="$SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT"
-#CMD="$SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -"
-CMD="$SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -"
+CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT"
+#CMD="$TRACE $SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -"
+CMD="$TRACE $SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -"
 printf "test $F_n $TEST... " $N
 $CMD 2>"${te}" |tail -c $dalen >"${tf}" &
 sleep 1
@@ -8597,7 +8637,7 @@ sleep 1
 kill "$(cat $tl 2>/dev/null)" 2>/dev/null
 wait
 if [ $? -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     echo "$CMD1"
     cat "${te}" "${te}1"
@@ -8644,8 +8684,8 @@ da="$(date) $RANDOM"
 dalen=$((${#da}+1))
 TUNNET=10.255.255
 TUNNAME=tun9
-CMD1="$SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME echo"
-CMD="$SOCAT $opts - INTERFACE:$TUNNAME"
+CMD1="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME echo"
+CMD="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}1" &
 pid1="$!"
@@ -8655,7 +8695,7 @@ echo "$da" |$CMD 2>"${te}1" >"$tf" 2>"${te}"
 kill $pid1 2>/dev/null
 wait
 if [ $? -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     echo "$CMD1"
     cat "${te}" "${te}1"
@@ -8693,9 +8733,9 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da1="test$N $(date) $RANDOM"
 #establish a listening abstract unix socket
-SRV="$SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\" PIPE"
+SRV="$TRACE $SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\" PIPE"
 #make a connection
-CMD="$SOCAT $opts - ABSTRACT-CONNECT:$ts"
+CMD="$TRACE $SOCAT $opts - ABSTRACT-CONNECT:$ts"
 $PRINTF "test $F_n $TEST... " $N
 touch "$ts"	# make a file with same name, so non-abstract fails
 eval "$SRV 2>${te}s &"
@@ -8748,9 +8788,9 @@ tdiff="$td/test$N.diff"
 ts1="$td/test$N.socket1"
 ts2="$td/test$N.socket2"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE"
-#CMD2="$SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
-CMD2="$SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
+CMD1="$TRACE $SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE"
+#CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
+CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
 printf "test $F_n $TEST... " $N
 touch "$ts1"	# make a file with same name, so non-abstract fails
 $CMD1 2>"${te}1" &
@@ -8760,7 +8800,7 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill "$pid1" 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -8797,8 +8837,8 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 ts1="$ts"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -"
-CMD2="$SOCAT $opts -u - ABSTRACT-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - ABSTRACT-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 touch "$ts1"	# make a file with same name, so non-abstract fails
 $CMD1 >"$tf" 2>"${te}1" &
@@ -8810,7 +8850,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -8859,8 +8899,8 @@ tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 SRVCERT=testsrv
 gentestcert "$SRVCERT"
-CMD1="$SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,reuseaddr,cert=$SRVCERT.pem,verify=0 -"
-CMD2="$SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,verify=0"
+CMD1="$TRACE $SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,reuseaddr,cert=$SRVCERT.pem,verify=0 -"
+CMD2="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,verify=0"
 printf "test $F_n $TEST... " $N
 #
 $CMD1 2>"${te}1" >"$tf" &
@@ -8869,7 +8909,7 @@ waittcp4port $PORT
 (echo "$da"; sleep 2) |$CMD2 2>"${te}2"
 kill "$pid" 2>/dev/null; wait
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1"
     cat "${te}1"
     echo "$CMD2"
@@ -8912,11 +8952,11 @@ to="$td/test$N.out"
 te="$td/test$N.err"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-CMD="$SOCAT $opts system:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null"
+CMD="$TRACE $SOCAT $opts SYSTEM:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null"
 printf "test $F_n $TEST... " $N
 (usleep $((2*MICROS)); echo) |eval "$CMD" >"$to" 2>"$te"
 if test -s "$to"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
@@ -8951,8 +8991,8 @@ cat >"$tsh" <<EOF
 sleep $SECONDs; echo; sleep $SECONDs;  touch "$tda"; echo
 EOF
 chmod a+x "$tsh"
-CMD1="$SOCAT $opts -t $SECONDs -U UNIX-LISTEN:$ts,fork EXEC:$tsh,pty"
-CMD="$SOCAT $opts -t $SECONDs /dev/null UNIX-CONNECT:$ts"
+CMD1="$TRACE $SOCAT $opts -t $SECONDs -U UNIX-LISTEN:$ts,fork EXEC:$tsh,pty"
+CMD="$TRACE $SOCAT $opts -t $SECONDs /dev/null UNIX-CONNECT:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 2>"${te}2" &
 pid1=$!
@@ -8963,7 +9003,7 @@ sleep $((2*SECONDs))
 kill "$pid1" 2>/dev/null
 wait
 if [ $? -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2"
@@ -9005,15 +9045,15 @@ PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')"
 tsl="$PORT"
 ts="127.0.0.1:$SERVICE"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts"
+CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
 waittcp4port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -9086,7 +9126,7 @@ N=$((N+1))
 # zombies because the master process did not catch SIGCHLD
 NAME=UDP4LISTEN_SIGCHLD
 case "$TESTS" in
-*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%signal%*|*%$NAME%*)
 TEST="$NAME: test if UDP4-LISTEN child becomes zombie"
 # idea: run a udp-listen process with fork and -T. Connect once, so a sub
 # process is forked off. Make some transfer and wait until the -T timeout is
@@ -9099,8 +9139,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="$LOCALHOST:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,reuseaddr,fork PIPE"
-CMD2="$SOCAT $opts - UDP4:$ts"
+CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,reuseaddr,fork PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -9118,7 +9158,7 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$NO_RESULT (diff failed)\n"	# already handled in test UDP4STREAM
     numCANT=$((numCANT+1))
 elif $(isdefunct "$l"); then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2"
@@ -9139,7 +9179,7 @@ N=$((N+1))
 # zombies because the master process caught SIGCHLD but did not wait()
 NAME=UDP4RECVFROM_SIGCHLD
 case "$TESTS" in
-*%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%signal%*|*%$NAME%*)
 TEST="$NAME: test if UDP4-RECVFROM child becomes zombie"
 # idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a
 # sub process is forked off. Make some transfer and wait until the -T timeout
@@ -9152,8 +9192,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="$LOCALHOST:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE"
-CMD2="$SOCAT $opts - UDP4-SENDTO:$ts"
+CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE"
+CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -9171,7 +9211,7 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$NO_RESULT\n"	# already handled in test UDP4DGRAM
     numCANT=$((numCANT+1))
 elif $(isdefunct "$l"); then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2"
@@ -9210,8 +9250,8 @@ ts1p=$PROTO; PROTO=$((PROTO+1))
 ts1a="127.0.0.1"
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -"
-CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1"
+CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -"
+CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1="$!"
@@ -9222,7 +9262,7 @@ rc2="$?"
 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do  usleep 100000; i=$((i+1));  done
 kill "$pid1" 2>/dev/null; wait
 if [ "$rc2" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1"
@@ -9262,8 +9302,8 @@ tdiff="$td/test$N.diff"
 tsp=$PORT
 ts="$LOCALHOST:$tsp"
 da="test$N $(date) $RANDOM"
-CMD1="$SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE"
-CMD2="$SOCAT $opts -T 1 - UDP4-SENDTO:$ts"
+CMD1="$TRACE $SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE"
+CMD2="$TRACE $SOCAT $opts -T 1 - UDP4-SENDTO:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >/dev/null 2>"${te}1" &
 pid1=$!
@@ -9278,7 +9318,7 @@ if [ $rc2b -ne 0 ]; then
     $PRINTF "$NO_RESULT\n"
     numCANT=$((numCANT+1))
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2" "${te}3"
@@ -9310,16 +9350,16 @@ da="test$N $(date)  $RANDOM"	# with a double space
 tdiff="$td/test$N.diff"
 # put the test data as first argument after two spaces. expect the data in the
 # first argument of the exec'd command.
-$SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\"  \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te"
+$TRACE $SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\"  \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te"
 rc=$?
 echo "$da" |diff - "$tf" >"$tdiff"
 if [ "$rc" -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     cat "$te"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
 elif [ -s "$tdiff" ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo diff:
     cat "$tdiff"
     if [ -n "$debug" ]; then cat $te; fi
@@ -9355,9 +9395,9 @@ tp=$PORT
 da1="test$N $(date) $RANDOM"
 a1="$LOCALHOST"
 a2="$SECONDADDR"
-#CMD0="$SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE"
-CMD0="$SOCAT $opts UDP4-LISTEN:$tp,range=$a2/32 PIPE"
-CMD1="$SOCAT $opts - UDP-CONNECT:$a1:$tp"
+#CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE"
+CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,range=$a2/32 PIPE"
+CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$a1:$tp"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid1=$!
@@ -9405,7 +9445,7 @@ tf="$td/test$N.stout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null"
+CMD0="$TRACE $SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null"
 printf "test $F_n $TEST... " $N
 (usleep 333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0"
 rc0=$?
@@ -9445,11 +9485,11 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT $opts -,escape=27 pipe"
+CMD="$TRACE $SOCAT $opts -,escape=27 pipe"
 printf "test $F_n $TEST... " $N
 $ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te"
 if [ $? -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
     numFAIL=$((numFAIL+1))
@@ -9481,7 +9521,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe"
+CMD="$TRACE $SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe"
 printf "test $F_n $TEST... " $N
 >"$ti"
 $CMD >"$tf" 2>"$te" &
@@ -9544,11 +9584,11 @@ case "X$IPPORT" in
     tra="$(eval echo "$ADDR")"	# resolve $N
     tsa="$tra"
 esac
-CMD0="$SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -"
-CMD1="$SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
+CMD0="$TRACE $SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -"
+CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
 printf "test $F_n $TEST... " $N
 # is this option supported?
-if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
+if $TRACE $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
 $CMD0 >"$tf" 2>"${te}0" &
 pid0="$!"
 wait${proto}port $tra 1
@@ -9569,7 +9609,7 @@ if [ "$SCM_VALUE" = "timestamp" ]; then
     SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y')"
 fi
 if [ "$rc1" -ne 0 ]; then
-    $PRINTF "$NO_RESULT: $SOCAT:\n"
+    $PRINTF "$NO_RESULT: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
     echo "$CMD1"
     grep " $LEVELS " "${te}0"
@@ -9591,7 +9631,7 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE" ${te}0 >/dev/nu
     grep " $LEVELS " "${te}0"
     grep " $LEVELS " "${te}1"
     badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')"
-    echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of \"$SCM_VALUE\""
+    echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of pattern \"$SCM_VALUE\""
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
 else
@@ -9689,9 +9729,9 @@ tcp="$TEST_PEERPORT"	# test client port
 if [ "$tcp" != ',' ]; then
     tca="$tca:$tcp"
 fi
-#CMD0="$SOCAT $opts -u $KEYW-LISTEN:$tsa1 system:\"export -p\""
-CMD0="$SOCAT $opts -u -lpsocat $KEYW-LISTEN:$tsa1 system:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\""
-CMD1="$SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
+#CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
+CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-LISTEN:$tsa1 SYSTEM:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\""
+CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
 printf "test $F_n $TEST... " $N
 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
 pid0=$!
@@ -9789,9 +9829,9 @@ case "X$IPPORT" in
     tra="$(eval echo "$ADDR")"	# resolve $N
     tsa="$tra"
 esac
-#CMD0="$SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV system:\"export -p\""
-CMD0="$SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV system:\"echo \\\$SOCAT_$SCM_ENVNAME\""
-CMD1="$SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
+#CMD0="$TRACE $SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"export -p\""
+CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"echo \\\$SOCAT_$SCM_ENVNAME\""
+CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
 printf "test $F_n $TEST... " $N
 # is this option supported?
 if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
@@ -9815,7 +9855,7 @@ if [ "$rc1" -ne 0 ]; then
     cat "${te}1"
     numCANT=$((numCANT+1))
 #elif ! egrep "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then
-#elif ! eval echo "$SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then
+#elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then
 elif ! expr "$(cat "$tf")" : "$(eval echo "\$SCM_VALUE")" >/dev/null; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -9886,8 +9926,8 @@ ts1a="7f000001" # "127.0.0.1"
 ts1="x${ts1p}${ts1a}x0000000000000000"
 ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1))
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts TCP4-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE"
-CMD1="$SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000"
+CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE"
+CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -9896,7 +9936,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -9947,8 +9987,8 @@ ts1a="00000000000000000000000000000001" # "[::1]"
 ts1="x${ts1p}x00000000x${ts1a}x00000000"
 ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1))
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts TCP6-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE"
-CMD1="$SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000"
+CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE"
+CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -9957,7 +9997,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -9997,8 +10037,8 @@ tdiff="$td/test$N.diff"
 ts0="$td/test$N.server"
 ts1="$td/test$N.client"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts UNIX-LISTEN:$ts0,reuseaddr PIPE"
-CMD1="$SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\""
+CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts0,reuseaddr PIPE"
+CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\""
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -10007,7 +10047,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10051,8 +10091,8 @@ ts0="x${ts0p}${ts0a}x0000000000000000"
 ts1b=$PORT; PORT=$((PORT+1))
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts SOCKET-LISTEN:2:6:$ts0,reuseaddr PIPE"
-CMD1="$SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b"
+CMD0="$TRACE $SOCAT $opts SOCKET-LISTEN:2:6:$ts0,reuseaddr PIPE"
+CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -10062,7 +10102,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10108,8 +10148,8 @@ ts1a="7f000001" # "127.0.0.1"
 ts1="x${ts1p}${ts1a}x0000000000000000"
 ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1))
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE"
-CMD1="$SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
+CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE"
+CMD1="$TRACE $SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -10118,7 +10158,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10163,8 +10203,8 @@ ts0="x${ts0p}${ts0a}x0000000000000000"
 ts1b=$PORT; PORT=$((PORT+1))
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE"
-CMD1="$SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b"
+CMD0="$TRACE $SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE"
+CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -10173,7 +10213,7 @@ echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10219,8 +10259,8 @@ ts0="x${ts0p}${ts0a}x0000000000000000"
 ts1b=$PORT; PORT=$((PORT+1))
 ts1="$ts1a:$ts1p"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -"
-CMD1="$SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b"
+CMD0="$TRACE $SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -"
+CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" >"$tf" &
 pid0="$!"
@@ -10230,7 +10270,7 @@ rc1="$?"
 sleep 1
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10276,8 +10316,8 @@ ts0b=$(printf "%04x" $ts0p)
 ts1b=$(printf "%04x" $ts1p)
 ts1="x${ts0b}${ts1a}x0000000000000000"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE"
-CMD1="$SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
+CMD0="$TRACE $SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE"
+CMD1="$TRACE $SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0="$!"
@@ -10286,7 +10326,7 @@ echo "$da" |$CMD1 2>>"${te}1" >"$tf"
 rc1="$?"
 kill "$pid0" 2>/dev/null; wait;
 if [ "$rc1" -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD0 &"
    cat "${te}0"
    echo "$CMD1"
@@ -10354,9 +10394,9 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts PTY,LINK=$tp pipe"
-CMD1="$SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0"
-CMD2="$SOCAT $opts - file:$tp,raw,echo=0"
+CMD0="$TRACE $SOCAT $opts PTY,LINK=$tp pipe"
+CMD1="$TRACE $SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0"
+CMD2="$TRACE $SOCAT $opts - file:$tp,raw,echo=0"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -10374,7 +10414,7 @@ if ! echo "$da" |diff - "$tf" >/dev/null; then
     echo "$da" |diff - "$tf"
     numCANT=$((numCANT+1))
 elif [ $rc2 -eq 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
     echo "$CMD1"
     echo "$CMD2"
@@ -10422,8 +10462,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts TCP4-L:$tp,setsockopt-int=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE"
-CMD1="$SOCAT $opts - TCP:localhost:$tp"
+CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,setsockopt-int=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE"
+CMD1="$TRACE $SOCAT $opts - TCP:localhost:$tp"
 CMD2="$CMD0"
 CMD3="$CMD1"
 printf "test $F_n $TEST... " $N
@@ -10445,14 +10485,14 @@ if ! echo "$da" |diff - "$tf"; then
     echo "$CMD1"
     numCANT=$((numCANT+1))
 elif [ $rc3 -ne 0 ]; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD3"
     cat "${te}2" "${te}3"
     numFAIL=$((numFAIL+1))
     listFAIL="$listFAIL $N"
 elif ! echo "$da" |diff - "${tf}3"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD3"
     echo "$da" |diff - "${tf}3"
@@ -10492,8 +10532,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="127.0.0.1:$tsl"
 da=$(date)
-CMD1="$SOCAT $opts SCTP4-LISTEN:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout SCTP4:$ts"
+CMD1="$TRACE $SOCAT $opts SCTP4-LISTEN:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout SCTP4:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid1=$!
@@ -10501,7 +10541,7 @@ waitsctp4port $tsl 1
 # SCTP does not seem to support half close, so we give it 1s to finish
 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -10545,8 +10585,8 @@ tdiff="$td/test$N.diff"
 tsl=$PORT
 ts="[::1]:$tsl"
 da=$(date)
-CMD1="$SOCAT $opts SCTP6-listen:$tsl,reuseaddr PIPE"
-CMD2="$SOCAT $opts stdin!!stdout SCTP6:$ts"
+CMD1="$TRACE $SOCAT $opts SCTP6-listen:$tsl,reuseaddr PIPE"
+CMD2="$TRACE $SOCAT $opts stdin!!stdout SCTP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
@@ -10554,7 +10594,7 @@ waitsctp6port $tsl 1
 # SCTP does not seem to support half close, so we let it 1s to finish
 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $SOCAT:\n"
+   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD1 &"
    cat "${te}1"
    echo "$CMD2"
@@ -10602,7 +10642,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
+CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
 CMD1="openssl s_client -port $PORT -verify 0"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
@@ -10656,7 +10696,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO"
+CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO"
 CMD1="openssl s_client -port $PORT -verify 0"
 printf "test $F_n $TEST... " $N
 eval "$CMD0 >/dev/null 2>\"${te}0\" &"
@@ -10701,7 +10741,7 @@ da="test$N $(date) $RANDOM"
 # prepare long data - perl might not be installed
 rm -f "$td/test$N.dat"
 i=0; while [ $i -lt 64 ]; do  echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
-CMD0="$SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO"
+CMD0="$TRACE $SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO"
 printf "test $F_n $TEST... " $N
 $CMD0 </dev/null 1>&0 2>"${te}0"
 rc0=$?
@@ -10735,7 +10775,7 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 i=0; while [ $i -lt 64 ]; do  echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
-CMD0="$SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO"
+CMD0="$TRACE $SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO"
 printf "test $F_n $TEST... " $N
 $CMD0 </dev/null 1>&0 2>"${te}0"
 rc0=$?
@@ -10773,8 +10813,8 @@ te="$td/test$N.stderr"
 ts="$td/test$N.sock"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts UNIX-LISTEN:$ts PIPE"
-CMD1="$SOCAT $opts -d - GOPEN:$ts"
+CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
+CMD1="$TRACE $SOCAT $opts -d - GOPEN:$ts"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" </dev/null &
 pid0=$!
@@ -10828,7 +10868,7 @@ TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socke
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.file"
 te="$td/test$N.stderr"
-CMD0="$SOCAT $opts -u UNIX-LISTEN:$tf /dev/null"
+CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$tf /dev/null"
 printf "test $F_n $TEST... " $N
 rm -f "$tf"; touch "$tf"
 $CMD0 >/dev/null 2>"${te}0"
@@ -10860,7 +10900,7 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts /dev/null PTY:/tmp/xyz"
+CMD0="$TRACE $SOCAT $opts /dev/null PTY:/tmp/xyz"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
@@ -10896,8 +10936,8 @@ tw="$td/test$N.wc-c"
 # make it large enough to exceed any atomic write size; but higher number might
 # take much time
 bytes=100000	# for Linux 2.6.? this must be >65536
-CMD0="$SOCAT $opts -u PIPE:$tp STDOUT"
-CMD1="$SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock"
+CMD0="$TRACE $SOCAT $opts -u PIPE:$tp STDOUT"
+CMD1="$TRACE $SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" |wc -c >"$tw" &
 pid=$!
@@ -10942,15 +10982,15 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe"
-CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD"
+CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe"
+CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD"
 printf "test $F_n $TEST... " $N
 eval "$CMD2 2>\"${te}1\" &"
 pid=$!	# background process id
 waittcp4port $PORT
 echo "$da" |$CMD >$tf 2>"${te}2"
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $SOCAT:\n"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD2 &"
     echo "$CMD"
     cat "${te}1"
@@ -10986,8 +11026,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append UNIX-L:$ts,fork,max-children=1"
-CMD1="$SOCAT $opts -u - UNIX-CONNECT:$ts"
+CMD0="$TRACE $SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append UNIX-L:$ts,fork,max-children=1"
+CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -11040,7 +11080,7 @@ printf "test $F_n $TEST... " $N
 #perl -e 'print "\r","Z"x513' >"$ti"
 echo $E -n "\rA" >"$ti"
 i=0; while [ $i -lt 32 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$ti"; let i=i+1; done
-$SOCAT - system:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0"
+$TRACE $SOCAT - SYSTEM:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0"
 rc=$?
 rc0="$(grep ^rc= "${te}0" |sed 's/.*=//')"
 if [ $rc -ne 0 ]; then
@@ -11081,9 +11121,9 @@ RLIMIT_NOFILE="$(ulimit -n)"
 if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
     $PRINTF "${YELLOW}cannot determine ulimit -n"
 else
-CMD0="$SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,range=$LOCALHOST:255.255.255.255 PIPE"
-CMD1="$SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT,bind=$SECONDADDR"
-CMD2="$SOCAT $opts - TCP:$LOCALHOST:$PORT"
+CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,range=$LOCALHOST:255.255.255.255 PIPE"
+CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT,bind=$SECONDADDR"
+CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT,bind=$LOCALHOST"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -11142,9 +11182,9 @@ EF=; for p in ef; do
 	EF="ef "; break
     fi
 done
-CMD0="$SOCAT $opts TCP-LISTEN:$PORT,reuseaddr FILE:/dev/null"
-#CMD1="$EF $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80"
-CMD1="$EF $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT"
+CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr FILE:/dev/null"
+#CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80"
+CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -11189,8 +11229,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 #tdiff="$td/test$N.diff"
 #da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,so-keepalive EXEC:\"$FILAN -i 1\",nofork"
-CMD1="$SOCAT $opts - TCP4:$LOCALHOST:$PORT"
+CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,so-keepalive EXEC:\"$FILAN -i 1\",nofork"
+CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
 printf "test $F_n $TEST... " $N
 eval $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -11241,8 +11281,8 @@ tf1="$td/test$N.1.stdout"
 te1="$td/test$N.1.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,ciphers=aNULL,verify=0, PIPE"
-CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,bind=$LOCALHOST,ciphers=aNULL,verify=0"
+CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,ciphers=aNULL,verify=0, PIPE"
+CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,bind=$LOCALHOST,ciphers=aNULL,verify=0"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"$te0" &
 pid0=$!
@@ -11294,8 +11334,8 @@ tf="$td/test$N.stdout"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 #testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0
-CMD0="$SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,range=127.0.0.1/0 CREATE:$tf"
-CMD1="$SOCAT $opts - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR"
+CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,range=127.0.0.1/0 CREATE:$tf"
+CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" &
 pid0=$!
@@ -11353,9 +11393,9 @@ 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"
+    CMD0="$TRACE $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"
+    CMD0="$TRACE $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" &
@@ -11426,9 +11466,9 @@ 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"
+    CMD0="$TRACE $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"
+    CMD0="$TRACE $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" &
@@ -11502,9 +11542,9 @@ 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"
+    CMD0="$TRACE $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"
+    CMD0="$TRACE $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" &
@@ -11575,9 +11615,9 @@ 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"
+    CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2"
 else
-    CMD0="$SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2"
+    CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2"
 fi
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"$te0" &
@@ -11643,9 +11683,9 @@ 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"
+    CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2"
 else
-    CMD0="$SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2"
+    CMD0="$TRACE $SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2"
 fi
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"$te0" &
@@ -11719,8 +11759,8 @@ te="$td/test$N.stderr"
 tl="$td/test$N.pty"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE"
-CMD1="$SOCAT $opts - $tl,raw,echo=0"
+CMD0="$TRACE $SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE"
+CMD1="$TRACE $SOCAT $opts - $tl,raw,echo=0"
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
 (echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf"
@@ -11789,8 +11829,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$SOCAT $opts server-address PIPE"
-CMD1="$SOCAT $opts - client-address"
+CMD0="$TRACE $SOCAT $opts server-address PIPE"
+CMD1="$TRACE $SOCAT $opts - client-address"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
diff --git a/vsnprintf_r.c b/vsnprintf_r.c
new file mode 100644
index 0000000..473ddba
--- /dev/null
+++ b/vsnprintf_r.c
@@ -0,0 +1,569 @@
+/* vsnprintf_r.c */
+/* Copyright Gerhard Rieger */
+
+/* a reduced but async-signal-safe and thread-safe version of vsnprintf */
+
+#include "config.h"
+
+#include <stddef.h>	/* ptrdiff_t */
+#include <ctype.h>	/* isdigit() */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#include <sys/utsname.h>
+#include <time.h>	/* time_t, strftime() */
+#include <sys/time.h>	/* gettimeofday() */
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "vsnprintf_r.h"
+
+/* helper functions for vsnprintf_r():
+   e.g. convert an unsigned long to decimal string.
+   in: field (must be long enough for all digits and \0
+       n: length of field in bytes
+       ulo: the value
+   returns: the pointer to the result string (need not be ==field)
+*/
+
+/* this function converts an unsigned long number to decimal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *_diag_ulong_to_dec(char *field, size_t n, unsigned long ulo) {
+   char *np = field+n;	/* point to the end */
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /* this is not optimal - uses much CPU, but simple to implement */
+   /*  calculate the result from right to left */
+   do { if (np==field) return NULL; *--np = '0'+(ulo%10); } while (ulo/=10);
+   return np;
+}
+
+/* this function converts an unsigned long number to decimal ASCII
+   and pads it with space or '0' when size and leading0 are set appropriately
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it reduces size to n-1 if it is greater or equal
+   it terminates result with \0
+ */
+static char *diag_ulong_to_dec(char *field, size_t n, unsigned long ulo, int leading0, int size) {
+   char *np;
+   char c;
+   int i;
+
+   if (n == 0)  return NULL;
+   np = _diag_ulong_to_dec(field, n, ulo);
+   if (np == NULL) return np;
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (--i >= 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+/* this function converts a signed long number to decimal ASCII  
+   and pads it with space or '0' when size and leading0 are set appropriately
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it reduces size to n-1 if it is greater or equal
+   it terminates result with \0
+ */
+/* like diag_ulong_to_dec but signed; fields need also space for '-' */
+static char *diag_long_to_dec(char *field, size_t n, long lo, int leading0, int size) {
+   char *np;
+   int minus;
+   unsigned long ulo;
+   int i;
+
+   if ((minus = (lo < 0))) {
+      ulo = (~lo)+1;
+   } else {
+      ulo = lo;
+   }
+   np = _diag_ulong_to_dec(field, n, ulo);
+   if (np == NULL)  return np;
+
+   if (size) {
+      if (size >= n)  size = n-1;
+      i = size - strlen(np);
+      if (leading0) {
+	 if (minus) --i; 
+	 while (--i >= 0) {
+	    *--np = '0';
+	 }
+	 if (minus)  *--np = '-';
+      } else {
+	 if (minus)  { *--np = '-'; --i; }
+	 while (--i >= 0) {
+	    *--np = ' ';
+	 }
+      }
+   } else {
+      if (minus)  *--np = '-';
+   }
+   return np;
+}
+
+/* this function converts an unsigned long number to hexadecimal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *diag_ulong_to_hex(char *field, size_t n, unsigned long ulo, int leading0, size_t size) {
+   char *np = field+n;	/* point to the end */
+   int i;
+   char c;
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /*  calculate the result from right to left */
+   do { if (np==field) return NULL; i = (ulo&0x0f);
+      *--np = (i<10?'0':('a'-10))+i; }
+   while (ulo>>=4);
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (--i >= 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+/* this function converts an unsigned long number to octal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *diag_ulong_to_oct(char *field, size_t n, unsigned long ulo, int leading0, size_t size) {
+   char *np = field+n;	/* point to the end */
+   int i;
+   char c;
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /* calculate the result from right to left */
+   do { if (np==field) return NULL;  i = (ulo&0x07); *--np = '0'+i; }
+   while (ulo>>=3);
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (--i >= 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+
+#if HAVE_TYPE_LONGLONG
+
+/* this function converts an unsigned long long number to decimal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *_diag_ulonglong_to_dec(char *field, size_t n, unsigned long long ull) {
+   char *np = field+n;	/* point to the end */
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /* this is not optimal - uses much CPU, but simple to implement */
+   /* calculate the result from right to left */
+   do { if (np==field) return NULL; *--np = '0'+(ull%10); } while (ull/=10);
+   return np;
+}
+
+/* this function converts an unsigned long long number to decimal ASCII
+   and pads it with space or '0' when size and leading0 are set appropriately
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it reduces size to n-1 if it is greater or equal
+   it terminates result with \0
+ */
+static char *diag_ulonglong_to_dec(char *field, size_t n, unsigned long long ull, int leading0, int size) {
+   char *np;
+   char c;
+   int i;
+
+   if (n == 0)  return NULL;
+   np = _diag_ulonglong_to_dec(field, n, ull);
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (i-- > 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+/* this function converts a signed long long number to decimal ASCII  
+   and pads it with space or '0' when size and leading0 are set appropriately
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it reduces size to n-1 if it is greater or equal
+   it terminates result with \0
+ */
+/* like diag_ulonglong_to_dec but signed; fields need also space for '-' */
+static char *diag_longlong_to_dec(char *field, size_t n, long long ll, int leading0, int size) {
+   char *np;
+   int minus;
+   unsigned long ull;
+   int i;
+
+   if ((minus = (ll < 0))) {
+      ull = (~ll)+1;
+   } else {
+      ull = ll;
+   }
+   np = _diag_ulonglong_to_dec(field, n, ull);
+   if (np == NULL)  return np;
+
+   if (size) {
+      if (size >= n)  size = n-1;
+      i = size - strlen(np);
+      if (leading0) {
+	 if (minus) --i; 
+	 while (--i >= 0) {
+	    *--np = '0';
+	 }
+	 if (minus)  *--np = '-';
+      } else {
+	 if (minus)  { *--np = '-'; --i; }
+	 while (--i >= 0) {
+	    *--np = ' ';
+	 }
+      }
+   }	     
+   return np;
+}
+
+/* this function converts an unsigned long long number to hexadecimal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *diag_ulonglong_to_hex(char *field, size_t n, unsigned long long ull, int leading0, size_t size) {
+   char *np = field+n;	/* point to the end */
+   unsigned int i;
+   char c;
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /* calculate the result from right to left */
+   do { if (np==field) return NULL; i = (ull&0x0f);
+      *--np = (i<10?'0':('a'-10))+i; }
+   while (ull>>=4);
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (--i >= 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+/* this function converts an unsigned long long number to octal ASCII
+   it is async signal safe and thread safe
+   it returns NULL if n==0
+   it returns NULL if field is too short to hold the result
+   it returns a pointer to the result string (somewhere within field)
+   it terminates result with \0
+ */
+static char *diag_ulonglong_to_oct(char *field, size_t n, unsigned long long ull, int leading0, size_t size) {
+   char *np = field+n;	/* point to the end */
+   int i;
+   char c;
+
+   if (n == 0)  return NULL;
+   *--np = '\0';	/* \0 in last char of string */
+   /* calculate the result from right to left */
+   do { if (np==field) return NULL;  i = (ull&0x07); *--np = '0'+i; }
+   while (ull>>=3);
+   if (size) {
+      if (size >= n)  size = n-1;
+      if (leading0) {
+	 c = '0';
+      } else {
+	 c = ' ';
+      }
+      i = size - strlen(np);
+      while (--i >= 0) {
+	 *--np = c;
+      }
+   }	     
+   return np;
+}
+
+#endif /* HAVE_TYPE_LONGLONG */
+
+
+/* this function is designed as a variant of vsnprintf(3) but async signal safe
+   and thread safe
+   it currently only implements a subset of the format directives
+   returns <0 if an error occurred (no scenario know yet)
+   returns >=size if output is truncated (conforming to C99 standard)
+*/
+int vsnprintf_r(char *str, size_t size, const char *format, va_list ap) {
+   size_t i = 0;
+   char c;
+   int full = 0;		/* indicate if output buffer full */
+
+   --size;	/* without trailing \0 */
+   while (c = *format++) {
+      if (c == '\\') {
+	 
+      } else if (c == '%') {
+#if HAVE_TYPE_LONGLONG
+#	 define num_buff_len ((sizeof(unsigned long long)*8+2)/3+1)	/* hold up to u long long in octal w/ \0 */
+#else
+#	 define num_buff_len ((sizeof(unsigned long)*8+2)/3+1)];	/* hold up to u long in octal w/ \0 */
+#endif
+	 char lengthmod = '\0';	/* 'h' 'l' 'L' 'z' */
+	 int leading0 = 0;	/* or 1 */
+	 size_t fsize = 0;	/* size of field */
+	 const char *st;		/* string */
+	 long  lo; unsigned long  ulo;
+#if HAVE_TYPE_LONGLONG
+	 long long ll; unsigned long long ull;
+#endif
+	 char field[num_buff_len];	/* result of number conversion */
+	 char *np;			/* num pointer */
+
+	 c = *format++;
+	 if (c == '\0')  { break; }
+	 
+	 /* flag characters */
+	 switch (c) {
+	 case '0': leading0 = 1;  c = *format++;  break;
+	    /* not handled: '#' '-' ' ' '+' '\'' */
+	 }
+	 if (c == '\0')  { break; }
+
+	 /* field width */
+	 switch (c) {
+	 case '1': case '2': case '3': case '4':
+	 case '5': case '6': case '7': case '8': case '9':
+	    do {
+	       fsize = 10*fsize+(c-'0');
+	       c = *format++;
+	    } while (c && isdigit(c));
+	    break;
+	 }
+	 if (c == '\0')  { break; }
+
+	 /* precision - not handles */
+
+	 /* length modifier */
+	 switch (c) {
+	    /* not handled: 'q' 'j' 't' */
+	    /* handled: 'h' 'hh'->'H' 'z' 'Z'->'z' 'l' 'll'->'L' 'L' */
+	 case 'Z': c = 'z'; /* fall through */
+#if HAVE_TYPE_LONGLONG
+	 case 'L':
+#endif
+	 case 'z': lengthmod = c; c = *format++; break;
+	 case 'h':
+	    lengthmod = c;
+	    if ((c = *format++) == 'h') {
+	       lengthmod = 'H'; c = *format++; 
+	    }
+	    break;
+	 case 'l': 
+	    lengthmod = c;
+	    if ((c = *format++) == 'l') {
+	       lengthmod = 'L'; c = *format++; 
+	    }
+	    break;
+	 }
+	 if (c == '\0')  { break; }
+
+	 /* conversion specifier */
+	 switch (c) {
+	 case 'c': c = va_arg(ap, int); /* fall through */
+	 case '%': *str++ = c; if (++i == size) { full = 1; } break;
+
+	 case 's': st = va_arg(ap, const char *);
+	    /* no modifier handled! */
+	    while (c = *st++) {
+	       *str++ = c;
+	       if (++i == size) { full = 1; break; }
+	    }
+	    break;
+	 case 'd':
+#if HAVE_TYPE_LONGLONG
+	    if (lengthmod == 'L') {
+	       ll = va_arg(ap, long long);
+	       np = diag_longlong_to_dec(field, num_buff_len, ll, leading0, fsize);
+	       while (c = *np++)  {
+		  *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    } else
+#endif
+	    {
+	       switch (lengthmod) {
+	       case 'l': lo = va_arg(ap, long); break;
+	       case 'z': lo = va_arg(ap, ptrdiff_t); break;
+	       default: lo = va_arg(ap, int); break;
+	       }
+	       np = diag_long_to_dec(field, num_buff_len, lo, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    }
+	    break;
+	 case 'u':
+#if HAVE_TYPE_LONGLONG
+	    if (lengthmod == 'L') {
+	       ull = va_arg(ap, unsigned long long);
+	       np = diag_ulonglong_to_dec(field, num_buff_len, ull, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    } else
+#endif
+	    {
+	       switch (lengthmod) {
+	       case 'l': ulo = va_arg(ap, unsigned long); break;
+	       case 'z': ulo = va_arg(ap, size_t); break;
+	       default: ulo = va_arg(ap, unsigned int); break;
+	       }
+	       np = diag_ulong_to_dec(field, num_buff_len, ulo, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    }
+	    break;
+	 case 'p':
+	    ulo = va_arg(ap, size_t);
+	    np = diag_ulong_to_hex(field, num_buff_len, ulo, leading0, fsize);
+	    *str++ = '0'; if (++i == size) { full = 1; break; }
+	    *str++ = 'x'; if (++i == size) { full = 1; break; }
+	    while (c = *np++)  { *str++ = c;
+	       if (++i == size) { full = 1; break; }
+	    }
+	    break;
+	 case 'x':
+#if HAVE_TYPE_LONGLONG
+	    if (lengthmod == 'L') {
+	       ull = va_arg(ap, unsigned long long);
+	       np = diag_ulonglong_to_hex(field, num_buff_len, ull, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    } else
+#endif
+	    {
+	       switch (lengthmod) {
+	       case 'l': ulo = va_arg(ap, unsigned long); break;
+	       case 'z': ulo = va_arg(ap, size_t); break;
+	       default: ulo = va_arg(ap, unsigned int); break;
+	       }
+	       np = diag_ulong_to_hex(field, num_buff_len, ulo, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    }
+	    break;
+	 case 'o':
+#if HAVE_TYPE_LONGLONG
+	    if (lengthmod == 'L') {
+	       ull = va_arg(ap, unsigned long long);
+	       np = diag_ulonglong_to_oct(field, num_buff_len, ull, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) break;
+	       }
+	    } else
+#endif
+	    {
+	       switch (lengthmod) {
+	       case 'l': ulo = va_arg(ap, unsigned long); break;
+	       case 'z': ulo = va_arg(ap, size_t); break;
+	       default: ulo = va_arg(ap, unsigned int); break;
+	       }
+	       np = diag_ulong_to_oct(field, num_buff_len, ulo, leading0, fsize);
+	       while (c = *np++)  { *str++ = c;
+		  if (++i == size) { full = 1; break; }
+	       }
+	    }
+	    break;
+	 default:
+	    *str++ = c;  if (++i == size) { full = 1; break; }
+	 }
+	 if (full)  break;
+      } else {
+	 *str++ = c;
+	 if (++i == size)  break;
+      }
+   }
+   *str = '\0';
+   return i;
+}
+
+int snprintf_r(char *str, size_t size, const char *format, ...) {
+   int result;
+   va_list ap;
+   va_start(ap, format);
+   result = vsnprintf_r(str, size, format, ap);
+   va_end(ap);
+   return result;
+}
+
diff --git a/vsnprintf_r.h b/vsnprintf_r.h
new file mode 100644
index 0000000..ac17e0f
--- /dev/null
+++ b/vsnprintf_r.h
@@ -0,0 +1,11 @@
+/* source: vsnprintf_r.h */
+/* Copyright Gerhard Rieger */
+/* Published under the GNU General Public License V.2, see file COPYING */
+
+#ifndef __vsnprintf_r_h_included
+#define __vsnprintf_r_h_included 1
+
+int vsnprintf_r(char *str, size_t size, const char *format, va_list ap);
+int snprintf_r(char *str, size_t size, const char *format, ...);
+
+#endif /* !defined(__vsnprintf_r_h_included) */
diff --git a/xio-socket.c b/xio-socket.c
index 305c6a4..0578e8e 100644
--- a/xio-socket.c
+++ b/xio-socket.c
@@ -1099,7 +1099,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
    handler sets xio_hashappened if the pid matched.
 */
 static pid_t xio_waitingfor;	/* info from recv loop to signal handler:
-				   indicates the pid that of the child process
+				   indicates the pid of the child process
 				   that should send us the USR1 signal */
 static bool xio_hashappened;	/* info from signal handler to loop: child
 				   process has read ("consumed") the packet */
@@ -1113,6 +1113,9 @@ void xiosigaction_hasread(int signum
    int _errno;
    int status = 0;
    bool wassig = false;
+
+   _errno = errno;
+   diag_in_handler = 1;
 #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO)
    Debug5("xiosigaction_hasread(%d, {%d,%d,%d,"F_pid"}, )",
 	  signum, siginfo->si_signo, siginfo->si_errno, siginfo->si_code,
@@ -1121,35 +1124,39 @@ void xiosigaction_hasread(int signum
    Debug1("xiosigaction_hasread(%d)", signum);
 #endif
    if (signum == SIGCHLD) {
-      _errno = errno;
       do {
 	 pid = Waitpid(-1, &status, WNOHANG);
 	 if (pid == 0) {
 	    Msg(wassig?E_INFO:E_WARN,
 		"waitpid(-1, {}, WNOHANG): no child has exited");
 	    Info("xiosigaction_hasread() finished");
-	    errno = _errno;
 	    Debug("xiosigaction_hasread() ->");
+	    diag_in_handler = 0;
+	    errno = _errno;
 	    return;
 	 } else if (pid < 0 && errno == ECHILD) {
-	    Msg1(wassig?E_INFO:E_WARN,
-		 "waitpid(-1, {}, WNOHANG): %s", strerror(errno));
+	    Msg(wassig?E_INFO:E_WARN,
+		 "waitpid(-1, {}, WNOHANG): "F_strerror);
 	    Info("xiosigaction_hasread() finished");
-	    errno = _errno;
 	    Debug("xiosigaction_hasread() ->");
+	    diag_in_handler = 0;
+	    errno = _errno;
 	    return;
 	 }
 	 wassig = true;
 	 if (pid < 0) {
-	    Warn2("waitpid(-1, {%d}, WNOHANG): %s", status, strerror(errno));
+	    Warn1("waitpid(-1, {%d}, WNOHANG): "F_strerror, status);
 	    Info("xiosigaction_hasread() finished");
-	    errno = _errno;
 	    Debug("xiosigaction_hasread() ->");
+	    diag_in_handler = 0;
+	    errno = _errno;
 	    return;
 	 }
 	 if (pid == xio_waitingfor) {
 	    xio_hashappened = true;
 	    Debug("xiosigaction_hasread() ->");
+	    diag_in_handler = 0;
+	    errno = _errno;
 	    return;
 	 }
       } while (1);
@@ -1161,7 +1168,12 @@ void xiosigaction_hasread(int signum
 #else
    xio_hashappened = true;
 #endif
+#if !HAVE_SIGACTION
+   Signal(sig, xiosigaction_hasread);
+#endif /* !HAVE_SIGACTION */
    Debug("xiosigaction_hasread() ->");
+   diag_in_handler = 0;
+   errno = _errno;
    return;
 }
 
@@ -1265,7 +1277,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
    {
       struct sigaction act;
       memset(&act, 0, sizeof(struct sigaction));
-      act.sa_flags   = SA_NOCLDSTOP|SA_RESTART
+      act.sa_flags   = SA_NOCLDSTOP/*|SA_RESTART*/
 #ifdef SA_SIGINFO /* not on Linux 2.0(.33) */
 	 |SA_SIGINFO
 #endif
@@ -1278,6 +1290,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
 #else /* Linux 2.0(.33) does not have sigaction.sa_sigaction */
       act.sa_handler = xiosigaction_hasread;
 #endif
+      sigfillset(&act.sa_mask);
       if (Sigaction(SIGUSR1, &act, NULL) < 0) {
          /*! Linux man does not explicitely say that errno is defined */
          Warn1("sigaction(SIGUSR1, {&xiosigaction_subaddr_ok}, NULL): %s", strerror(errno));
diff --git a/xioexit.c b/xioexit.c
index 9c27011..65b4752 100644
--- a/xioexit.c
+++ b/xioexit.c
@@ -7,6 +7,7 @@
 #include "xiosysincludes.h"
 #include "compat.h"
 #include "xio.h"
+#include "error.h"
 
 
 /* this function closes all open xio sockets on exit, if they are still open.
@@ -14,9 +15,12 @@
 void xioexit(void) {
    int i;
 
+   diag_in_handler = 0;
+   Debug("starting xioexit()");
    for (i = 0; i < XIO_MAXSOCK; ++i) {
       if (sock[i] != NULL && sock[i]->tag != XIO_TAG_INVALID) {
 	 xioclose(sock[i]);
       }
    }
+   Debug("finished xioexit()");
 }
diff --git a/xioshutdown.c b/xioshutdown.c
index fc53068..e7833de 100644
--- a/xioshutdown.c
+++ b/xioshutdown.c
@@ -11,8 +11,13 @@
 static pid_t socat_kill_pid;	/* here we pass the pid to be killed in sighandler */
 
 static void signal_kill_pid(int dummy) {
-   Notice("SIGALRM while waiting for w/o child process to die, killing it now");
+   int _errno;
+   _errno = errno;
+   diag_in_handler = 1;
+   Notice("SIGALRM while waiting for wo child process to die, killing it now");
    Kill(socat_kill_pid, SIGTERM);
+   diag_in_handler = 0;
+   errno = _errno;
 }
 
 int xioshutdown(xiofile_t *sock, int how) {
@@ -114,7 +119,13 @@ int xioshutdown(xiofile_t *sock, int how) {
 	    we raise an alarm after some time.
 	    NOTE: the alarm does not terminate waitpid() on Linux/glibc (BUG?),
 	    therefore we have to do the kill in the signal handler */
-	 Signal(SIGALRM, signal_kill_pid);
+	 {
+	    struct sigaction act;
+	    sigfillset(&act.sa_mask);
+	    act.sa_flags = 0;
+	    act.sa_handler = signal_kill_pid;
+	    Sigaction(SIGALRM, &act, NULL);
+	 }
 	 socat_kill_pid = sock->stream.para.exec.pid;
 #if HAVE_SETITIMER
 	 /*! with next feature release, we get usec resolution and an option */
diff --git a/xiosigchld.c b/xiosigchld.c
index a19ce3f..0e7d0b0 100644
--- a/xiosigchld.c
+++ b/xiosigchld.c
@@ -27,6 +27,7 @@ int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)) {
 }
 
 /* exec'd child has died, perform appropriate changes to descriptor */
+/* is async-signal-safe */
 static int sigchld_stream(struct single *file) {
    /*!! call back to application */
    file->para.exec.pid = 0;
@@ -47,7 +48,7 @@ static int xio_checkchild(xiofile_t *socket, int socknum, pid_t deadchild) {
 	     socket->stream.para.exec.pid == deadchild) {
 	    Info2("exec'd process %d on socket %d terminated",
 		  socket->stream.para.exec.pid, socknum);
-	    sigchld_stream(&socket->stream);
+	    sigchld_stream(&socket->stream);	/* is async-signal-safe */
 	    return 1;
 	 }
       } else {
@@ -78,8 +79,8 @@ void childdied(int signum) {
 			   to set it to EINTR _before_ handling the signal, and
 			   then passes the value left by the signal handler to
 			   the caller of select(), accept() etc. */
-   /* is not thread/signal save, but confused messages in rare cases are better
-      than no messages at all */
+   diag_in_handler = 1;
+   Notice1("childdied(): handling signal %d", signum);
    Info1("childdied(signum=%d)", signum);
    do {
       pid = Waitpid(-1, &status, WNOHANG);
@@ -87,19 +88,22 @@ void childdied(int signum) {
 	 Msg(wassig?E_INFO:E_WARN,
 	     "waitpid(-1, {}, WNOHANG): no child has exited");
 	 Info("childdied() finished");
+	 diag_in_handler = 0;
 	 errno = _errno;
 	 return;
       } else if (pid < 0 && errno == ECHILD) {
-	 Msg1(wassig?E_INFO:E_WARN,
-	      "waitpid(-1, {}, WNOHANG): %s", strerror(errno));
+	 Msg(wassig?E_INFO:E_WARN,
+	      "waitpid(-1, {}, WNOHANG): "F_strerror);
 	 Info("childdied() finished");
+	 diag_in_handler = 0;
 	 errno = _errno;
 	 return;
       }
       wassig = true;
       if (pid < 0) {
-	 Warn2("waitpid(-1, {%d}, WNOHANG): %s", status, strerror(errno));
+	 Warn1("waitpid(-1, {%d}, WNOHANG): "F_strerror, status);
 	 Info("childdied() finished");
+	 diag_in_handler = 0;
 	 errno = _errno;
 	 return;
       }
@@ -142,11 +146,12 @@ void childdied(int signum) {
 #if !HAVE_SIGACTION
    /* we might need to re-register our handler */
    if (Signal(SIGCHLD, childdied) == SIG_ERR) {
-      Warn2("signal(SIGCHLD, %p): %s", childdied, strerror(errno));
+      Warn("signal(SIGCHLD, childdied): "F_strerror);
    }
 #endif /* !HAVE_SIGACTION */
   } while (1);
    Info("childdied() finished");
+   diag_in_handler = 0;
    errno = _errno;
 }
 
@@ -155,12 +160,13 @@ int xiosetchilddied(void) {
 #if HAVE_SIGACTION
    struct sigaction act;
    memset(&act, 0, sizeof(struct sigaction));
-   act.sa_flags   = SA_NOCLDSTOP|SA_RESTART
+   act.sa_flags   = SA_NOCLDSTOP/*|SA_RESTART*/
 #ifdef SA_NOMASK
       |SA_NOMASK
 #endif
       ;
    act.sa_handler = childdied;
+   sigfillset(&act.sa_mask);
    if (Sigaction(SIGCHLD, &act, NULL) < 0) {
       /*! man does not say that errno is defined */
       Warn2("sigaction(SIGCHLD, %p, NULL): %s", childdied, strerror(errno));
diff --git a/xiosignal.c b/xiosignal.c
index f41d24d..c795aeb 100644
--- a/xiosignal.c
+++ b/xiosignal.c
@@ -1,5 +1,5 @@
 /* source: xiosignal.c */
-/* Copyright Gerhard Rieger 2001-2003 */
+/* Copyright Gerhard Rieger */
 /* Published under the GNU General Public License V.2, see file COPYING */
 
 /* this file contains code for handling signals (except SIGCHLD) */
@@ -35,6 +35,7 @@ static struct socat_sig_desc socat_sigquit;
 #endif
 
 
+/* is async-signal-safe */
 static struct socat_sig_desc *socat_get_sig_desc(int signum) {
    struct socat_sig_desc *sigdesc;
    switch (signum) {
@@ -46,21 +47,26 @@ static struct socat_sig_desc *socat_get_sig_desc(int signum) {
    return sigdesc;
 }
 
-/* a signal handler that eventually passes the signal to sub processes */
+/* a signal handler that possibly passes the signal to sub processes */
 void socatsignalpass(int sig) {
    int i;
    struct socat_sig_desc *sigdesc;
-
-   Debug1("socatsignalpass(%d)", sig);
-   if ((sigdesc = socat_get_sig_desc(sig)) == NULL) {
+   int _errno;
+
+   _errno = errno;
+   diag_in_handler = 1;
+   Notice1("socatsignalpass(%d)", sig);
+   if ((sigdesc = socat_get_sig_desc(sig)) == NULL) {	/* is async-signal-safe */
+      diag_in_handler = 0;
+      errno = _errno;
       return;
    }
 
    for (i=0; i<sigdesc->sig_use; ++i) {
       if (sigdesc->sig_pids[i]) {
 	 if (Kill(sigdesc->sig_pids[i], sig) < 0) {
-	    Warn3("kill("F_pid", %d): %s",
-		  sigdesc->sig_pids[i], sig, strerror(errno));
+	    Warn2("kill("F_pid", %d): %m",
+		  sigdesc->sig_pids[i], sig);
 	 }
       }
    }
@@ -68,6 +74,8 @@ void socatsignalpass(int sig) {
    Signal(sig, socatsignalpass);
 #endif /* !HAVE_SIGACTION */
    Debug("socatsignalpass() ->");
+   diag_in_handler = 0;
+   errno = _errno;
 }
 
 
@@ -91,8 +99,9 @@ int xio_opt_signal(pid_t pid, int signum) {
 #if HAVE_SIGACTION
       struct sigaction act;
       memset(&act, 0, sizeof(struct sigaction));
-      act.sa_flags   = SA_RESTART;
+      act.sa_flags   = 0/*|SA_RESTART*/;
       act.sa_handler = socatsignalpass;
+      sigfillset(&act.sa_mask);
       if (Sigaction(signum, &act, NULL) < 0) {
 	 /*! man does not say that errno is defined */
 	 Warn3("sigaction(%d, %p, NULL): %s", signum, &act, strerror(errno));
-- 
2.43.0

