diff --git a/CHANGES b/CHANGES
index 3b654aa..b64fb4c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,191 @@
 
+####################### V 1.8.0.3:
+
+Security:
+	readline.sh has new option -lf <logfile> for stderr. If this option is
+	not given it logs to a file in . (cwd) only when . is not writable by
+	other users.
+
+Corrections:
+	Fixed display of option phases in help output.
+
+	filan -s  displayed "(stream)" instead of "tcp" with addresses
+	(regression).
+
+	Fixed a bug that made ignoreeof fail in 1.8.0.0 and 1.8.0.1;
+	corrected test IGNOREEOF.
+	Thanks to Rusty Bird for the precise problem report.
+
+	Fixed the regression introduced with version 1.8.0.1 that in socks5
+	addresses the explicit socksport (2nd address parameter) was ignored.
+	Thanks to Jakub Fišer for reporting this bug.
+
+	Do not log simple successful write with NOTICE level.
+
+	On partial write to not poll with sleep() but use select()/poll().
+
+	Partial write situations respect total inactivity timeout when
+	nonblocking.
+
+	Fixed a bug that could lead to error "xiopoll(...): Bad file descriptor"
+	or to undefined behaviour before terminating Socat with addresses EXEC,
+	SYSTEM, or SHELL.
+
+	Option ip-add-source-membership did not work.
+	Thanks to Duncan Sands and others for reporting this issue and sending
+	the fix.
+
+	Option ip-add-membership with only two parameters crashed or failed
+	when malloc() does not initialize memory with zeros.
+	Thanks to Nicolas Cavallari for reporting and fixing this bug.
+
+	The readline() library function does not output the newline of empty
+	input lines. Changed Socat to explicitly print the newline in this
+	case.
+
+	Fixed implementation of options o-creat, o-excl, and o-cloexec with
+	POSIXMQ-* addresses.
+	POSIXMQ addresses are no longer experimental.
+
+	With version 1.8.0.0, and with 1.8.0.1 and option -0, the following
+	command failed:
+	socat UDP-LISTEN:1234,fork,reuseaddr,bind=127.0.0.1 -
+	Message: "E xioopen_ipdgram_listen(): unknown address family 0":
+	Thanks to Brian Woo for reporting this issue.
+	Test: UDP_LISTEN_BIND4
+
+	Protected SSL_connect() from SIGCHLD,SIGUSR1.
+
+	Nanosleep() trace output now in decimal form.
+
+	UNIX-LISTEN with bind option terminated with INTERNAL error, this is
+	now handled properly.
+	Test: UNIX_L_BIND
+
+	Removed unused bytes variable from gettimestamp(), corrected #elsif,
+	and socks4 record length.
+	Thanks to clang-18 and gcc-13.
+
+	Address TCP-CONNECT, when target address resolves to both IPv4 and
+	IPv6, now tries to take into account bind address for protocol
+	selection.
+
+	Reworked and harmonized ipapp client addresses.
+	Tests: TCP_CONNECT_RETRY SCTP_CONNECT_RETRY DCCP_CONNECT_RETRY
+	OPENSSL_CONNECT_RETRY SOCKS4_RETRY SOCKS5_CONNECT_RETRY
+	PROXY_CONNECT_RETRY
+
+	Socks and proxy clients now also support option max-children.
+	Tests: TCP_CONNECT_MAXCHILDREN SCTP_CONNECT_MAXCHILDREN
+	DCCP_CONNECT_MAXCHILDREN OPENSSL_CONNECT_MAXCHILDREN
+	SOCKS4_MAXCHILDREN SOCKS5_CONNECT_MAXCHILDREN PROXY_CONNECT_MAXCHILDREN
+
+	On failure of getpwuid() (used in options su and su-d) now consider
+	errno.
+
+	When IP4 was completed deconfigured, UDP6-RECVFROM with range option
+	failed.
+
+	Fixed preprocessor directives in macro invocation.
+	Thanks to Mario de Weerd for reporting this issue.
+
+	CONNECT addresses could use a wrong IPPROTO when getaddrinfo() does not
+	support the selected one (at least on Debian-4 with SCTP).
+
+	socat -h (help) did not show option groups POSIXMQ, SCTP, DCCP, and
+	UDPLITE of addresses.
+
+Features:
+	POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T,
+	makes it possible to terminate Socat in case the queue is empty.
+
+	New option posixmq-flush (mq-flush) for POSIXMQ addresses empties the
+	queue before starting to transfer data.
+	Test: LINUX_POSIXMQ_FLUSH
+
+	New options posixmq-maxmsg, posixmq-msgsize.
+	Tests: POSIXMQ_MAXMSG POSIXMQ_MSGSIZE
+
+	POSIXMQ is now an alias for POSIXMQ-BIDIRECTIONAL. It can also be used
+	in unidirectional context.
+
+	Procan uses getresuid() and getresgid() when available, to determine
+	the saved set-user-ID.
+
+	Procan prints more C-defines, esp.O_*, AI_*, EAI_*; __GLIBC__;
+	prints some C-defines in oct and hex;
+	added option -V
+
+	Procan tells if char is signed or unsigned
+
+	Socat now prints an info message when implicitly setting SO_REUSEADDR.
+	Thanks to Michael Renner for this suggestion.
+
+	Added generic options setsockopt-socket and setsockopt-connected that
+	are applied after socket() or when connected.
+
+	POSIXMQ addresses now print a warning when options posixmq-maxmsg or
+	posixmq-msgsize were not applied.
+
+	New address POSIXMQ-WRITE does the same as POSIXMQ-SEND, as counterpart
+	of POSIXMQ-READ.
+
+Building:
+	Disabling certain features during configure could break build process.
+
+	Again fixes a few disable problems.
+
+Porting:
+	Fix for old FreeBSD.
+
+	Fixes for old Debian
+
+	Fixes for old Scientific/RHEL
+
+	Socat failed to build on platforms without flock() function (AIX,
+	Solaris) due to a missing guard.
+
+	Newer Linux distributions do not provide libwrap: do not leave unused
+	variable.
+
+	Newer Linux distributions deprecate usleep, replace it.
+
+	OpenSSL-3 loudly deprecates some functions or macros, replace a first
+	bunch of them.
+
+	Fixes for FreeBSD-15 (DCCP)
+
+	Fix for compiling on Solaris-11
+
+Testing:
+	test.sh produces file results.txt with columns of test numbers, names,
+	and results.
+
+	Fixed a few testing issues.
+
+	Added test script sock5server-echo.sh for SOCKS5-CONNECT and
+	SOCKS5-LISTEN, and appropriate tests.
+	SOCKS5 addresses are no longer experimental.
+	Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4
+
+	Added a developer test that overwrites malloc'ed memory with non-zeros.
+
+	Newer Linux distributions now deprecate usleep; replaced it in test.sh
+
+	UDPLITE4STREAM was trice, changed one of them to UDPLITE6STREAM.
+
+	Catch problems caused by ISPs that filter *.dest-unreach.net records.
+
+Documentation:
+	Removed obsolete CHANGES.ISO-8859-1 file.
+
+	Corrected lots of misspelling and typos.
+	Thanks to Mario de Weerd for reporting these issues.
+
+	Improved README file.
+
+	Better explained benefit of UDP-DATAGRAM address type.
+
 ####################### V 1.8.0.2:
 
 Security:
@@ -70,6 +257,9 @@ Corrections:
 	Print warning about not checking CRLs in OpenSSL only in the first
 	child process.
 
+	Fixed preprocessor directives in macro invocation.
+	Thanks to Mario de Weerd for reporting this issue.
+
 Features:
 	Total inactivity timeout option -T 0 now means 0.0 seconds; up to
 	version 1.8.0.0 it meant no total inactivity timeout.
@@ -237,11 +427,11 @@ Features:
 	no IP version is preferred by build, environment, option, or address
 	type, Socat chooses IPv6 because this might activate both versions (but
 	check option ipv6-v6only).
-	Added option ai-passive to control this flag explicitely.
+	Added option ai-passive to control this flag explicitly.
 
 	New option ai-v4mapped (v4mapped) sets or unsets the AI_V4MAPPED flag
 	of the resolver. For Socat addresses requiring IPv6 addresses, this
-	resolves IPv4 addresses to the approriate IPv6 address [::ffff:*:*].
+	resolves IPv4 addresses to the appropriate IPv6 address [::ffff:*:*].
 
 	DNS resolver Options (res-*) are now set for the complete open phase of
 	the address, not per getaddrinfo() invocation.
@@ -434,14 +624,14 @@ Porting:
 	Some corrections for better 32bit systems support.
 
 Testing:
-	Removed obselete parts from test.sh
+	Removed obsolete parts from test.sh
 
 	test.sh: Introduced function checkcond
 
 	Renamed test.sh option -foreign to -internet
 
 Documentation:
-	Removed obselete file doc/xio.help
+	Removed obsolete file doc/xio.help
 
 	Added doc for option ipv6-join-group (ipv6-add-membership)
 	Thanks to Martin Buck for sending the patch.
@@ -454,7 +644,7 @@ Documentation:
 
 Corrections:
 	On connect() failure and in some other situations Socat tries to get
-	detailled information about the error with recvmsg(). Error return of
+	detailed information about the error with recvmsg(). Error return of
 	this function is now logged as Info instead of Warn.
 
 	Tests of the correction of the "IP_ADD_SOURCE_MEMBERSHIP but not struct
@@ -498,7 +688,7 @@ Corrections:
 	Thanks to Gordon W.Ross for reporting and fixing this issue.
 	Test: RESTORE_TTY
 
-	The OpenSSL client SNI parameter, when not explicitely specified, is
+	The OpenSSL client SNI parameter, when not explicitly specified, is
 	derived from option commonname or rom target server name. This is not
 	useful with IP addresses, which Socat now checks and avoids.
 
@@ -529,7 +719,7 @@ Coding:
 
 	fcntl() trace prints flags now in hexadecimal.
 
-	Stream dump options -r and -R now open their pathes with CLOEXEC to
+	Stream dump options -r and -R now open their paths with CLOEXEC to
 	prevent leaking into sub processes.
 	Test: EXEC_SNIFF
 
@@ -828,7 +1018,7 @@ Corrections:
 	Print a message when readbytes option causes EOF
 
 	The ip-recverr option had no effect. Corrected and improved its
-	handling of ancilliary messages, so it is able to analyze ICMP error
+	handling of ancillary messages, so it is able to analyze ICMP error
 	packets (Linux only?)
 
 	Setgui(), Setuid() calls in xio-progcall.c were useless.
@@ -862,11 +1052,11 @@ Corrections:
 
 	Under certain conditions OpenSSL stream connections, in particular bulk
 	data transfer in unidirectional mode, failed during transfer or near
-	its with Connection reset by peer on receiver side.
+	its end with Connection reset by peer on receiver side.
 	This happened with Socat versions 1.7.3.3 to 1.7.4.0. Reasons were
 	lazy SSL shutdown handling on the sender side in combination with
 	SSL_MODE_AUTO_RETRY turned off.
-	Fix: After SSH_shutdown but before socket shutdown call SSL_read()
+	Fix: After SSL_shutdown() but before socket shutdown call SSL_read()
 	Test: OPENSSL_STREAM_TO_SERVER
 	Fixes Red Hat issue 1870279.
 
@@ -966,7 +1156,7 @@ Porting:
 	ai_protocol=0 and try again
 	Test: SCTP_SERVICENAME
 
-	Per file filesystem options were still named ext2-* and depended on
+	Per file filesystem options were still named ext2-* and dependent on
 	<linux/ext2_fs.h>. Now they are called fs-* and depend on <linux/fs.h>.
 	These fs-* options are also available on old systems with ext2_fs.h
 
@@ -979,14 +1169,14 @@ Porting:
 	SSL_library_init.
 
 	With OPENSSL_API_COMPAT=0x10000000L the files openssl/dh.h, openssl/bn.h
-	must explicitely be included.
+	must explicitly be included.
 	Thanks to Rosen Penev for reporting and sending a patch.
 
 Testing:
 	test.sh now produces a list of tests that could not be performed for
 	any reason. This helps to analyse these cases.
 
-	OpenSSL s_server appearently started to neglect TCPs half close feature.
+	OpenSSL s_server apparently started to neglect TCPs half close feature.
 	Test OPENSSL_TCP4 has been changed to tolerate this.
 
 	OpenSSL changed its behaviour when connection is rejected. Tests
@@ -1180,7 +1370,7 @@ Corrections:
 Porting:
 	OpenSSL functions TLS1_client_method() and similar are 
 	deprecated. Socat now uses recommended TLS_client_method(). The old
-	functions and dependend option openssl-method can still be
+	functions and dependent option openssl-method can still be
 	used when configuring socat with --enable-openssl-method
 
 	Shell scripts in socat distribution are now headed with:
@@ -1222,7 +1412,7 @@ Testing:
 	More corrections to test.sh:
 	Language settings could still influence test results
 	netstat was still required
-	Suppress usleep deprecated messag
+	Suppress usleep deprecated message
 	Force use of IPv4 with some certificates
 	Set timeout for UDPxMAXCHILDREN tests
 
@@ -1375,7 +1565,7 @@ testing:
 
 docu:
 	Corrected source of socat man page to correctly show man references
-	like socket(2); removed obseolete entries from See Also
+	like socket(2); removed obsolete entries from See Also
 
 	Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT
 	that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL
@@ -1410,6 +1600,7 @@ security:
 
 	Socat security advisory 7
 	MSVR-1499
+	CVE-2016-2217
 	In the OpenSSL address implementation the hard coded 1024 bit DH p
 	parameter was not prime. The effective cryptographic strength of a key
 	exchange using these parameters was weaker than the one one could get by
@@ -1417,7 +1608,7 @@ security:
 	parameters were chosen, the existence of a trapdoor that makes possible
 	for an eavesdropper to recover the shared secret from a key exchange
 	that uses them cannot be ruled out.
-	Futhermore, 1024bit is not considered sufficiently secure.
+	Furthermore, 1024bit is not considered sufficiently secure.
 	Fix: generated a new 2048bit prime.
 	Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability
 	Research (MSVR) for finding and reporting this issue.
@@ -1431,7 +1622,7 @@ security:
 	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
+	applied to make the code async signal safe but still provide detailed
 	logging from signal handlers:
 	Coded function vsnprintf_r() as async signal safe incomplete substitute
 	of libc vsnprintf()
@@ -1519,7 +1710,7 @@ corrections:
 	Issue reported by Hendrik.
 
 	Added option termios-cfmakeraw that calls cfmakeraw() and is preferred
-	over option raw which is now obsolote. On SysV systems this call is
+	over option raw which is now obsolete. On SysV systems this call is
 	simulated by appropriate setting.
 	Thanks to Youfu Zhang for reporting issue with option raw.
 
@@ -1532,7 +1723,7 @@ porting:
 	Thanks to Ross Burton and Danomi Manchego for reporting this issue.
 
 	Debian Bug#764251: Set the build timestamp to a deterministic time:
-	support external BUILD_DATE env var to allow to build reproducable
+	support external BUILD_DATE env var to allow to build reproducible
 	binaries
 
 	Joachim Fenkes provided an new adapted spec file.
@@ -1653,7 +1844,7 @@ porting:
 	autoconf now prefers configure.ac over configure.in
 	Thanks to Michael Vastola for sending a patch.
 
-	type of struct cmsghdr.cmsg is system dependend, determine it with
+	type of struct cmsghdr.cmsg is system dependent, determine it with
 	configure; some more print format corrections
 
 docu:
@@ -1707,7 +1898,7 @@ corrections:
 	socket using address GOPEN. Thanks to Martin Forssen for bug report and
 	patch.
 
-	UDP-LISTEN would alway set SO_REUSEADDR even without fork option and
+	UDP-LISTEN would always set SO_REUSEADDR even without fork option and
 	when user set it to 0. Thanks to Michal Svoboda for reporting this bug.
 
 	UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who
@@ -1940,7 +2131,7 @@ new features:
 
 	added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN,
 	SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow
-	protocol independent socket handling; all parameters are explicitely
+	protocol independent socket handling; all parameters are explicitly
 	specified as numbers or hex data
 
 	added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string,
@@ -2013,7 +2204,7 @@ corrections:
 	this bug). test: EXECSPACES
 
 	in ignoreeof polling mode socat also blocked data transfer in the other
-	direction during the 1s wait intervalls (thanks to Jorgen Cederlof for
+	direction during the 1s wait intervals (thanks to Jorgen Cederlof for
 	reporting this bug)
 
 	corrected alphabetical order of options (proxy-auth)
@@ -2439,7 +2630,7 @@ corrections:
 
 	check for /proc at runtime, even if configure found it
 
-	src.rpm accidently supported SuSE instead of RedHat
+	src.rpm accidentally supported SuSE instead of RedHat
 
 ####################### V 1.3.2.0:
 
@@ -2715,7 +2906,7 @@ solved problems and bugs:
 	SOLVED: now uses common TCP service resolver
 
 	PROBLEM: with PIPE, wrong FDs were shown for data transfer loop
-	SOLVED: retrieval of FDs now pays respect to PIPE pecularities
+	SOLVED: retrieval of FDs now pays respect to PIPE peculiarities
 
 	PROBLEM: using address EXEC against an address with IGNOREEOF, socat
 		never terminated
diff --git a/CHANGES.ISO-8859-1 b/CHANGES.ISO-8859-1
deleted file mode 100644
index 9509e36..0000000
--- a/CHANGES.ISO-8859-1
+++ /dev/null
@@ -1,1800 +0,0 @@
-
-####################### V 1.7.3.4:
-
-Corrections:
-	Header of xiotermios_speed() declared parameter unsigned int instead of
-	speed_t, thus compiling failed on MacOS
-	Thanks to Joe Strout and others for reporting this bug.
-	Thanks to Andrew Childs and others for sending a patch.
-
-	Under certain circumstances, termios options of the first address were
-	applied to the second address, resulting in error
-	"Inappropriate ioctl for device" 
-	This affected version 1.7.3.3 only.
-	Test: TERMIOS_PH_ALL
-	Thanks to Ivan J. for reporting this issue.
-
-	Socat failed to compile when no poll() system call was found by
-	configure.
-	Thanks to Jason White for sending a patch.
-
-	Due to use of SSL_CTX_clear_mode() Socat failed to compile on old
-	systems with, e.g., OpenSSL-0.9.8. Thanks to Simon Matter and Moritz B.
-	for reporting this problem and sending initial patches.
-
-	getaddrinfo() in IP4-SENDTO and IP6-SENDTO addresses failed with
-	"ai_socktype not supported" when protocol 6 was addressed.
-	The fix removes the possibility to use service names with SCTP.
-	Test: IP_SENDTO_6
-	Thanks to S�ren for sending an initial patch.
-
-	Under certain circumstances, Socat printed the "socket ... is at EOF"
-	multiple times.
-	Test: MULTIPLE_EOF
-
-	Newer parts of test.sh used substitutions ${x,,*} or ${x^^*} that are
-	not implemented in older bash versions.
-
-####################### V 1.7.3.3:
-
-Corrections:
-	Makefile.in did not specify dependencies of filan on vsnprintf_r.o
-	and snprinterr.o
-	Added definition of FILAN_OBJS
-	Thanks to Craig Leres, Clayton Shotwell, and Chris Packham for
-	providing patches.
-
-	configure option --enable-msglevel did not work with numbers
-
-	The autoconf mechanism for determining SHIFT_OFFSET did not work when
-	cross compiling.
-	Thanks to Max Freisinger from Gentoo for sending a patch.
-
-	Socat still depended on obsolete gethostbyname() function, thus
-	compiling with MUSL libc failed.
-	Problem reported by Kennedy33.
-
-	The async signal safe diagnostic system used FDs 3 and 4 internally, so
-	use of appropriate fdin or fdout led to failures.
-	Test: DIAG_FDIN
-	Problem reported by Onur Sent�rk.
-
-	The socket based mechanism for passing messages and signal information
-	from signal handler to process could reach and kill the wrong process.
-	Introduces functions diag_sock_pair(), diag_fork()
-	Thanks to Darren Zhao for analysing and reporting this problem.
-
-	Option ipv6-join-group did not work because it was applied in the wrong
-	phase
-	Test: UDP6MULTICAST_UNIDIR
-	Thanks to Angus Gratton for sending a patch.
-
-	Setting ispeed and ospeed failed for some serial devices because the
-	two settings were applied with two different get/set cycles, Thanks to
-	Alexandre Fenyo for providing an initial patch.
-	However, the actual fix is part of a conceptual change of the termios
-	module that aims for applying all changes in a single tcsetaddr call.
-	Fixes FreeBSD Bug 198441
-
-	Termios options TAB0,TAB1,TAB2,TAB3, and XTABS did not have an effect.
-	Thanks to Alan Walters for reporting this bug.
-
-	Substituted cumbersom ISPEED_OFFSET mechanism for cfsetispeed() calls
-
-	With TCP6-LISTEN and the other passive IPv6 addresses the range option
-	just failed: due to a bug in the syntax parser and two more bugs in
-	the xiocheckrange_ip6() function.
-	The syntax has now been changed from "[::1/128]" to "[::1]/128"!
-	Thanks Leah Neukirchen for sending an initial fix.
-
-	For name resolution Socat only checked the first character of the host
-	name to decide if it is an IPv4 address. This was not RFC conform. This
-	fix removes the possibility for use of IPv4 addresses with IPv6, e.g.
-	TCP6:127.0.0.1:80
-	Debian issue 695885
-	Thanks to Nicolas Fournil for reporting this issue.
-
-	Print a useful error message when single character options appear to be
-	merged in Socat invocation
-        Test: SOCCAT_OPT_HINT
-
-	Fixed some docu typos.
-	Thanks to Travis Wellman, Thomas <tjps636>, Dan Kenigsberg,
-	Julian Zinn, and Simon Matter
-
-Porting:
-	OpenSSL functions TLS1_client_method() and similar are 
-	deprecated. Socat now uses recommended TLS_client_method(). The old
-	functions and dependend option openssl-method can still be
-	used when configuring socat with --enable-openssl-method
-
-	Shell scripts in socat distribution are now headed with:
-	#! /usr/bin/env bash
-	to make them better portable to systems without /bin/bash
-	Thanks to Maya Rashish for sending a patch
-
-	RES_AAONLY, RES_PRIMARY are deprecated. You can still enable them with
-	configure option --enable-res-deprecated.
-
-	New versions of OpenSSL preset SSL_MODE_AUTO_RETRY which may hang socat.
-	Solution: clear SSL_MODE_AUTO_RETRY when it is set.
-
-	Renamed configure.in to configure.ac and set an appropriate symlink for
-	older environments.
-	Related Gentoo bug 426262: Warning on configure.in
-	Thanks to Francesco Turco for reporting that warning.
-
-	Fixed new IPv6 range code for platforms without s6_addr32 component.
-
-Testing:
-	test.sh: Show a warning when phase-1 (insecure phase) of a security
-	test fails
-
-	OpenSSL tests failed on actual Linux distributions. Measures:
-	Increased key lengths from 768 to 1024 bits
-	Added test.sh option -C to delete temp certs from prevsious runs
-	Provide DH-parameter in certificate in PEM
-	OpenSSL s_server option -verify 0 must be omitted
-	OpenSSL authentication method aNULL no longer works
-	Failure of cipher aNULL is not a failure
-	Failure of methods SSL3 and SSL23 is desired
-
-	test.sh depended on ifconfig and netstat utilities which are no longer
-	availabie in some distributions. test.sh now checks for and prefers
-	ip and ss.
-	Thanks to Ruediger Meier for reporting this problem.
-
-	More corrections to test.sh:
-	Language settings could still influence test results
-	netstat was still required
-	Suppress usleep deprecated messag
-	Force use of IPv4 with some certificates
-	Set timeout for UDPxMAXCHILDREN tests
-
-Git:
-	Added missing Config/Makefile.DragonFly-2-8-2,
-	Config/config.DragonFly-2-8-2.h
-	Removed testcert.conf (to be generated by test.sh)
-
-Cosmetics:
-	Simplified handling of missing termios defines.
-
-New features:
-	Permit combined -d options as -dd etc.
-
-####################### V 1.7.3.2:
-
-corrections:
-	SIGSEGV and other signals could lead to a 100% CPU loop
-
-	Failing name resolution could lead to SIGSEGV
-	Thanks to Max for reporting this issue.
-
-	Include <stddef.h> for ptrdiff_t
-	Thanks to Jeroen Roovers for reporting this issue.
-
-	Building with --disable-sycls failed due to missing sslcls.h defines
-
-	Socat hung when configured with --disable-sycls.
-
-	Some minor corrections with includes etc.
-
-	Option so-reuseport did not work. Thanks to Some Raghavendra Prabhu
-	for sending a patch.
-
-	Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout
-	incorrectly assigned
-	Test: EXEC_NOFORK_UNIDIR
-	Thanks to David Reiss for reporting this problem.
-
-	Socat exited with status 0 even when a program invoked with SYSTEM or
-	EXEC failed.
-	Tests: SYSTEM_RC EXEC_RC
-	Issue reported by Felix Winkelmann.
-
-	AddressSanitizer reported a few buffer overflows (false positives).
-	Nevertheless fixed Socat source.
-	Issue reported by Hanno B�ck.
-
-	Socat did not use option ipv6-join-group.
-	Test: USE_IPV6_JOIN_GROUP
-	Thanks to Linus L�ssing for sending a patch.
-
-	UDP-LISTEN did not honor the max-children option.
-	Test: UDP4MAXCHILDREN UDP6MAXCHILDREN
-	Thanks to Leander Berwers for reporting this issue.
-
-	Options so-rcvtimeo and so-sndtimeo do not work with poll()/select()
-	and therefore were useless.
-	Thanks to Steve Borenstein for reporting this issue.
-
-	Option dhparam was documented as dhparams. Added the alias name
-	dhparams to fix this.
-	Thanks to Alexander Neumann for sending a patch.
-
-	Options shut-down and shut-close did not work.
-	Thanks to Stefan Schimanski for providing a patch.
-
-	There was a bug in printing readline log message caused by a misleading
-	indentation.
-	Thanks to Paul Wouters for reporting.
-
-	The internal vsnprintf_r function looped or crashed on size parameter
-	with hexadecimal output.
-
-	Ignore exit code of child process when it was killed by master due to
-	EOF
-
-	Corrected byte order on read of IPV6_TCLASS value from ancillary
-	message
-
-	Fixed type of the bool element in options. This had bug caused failures
-	e.g. of ignoreeof on big-endian systems when bool was not based on int.
-
-	On systems with predefined bool type whose size differs from int some
-	IPv6 and TCP options (per setsockopt()) failed.
-
-	Length of integral data in ancillary messages varies (TOS: 1 byte,
-	TTL: 4 bytes), the old implementation failed for TTL on big-endian
-	hosts.
-
-	Fixed an issue in options processing: TUN and DNS flags had failed on
-	big-endian systems and the NO- forms had probable never worked.
-
-porting:
-	Type conflict between int and sig_atomic_t between declaration and
-	definition of diag_immediate_type and diag_immediate_exit broke
-	compilation on FreeBSD 10.1 with clang. Thanks to Emanuel Haupt for
-	reporting this bug.
-
-	Socat failed to compile on platforms with OpenSSL without
-	DTLSv1_client_method or DTLSv1_server_method.
-	Thanks to Simon Matter for sending a patch.
-
-	NuttX OS headers do not provide struct ip, thus socat did not compile.
-	Made struct ip subject to configure.
-	Thanks to SP for reporting this issue.
-
-	Socat failed to compile with OpenSSL version 1.0.2d where
-	SSLv3_server_method and SSLv3_client_method are no longer defined.
-	Thanks to Mischa ter Smitten for reporting this issue and providing
-	a patch.
-
-	configure checked for OpenSSL EC_KEY assuming it is a define but it
-	is a type, thus OpenSSL ECDHE ciphers failed even on Linux.
-	Thanks to Andrey Arapov for reporting this bug.
-
-	Changes to make socat compile with OpenSSL 1.1. 
-	Thanks to Sebastian Andrzej Siewior e.a. from the Debian team for
-	providing the base patch.
-	Debian Bug#828550
-
-	Make Socat compatible with BoringSSL.
-	Thanks to Matt Braithwaite for providing a patch.
-
-	OpenSSL: Use RAND_status to determine PRNG state
-	Thanks to Adam Langley for providing a patch
-
-	AIX-7 uses an extended O_ACCMODE that does not fit socat's internal
-	requirements. Thanks to Garrick Trowsdale for providing a patch
-
-	LibreSSL support: check for OPENSSL_NO_COMP
-	Thanks to Bernard Spil for providing a patch
-
-testing:
-	socks4echo.sh and socks4a-echo.sh hung with new bash with read -n
-
-	test.sh: stderr; option -v (verbose); FDOUT_ERROR description
-
-	improved proxy.sh - it now also takes hostnames
-
-	A few corrections in test.sh
-
-	DTLS1 test hangs on some distributions. Test is now only performed
-	with OpenSSL 1.0.2 or higher.
-
-	More corrections to test.sh that reveal a mistake with IPV6_TCLASS
-
-docu:
-	Corrected source of socat man page to correctly show man references
-	like socket(2); removed obseolete entries from See Also
-
-	Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT
-	that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL
-	are correct).
-	Thanks to Zhigang Wang for reporting this issue.
-
-	Fixed a couple of English spelling and grammar mistakes.
-	Thanks to Jakub Wild for sending the patches.
-
-	NOEXPAND() was not resolved 2 times.
-
-	More minor docu corrections
-
-legal:
-	Added contributors to copyright notices. Suggested by Matt Braithwaite.
-
-####################### V 1.7.3.1:
-
-security:
-	Socat security advisory 8
-	A stack overflow in vulnerability was found that can be triggered when
-	command line arguments (complete address specifications, host names,
-	file names) are longer than 512 bytes.
-	Successful exploitation might allow an attacker to execute arbitrary
-	code with the privileges of the socat process.
-	This vulnerability can only be exploited when an attacker is able to
-	inject data into socat's command line.
-	A vulnerable scenario would be a CGI script that reads data from clients
-	and uses (parts of) this data as hostname for a Socat invocation.
-	Test: NESTEDOVFL
-	Credits to Takumi Akiyama for finding and reporting this issue.
-
-	Socat security advisory 7
-	MSVR-1499
-	In the OpenSSL address implementation the hard coded 1024 bit DH p
-	parameter was not prime. The effective cryptographic strength of a key
-	exchange using these parameters was weaker than the one one could get by
-	using a prime p. Moreover, since there is no indication of how these
-	parameters were chosen, the existence of a trapdoor that makes possible
-	for an eavesdropper to recover the shared secret from a key exchange
-	that uses them cannot be ruled out.
-	Futhermore, 1024bit is not considered sufficiently secure.
-	Fix: generated a new 2048bit prime.
-	Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability
-	Research (MSVR) for finding and reporting this issue.
-
-####################### V 1.7.3.0:
-
-security:
-	Socat security advisory 6
-	CVE-2015-1379: Possible DoS with fork
-	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.
-
-	Red Hat issue 1019975: add TLS host name checks
-	OpenSSL client checks if the server certificates names in
-	extensions/subjectAltName/DNS or in subject/commonName match the name
-	used to connect or the value of the openssl-commonname option.
-	Test: OPENSSL_CN_CLIENT_SECURITY
-
-	OpenSSL server checks if the client certificates names in
-	extensions/subjectAltNames/DNS or subject/commonName match the value of
-	the openssl-commonname option when it is used.
-	Test: OPENSSL_CN_SERVER_SECURITY
-
-	Red Hat issue 1019964: socat now uses the system certificate store with
-	OPENSSL when neither options cafile nor capath are used
-
-	Red Hat issue 1019972: needs to specify OpenSSL cipher suites
-	Default cipherlist is now "HIGH:-NULL:-PSK:-aNULL" instead of empty to
-	prevent downgrade attacks
-
-new features:
-	OpenSSL addresses set couple of environment variables from values in
-	peer certificate, e.g.: 
-	SOCAT_OPENSSL_X509_SUBJECT, SOCAT_OPENSSL_X509_ISSUER,
-	SOCAT_OPENSSL_X509_COMMONNAME, 
-	SOCAT_OPENSSL_X509V3_SUBJECTALTNAME_DNS
-	Tests: ENV_OPENSSL_{CLIENT,SERVER}_X509_*
-
-	Added support for methods TLSv1, TLSv1.1, TLSv1.2, and DTLS1
-	Tests: OPENSSL_METHOD_*
-
-	Enabled OpenSSL server side use of ECDHE ciphers. Feature suggested
-	by Andrey Arapov.
-
-	Added a new option termios-rawer for ptys.
-	Thanks to Christian Vogelgsang for pointing me to this requirement
-
-corrections:
-	Bind with ABSTRACT commands used non-abstract namespace (Linux).
-	Test: ABSTRACT_BIND
-	Thanks to Denis Shatov for reporting this bug.
-
-	Fixed return value of nestlex()
-
-	Option ignoreeof on the right address hung.
-	Test: IGNOREEOF_REV
-	Thanks to Franz Fasching for reporting this bug.
-
-	Address SYSTEM, when terminating, shut down its parent addresses,
-	e.g. an SSL connection which the parent assumed to still be active.
-	Test: SYSTEM_SHUTDOWN
-
-	Passive (listening or receiving) addresses with empty port field bound
-	to a random port instead of terminating with error.
-	Test: TCP4_NOPORT
-
-	configure with some combination of disable options produced config
-	files that failed to compile due to missing IPPROTO_TCP.
-	Thanks to Thierry Fournier for report and patch.
-
-	fixed a few minor bugs with OpenSSL in configure and with messages
-
-	Socat did not work in FIPS mode because 1024 instead of 512 bit DH prime
-	is required. Thanks to Zhigang Wang for reporting and sending a patch.
-
-	Christophe Leroy provided a patch that fixes memory leaks reported by
-	valgrind
-
-	Help for filan -L was bad, is now corrected to:
-	"follow symbolic links instead of showing their properties"
-
-	Address options fdin and fdout were silently ignored when not applicable
-	due to -u or -U option. Now these combinations are caught as errors.
-	Test: FDOUT_ERROR
-	Issue reported by Hendrik.
-
-	Added option termios-cfmakeraw that calls cfmakeraw() and is preferred
-	over option raw which is now obsolote. On SysV systems this call is
-	simulated by appropriate setting.
-	Thanks to Youfu Zhang for reporting issue with option raw.
-
-porting:
-	Socat included <sys/poll.h> instead of POSIX <poll.h>
-	Thanks to John Spencer for reporting this issue.
-
-	Version 1.7.2.4 changed the check for gcc in configure.ac; this
-	broke cross compiling. The particular check gets reverted.
-	Thanks to Ross Burton and Danomi Manchego for reporting this issue.
-
-	Debian Bug#764251: Set the build timestamp to a deterministic time:
-	support external BUILD_DATE env var to allow to build reproducable
-	binaries
-
-	Joachim Fenkes provided an new adapted spec file.
-
-	Type bool and macros Min and Max are defined by socat which led to
-	compile errors when they were already provided by build framework.
-	Thanks to Liyu Liu for providing a patch.
-
-	David Arnstein contributed a patch for NetBSD 5.1 including stdbool.h
-	support and appropriate files in Config/
-
-	Lauri Tirkkonen contributed a patch regarding netinet/if_ether.h
-	on Illumos
-
-	Changes for Openindiana: define _XPG4_2, __EXTENSIONS__,
-	_POSIX_PTHREAD_SEMANTICS; and minor changes
-
-	Red Hat issue 1182005: socat 1.7.2.4 build failure missing
-	linux/errqueue.h
-	Socat failed to compile on on PPC due to new requirements for
-	including <linux/errqueue.h> and a weakness in the conditional code.
-	Thanks to Michel Normand for reporting this issue.
-
-doc:
-	In the man page the PTY example was badly formatted. Thanks to
-	J.F.Sebastian for sending a patch.
-
-	Added missing CVE ids to security issues in CHANGES
-
-testing:
-	Do not distribute testcert.conf with socat source but generate it
-	(and new testcert6.conf) during test.sh run.
-
-####################### V 1.7.2.4:
-
-corrections:
-	LISTEN based addresses applied some address options, e.g. so-keepalive,
-	to the listening file descriptor instead of the connected file
-	descriptor
-	Thanks to Ulises Alonso for reporting this bug
-
-	make failed after configure with non gcc compiler due to missing
-	include. Thanks to Horacio Mijail for reporting this problem
-
-	configure checked for --disable-rawsocket but printed
-	--disable-genericsocket in the help text. Thanks to Ben Gardiner for
-	reporting and patching this bug
-
-	In xioshutdown() a wrong branch was chosen after RECVFROM type addresses.
-	Probably no impact.
-	Thanks to David Binderman for reporting this issue.
-
-	procan could not cleanly format ulimit values longer than 16 decimal
-	digits. Thanks to Frank Dana for providing a patch that increases field
-	width to 24 digits.
-
-	OPENSSL-CONNECT with bind option failed on some systems, eg.FreeBSD, with
-	"Invalid argument"
-	Thanks to Emile den Tex for reporting this bug.
-
-	Changed some variable definitions to make gcc -O2 aliasing checker happy
-	Thanks to Ilya Gordeev for reporting these warnings
-
-	On big endian platforms with type long >32bit the range option applied a
-	bad base address. Thanks to hejia hejia for reporting and fixing this bug.
-
-	Red Hat issue 1022070: missing length check in xiolog_ancillary_socket()
-
-	Red Hat issue 1022063: out-of-range shifts on net mask bits
-
-	Red Hat issue 1022062: strcpy misuse in xiosetsockaddrenv_ip4()
-
-	Red Hat issue 1022048: strncpy hardening: corrected suspicious strncpy()
-	uses
-
-	Red Hat issue 1021958: fixed a bug with faulty buffer/data length
-	calculation in xio-ascii.c:_xiodump()
-
-	Red Hat issue 1021972: fixed a missing NUL termination in return string
-	of sysutils.c:sockaddr_info() for the AF_UNIX case
-
-	fixed some typos and minor issues, including:
-	Red Hat issue 1021967: formatting error in manual page
-
-	UNIX-LISTEN with fork option did not remove the socket file system entry
-	when exiting. Other file system based passive address types had similar
-	issues or failed to apply options umask, user e.a.
-	Thanks to Lorenzo Monti for pointing me to this issue
-
-porting:
-	Red Hat issue 1020203: configure checks fail with some compilers.
-	Use case: clang
-
-	Performed changes for Fedora release 19
-
-	Adapted, improved test.sh script
-
-	Red Hat issue 1021429: getgroupent fails with large number of groups;
-	use getgrouplist() when available instead of sequence of calls to
-	getgrent()
-
-	Red Hat issue 1021948: snprintf API change;
-	Implemented xio_snprintf() function as wrapper that tries to emulate C99
-	behaviour on old glibc systems, and adapted all affected calls
-	appropriately
-
-	Mike Frysinger provided a patch that supports long long for time_t,
-	socklen_t and a few other libc types.
-
-	Artem Mygaiev extended Cedril Priscals Android build script with pty code
-
-	The check for fips.h required stddef.h
-	Thanks to Matt Hilt for reporting this issue and sending a patch
-
-	Check for linux/errqueue.h failed on some systems due to lack of
-	linux/types.h inclusion. Thanks to Michael Vastola for sending a patch.
-
-	autoconf now prefers configure.ac over configure.in
-	Thanks to Michael Vastola for sending a patch.
-
-	type of struct cmsghdr.cmsg is system dependend, determine it with
-	configure; some more print format corrections
-
-docu:
-	libwrap always logs to syslog
-
-	added actual text version of GPLv2
-
-####################### V 1.7.2.3:
-
-security:
-	Socat security advisory 5
-	CVE-2014-0019: socats PROXY-CONNECT address was vulnerable to a buffer
-	overflow with data from command line (see socat-secadv5.txt)
-	Credits to Florian Weimer of the Red Hat Product Security Team
-
-####################### V 1.7.2.2:
-
-security:
-	Socat security advisory 4
-	CVE-2013-3571:
-	after refusing a client connection due to bad source address or source
-	port socat shutdown() the socket but did not close() it, resulting in
-	a file descriptor leak in the listening process, visible with lsof and
-	possibly resulting in EMFILE Too many open files. This issue could be
-	misused for a denial of service attack.
-	Full credits to Catalin Mitrofan for finding and reporting this issue.
-
-####################### V 1.7.2.1:
-
-security:
-	Socat security advisory 3
-	CVE-2012-0219:
-	fixed a possible heap buffer overflow in the readline address. This bug
-	could be exploited when all of the following conditions were met:
-	1) one of the addresses is READLINE without the noprompt and without the
-	prompt options.
-	2) the other (almost arbitrary address) reads malicious data (which is
-	then transferred by socat to READLINE).
-	Workaround: when using the READLINE address apply option prompt or
-	noprompt.
-	Full credits to Johan Thillemann for finding and reporting this issue.
-
-####################### V 1.7.2.0:
-
-corrections:
-	when UNIX-LISTEN was applied to an existing file it failed as expected
-	but removed the file. Thanks to Bjoern Bosselmann for reporting this
-	problem
-
-	fixed a bug where socat might crash when connecting to a unix domain
-	socket using address GOPEN. Thanks to Martin Forssen for bug report and
-	patch.
-
-	UDP-LISTEN would alway set SO_REUSEADDR even without fork option and
-	when user set it to 0. Thanks to Michal Svoboda for reporting this bug.
-
-	UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who
-	pointed me to that bug
-
-	TCP-CONNECT with option nonblock reported successful connect even when
-	it was still pending
-
-	address option ioctl-intp failed with "unimplemented type 26". Thanks
-	to Jeremy W. Sherman for reporting and fixing that bug
-
-	socat option -x did not print packet direction, timestamp etc; thanks
-	to Anthony Sharobaiko for sending a patch
-
-	address PTY does not take any parameters but did not report an error
-	when some were given
-
-	Marcus Meissner provided a patch that fixes invalid output and possible
-	process crash when socat prints info about an unnamed unix domain
-	socket
-
-	Michal Soltys reported the following problem and provided an initial
-	patch: when socat was interrupted, e.g. by SIGSTOP, and resumed during
-	data transfer only parts of the data might have been written.
-
-	Option o-nonblock in combination with large transfer block sizes
-	may result in partial writes and/or EAGAIN errors that were not handled
-	properly but resulted in data loss or process termination.
-
-	Fixed a bug that could freeze socat when during assembly of a log
-	message a signal was handled that also printed a log message. socat
-	development had been aware that localtime() is not thread safe but had
-	only expected broken messages, not corrupted stack (glibc 2.11.1,
-	Ubuntu 10.4)
-
-	an internal store for child pids was susceptible to pid reuse which
-	could lead to sporadic data loss when both fork option and exec address
-	were used. Thanks to Tetsuya Sodo for reporting this problem and
-	sending a patch
-
-	OpenSSL server failed with "no shared cipher" when using cipher aNULL.
-	Fixed by providing temporary DH parameters. Thanks to Philip Rowlands
-	for drawing my attention to this issue.
-
-	UDP-LISTEN slept 1s after accepting a connection. This is not required.
-	Thanks to Peter Valdemar Morch for reporting this issue
-
-	fixed a bug that could lead to error or socat crash after a client
-	connection with option retry had been established
-
-	fixed configure.in bug on net/if.h check that caused IF_NAMESIZE to be
-	undefined
-
-	improved dev_t print format definition
-
-porting:
-	Cedril Priscal ported socat to Android (using Googles cross compiler).
-	The port includes the socat_buildscript_for_android.sh script
-
-	added check for component ipi_spec_dst in struct in_pktinfo so
-	compilation does not fail on Cygwin (thanks to Peter Wagemans for
-	reporting this problem)
-
-	build failed on RHEL6 due to presence of fips.h; configure now checks
-	for fipsld too. Thanks to Andreas Gruenbacher for reporting this
-	problem
-
-	check for netinet6/in6.h only when IPv6 is available and enabled
-
-	don't fail to compile when the following defines are missing:
-	IPV6_PKTINFO IPV6_RTHDR IPV6_DSTOPTS IPV6_HOPOPTS IPV6_HOPLIMIT
-	Thanks to Jerry Jacobs for reporting this problem (Mac OS X Lion 10.7)
-
-	check if define __APPLE_USE_RFC_2292 helps to enable IPV6_* (MacOSX
-	Lion 7.1); thanks to Jerry Jacobs to reporting this problem and
-	proposing a solution
-
-	fixed compiler warnings on Mac OS X 64bit. Thanks to Guy Harris for
-	providing the patch.
-
-	corrections for OpenEmbedded, especially termios SHIFT values and
-	ISPEED/OSPEED. Thanks to John Faith for providing the patch
-
-	minor corrections to docu and test.sh resulting from local compilation
-	on Openmoko SHR
-
-	fixed sa_family_t compile error on DragonFly. Thanks to Tony Young for
-	reporting this issue and sending a patch.
-
-	Ubuntu Oneiric: OpenSSL no longer provides SSLv2 functions; libutil.sh
-	is now bsd/libutil.h; compiler warns on vars that is only written to
-
-new features: 
-	added option max-children that limits the number of concurrent child
-	processes. Thanks to Sam Liddicott for providing the patch.
-
-	Till Maas added support for tun/tap addresses without IP address
- 
-	added an option openssl-compress that allows to disable the compression
-	feature of newer OpenSSL versions. Thanks to Michael Hanselmann for
-	providing this contribution (sponsored by Google Inc.)
-
-docu:
-	minor corrections in docu (thanks to Paggas)
-
-	client process -> child process
-
-####################### V 1.7.1.3:
-
-security:
-	Socat security advisory 2
-	CVE-2010-2799:
-	fixed a stack overflow vulnerability that occurred when command
-	line arguments (whole addresses, host names, file names) were longer
-	than 512 bytes.
-	Note that this could only be exploited when an attacker was able to
-	inject data into socat's command line.
-	Full credits to Felix Gr�bert, Google Security Team, for finding and
-	reporting this issue
-
-####################### V 1.7.1.2:
-
-corrections:
-	user-late and group-late, when applied to a pty, affected the system
-	device /dev/ptmx instead of the pty (thanks to Matthew Cloke for
-	pointing me to this bug)
-
-	socats openssl addresses failed with "nonblocking operation did not
-	complete" when the peer performed a renegotiation. Thanks to Benjamin
-	Delpy for reporting this bug.
-
-	info message during socks connect showed bad port number on little
-	endian systems due to wrong byte order (thanks to Peter M. Galbavy for
-	bug report and patch)
-
-	Debian bug 531078: socat execs children with SIGCHLD ignored; corrected
-	to default. Thanks to Martin Dorey for reporting this bug.
-
-porting:
-	building socat on systems that predefined the CFLAGS environment to
-	contain -Wall failed (esp.RedHat). Thanks to Paul Wouters for reporting
-	this problem and to Simon Matter for providing the patch
-
-	support for Solaris 8 and Sun Studio support (thanks to Sebastian
-	Kayser for providing the patches)
-
-	on some 64bit systems a compiler warning "cast from pointer to integer
-	of different size" was issued on some option definitions
-
-	added struct sockaddr_ll to union sockaddr_union to avoid "strict
-	aliasing" warnings (problem reported by Paul Wouters)
-
-docu:
-	minor corrections in docu
-
-####################### V 1.7.1.1:
-
-corrections:
-	corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might
-	occur under those conditions. Thanks to Toni Mattila for first
-	reporting this problem.
-
-	ftruncate64 cut its argument to 32 bits on systems with 32 bit long type
-
-	socat crashed on systems without setenv() (esp. SunOS up to Solaris 9);
-	thanks to Todd Stansell for reporting this bug
-
-	with unidirectional EXEC and SYSTEM a close() operation was performed
-	on a random number which could result in hanging e.a.
-
-	fixed a compile problem caused by size_t/socklen_t mismatch on 64bit
-	systems
-
-	docu mentioned option so-bindtodev but correct name is so-bindtodevice. 
-	Thanks to Jim Zimmerman for reporting.
-
-docu changes:
-	added environment variables example to doc/socat-multicast.html
-
-####################### V 1.7.1.0:
-
-new features:
-	address options shut-none, shut-down, and shut-close allow to control
-	socat's half close behaviour
-
-	with address option shut-null socat sends an empty packet to the peer
-	to indicate EOF
-
-	option null-eof changes the behaviour of sockets that receive an empty
-	packet to see EOF instead of ignoring it
-
-	introduced option names substuser-early and su-e, currently equivalent
-	to option substuser (thanks to Mike Perry for providing the patch)
-
-corrections:
-	fixed some typos and improved some comments
-
-####################### V 1.7.0.1:
-
-corrections:
-	fixed possible SIGSEGV in listening addresses when a new connection was
-	reset by peer before the socket addresses could be retrieved. Thanks to
-	Mike Perry for sending a patch.
-
-	fixed a bug, introduced with version 1.7.0.0, that let client
-	connections with option connect-timeout fail when the connections
-	succeeded. Thanks to Bruno De Fraine for reporting this bug.
-
-	option end-close "did not apply" to addresses PTY, SOCKET-CONNECT,
-	and most UNIX-* and ABSTRACT-*
-
-	half close of EXEC and SYSTEM addresses did not work for pipes and
-	sometimes socketpair
-
-	help displayed for some option a wrong type
-
-	under some circumstances shutdown was called multiple times for the
-	same fd
-
-####################### V 1.7.0.0:
-
-new features:
-	new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream
-	mode for IPv4 and IPv6; new address options sctp-maxseg and
-	sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brannan
-	for providing an initial patch)
-
-	new address "INTERFACE" for transparent network interface handling
-	(suggested by Stuart Nicholson)
-
-	added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN,
-	SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow
-	protocol independent socket handling; all parameters are explicitely
-	specified as numbers or hex data
-
-	added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string,
-	ioctl-bin for generic ioctl() calls.
-
-	added address options setsockopt-int, setsockopt-bin, and
-	setsockopt-string for generic setsockopt() calls
-
-	option so-type now only affects the socket() and socketpair() calls,
-	not the name resolution. so-type and so-prototype can now be applied to
-	all socket based addresses.
-
-	new address option "escape" allows to break a socat instance even when
-	raw terminal mode prevents ^C etc. (feature suggested by Guido Trotter)
-
-	socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID
-	for use in executed scripts
-
-	socat sets environment variables SOCAT_SOCKADDR, SOCAT_SOCKPORT,
-	SOCAT_PEERADDR, SOCAT_PEERPORT in LISTEN type addresses (feature
-	suggested by Ed Sawicki)
-
-	socat receives all ancillary messages with each received packet on
-	datagram related addresses. The messages are logged in raw form with
-	debug level, and broken down with info level. note: each type of
-	ancillary message must be enabled by appropriate address options. 
-
-	socat provides the contents of ancillary messages received on RECVFROM
-	addresses in appropriate environment variables:
-	SOCAT_TIMESTAMP, SOCAT_IP_DSTADDR, SOCAT_IP_IF, SOCAT_IP_LOCADDR,
-	SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, SOCAT_IPV6_DSTADDR,
-	SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS
-
-	the following address options were added to enable ancillary messages:
-	so-timestamp, ip-pktinfo (not BSD), ip-recvdstaddr (BSD), ip-recverr,
-	ip-recvif (BSD), ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts,
-	ipv6-recverr, ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu,
-	ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass
-
-	new address options ipv6-tclass and ipv6-unicast-hops set the related
-	socket options.
-
-	STREAMS (UNIX System V STREAMS) can be configured with the new address
-	options i-pop-all and i-push (thanks to Michal Rysavy for providing a
-	patch)
-
-corrections:
-	some raw IP and UNIX datagram modes failed on BSD systems
-
-	when UDP-LISTEN continued to listen after packet dropped by, e.g.,
-	range option, the old listen socket would not be closed but a new one
-	created. open sockets could accumulate.
-
-	there was a bug in ip*-recv with bind option: it did not bind, and
-	with the first received packet an error occurred:
-	socket_init(): unknown address family 0
-	test: RAWIP4RECVBIND
-
-	RECVFROM addresses with FORK option hung after processing the first
-	packet. test: UDP4RECVFROM_FORK
-
-	corrected a few mistakes that caused compiler warnings on 64bit hosts
-	(thanks to Jonathan Brannan e.a. for providing a patch)
-
-	EXEC and SYSTEM with stderr injected socat messages into the data
-	stream. test: EXECSTDERRLOG
-
-	when the EXEC address got a string with consecutive spaces it created
-	additional empty arguments (thanks to Olivier Hervieu for reporting
-	this bug). test: EXECSPACES
-
-	in ignoreeof polling mode socat also blocked data transfer in the other
-	direction during the 1s wait intervalls (thanks to Jorgen Cederlof for
-	reporting this bug)
-
-	corrected alphabetical order of options (proxy-auth)
-
-	some minor corrections
-
-	improved test.sh script: more stable timing, corrections for BSD
-
-	replaced the select() calls by poll() to cleanly fix the problems with
-	many file descriptors already open
-
-	socat option -lf did not log to file but to stderr
-
-	socat did not compile on Solaris when configured without termios
-	feature (thanks to Pavan Gadi for reporting this bug)
-
-porting:
-	socat compiles and runs on AIX with gcc (thanks to Andi Mather for his
-	help)
-
-	socat compiles and runs on Cygwin (thanks to Jan Just Keijser for his
-	help)
-
-	socat compiles and runs on HP-UX with gcc (thanks to Michal Rysavy for
-	his help)
-
-	socat compiles and runs on MacOS X (thanks to Camillo Lugaresi for his
-	help)
-
-further changes:
-	filan -s prefixes output with FD number if more than one FD
-
-	Makefile now supports datarootdir (thanks to Camillo Lugaresi for
-	providing the patch)
-
-	cleanup in xio-unix.c
-
-####################### V 1.6.0.1:
-
-new features:
-	new make target "gitclean"
-
-	docu source doc/socat.yo released
-
-corrections:
-	exec:...,pty did not kill child process under some circumstances; fixed
-	by correcting typo in xio-progcall.c (thanks to Ralph Forsythe for
-	reporting this problem) 
-
-	service name resolution failed due to byte order mistake
-	(thanks to James Sainsbury for reporting this problem)
-
-	socat would hang when invoked with many file descriptors already opened
-	fix: replaced FOPEN_MAX with FD_SETSIZE
-	thanks to Daniel Lucq for reporting this problem.
-
-	fixed bugs where sub processes would become zombies because the master
-	process did not catch SIGCHLD. this affected addresses UDP-LISTEN,
-	UDP-CONNECT, TCP-CONNECT, OPENSSL, PROXY, UNIX-CONNECT, UNIX-CLIENT,
-	ABSTRACT-CONNECT, ABSTRACT-CLIENT, SOCKSA, SOCKS4A
-	(thanks to Fernanda G Weiden for reporting this problem)
-
-	fixed a bug where sub processes would become zombies because the master
-	process caught SIGCHLD but did not wait(). this affected addresses
-	UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, ABSTRACT-RECVFROM
-	(thanks to Evan Borgstrom for reporting this problem)
-
-	corrected option handling with STDIO; usecase: cool-write
-
-	configure --disable-pty  also disabled option waitlock
-
-	fixed small bugs on systems with struct ip_mreq without struct ip_mreqn
-	(thanks to Roland Illig for sending a patch)
-
-	corrected name of option intervall to interval (old form still valid
-	for us German speaking guys)
-
-	corrected some print statements and variable names
-
-	make uninstall  did not uninstall procan
-
-	fixed lots of weaknesses in test.sh
-
-	corrected some bugs and typos in doc/socat.yo, EXAMPLES, C comments
-
-further changes:
-	procan -c prints C defines important for socat
-
-	added test OPENSSLEOF for OpenSSL half close
-
-####################### V 1.6.0.0:
-
-new features:
-	new addresses IP-DATAGRAM and UDP-DATAGRAM allow versatile broadcast
-	and multicast modes 
-
-	new option ip-add-membership for control of multicast group membership
-
-	new address TUN for generation of Linux TUN/TAP pseudo network
-	interfaces (suggested by Mat Caughron); associated options tun-device,
-	tun-name, tun-type; iff-up, iff-promisc, iff-noarp, iff-no-pi etc.
-
-	new addresses ABSTRACT-CONNECT, ABSTRACT-LISTEN, ABSTRACT-SENDTO,
-	ABSTRACT-RECV, and ABSTRACT-RECVFROM for abstract UNIX domain addresses
-	on Linux (requested by Zeeshan Ali); option unix-tightsocklen controls
-	socklen parameter on system calls.
-
-	option end-close for control of connection closing allows FD sharing
-	by sub processes
-
-	range option supports form address:mask with IPv4
-
-	changed behaviour of OPENSSL-LISTEN to require and verify client
-	certificate per default
-
-	options f-setlkw-rd, f-setlkw-wr, f-setlk-rd, f-setlk-wr allow finer
-	grained locking on regular files
-
-	uninstall target in Makefile (lack reported by Zeeshan Ali)
-
-corrections:
-	fixed bug where only first tcpwrap option was applied; fixed bug where
-	tcpwrap IPv6 check always failed (thanks to Rudolf Cejka for reporting
-	and fixing this bug) 
-
-	filan (and socat -D) could hang when a socket was involved
-
-	corrected PTYs on HP-UX (and maybe others) using STREAMS (inspired by
-	Roberto Mackun)
-
-	correct bind with udp6-listen (thanks to Jan Horak for reporting this
-	bug)
-
-	corrected filan.c peekbuff[0] which did not compile with Sun Studio Pro
-	(thanks to Leo Zhadanovsky for reporting this problem)
-
-	corrected problem with read data buffered in OpenSSL layer (thanks to
-	Jon Nelson for reporting this bug)
-
-	corrected problem with option readbytes when input stream stayed idle
-	after so many bytes
-
-	fixed a bug where a datagram receiver with option fork could fork two
-	sub processes per packet
-
-further changes:
-	moved documentation to new doc/ subdir
-
-	new documents (kind of mini tutorials) are provided in doc/
-
-####################### V 1.5.0.0:
-
-new features:
-	new datagram modes for udp, rawip, unix domain sockets
-
-	socat option -T specifies inactivity timeout
-
-	rewrote lexical analysis to allow nested socat calls
-
-	addresses tcp, udp, tcp-l, udp-l, and rawip now support IPv4 and IPv6
-
-	socat options -4, -6 and environment variables SOCAT_DEFAULT_LISTEN_IP,
-	SOCAT_PREFERRED_RESOLVE_IP for control of protocol selection
-
-	addresses ssl, ssl-l, socks, proxy now support IPv4 and IPv6
-
-	option protocol-family (pf), esp. for openssl-listen
-
-	range option supports IPv6 - syntax: range=[::1/128]
-
-	option ipv6-v6only (ipv6only)
-
-	new tcp-wrappers options allow-table, deny-table, tcpwrap-etc
-
-	FIPS version of OpenSSL can be integrated - initial patch provided by
-	David Acker. See README.FIPS
-
-	support for resolver options res-debug, aaonly, usevc, primary, igntc,
-	recurse, defnames, stayopen, dnsrch
-
-	options for file attributes on advanced filesystems (ext2, ext3,
-	reiser): secrm, unrm, compr, ext2-sync, immutable, ext2-append, nodump,
-	ext2-noatime, journal-data etc.
-
-	option cool-write controls severeness of write failure (EPIPE,
-	ECONNRESET)
-
-	option o-noatime
-
-	socat option -lh for hostname in log output
-
-	traffic dumping provides packet headers
-
-	configure.in became part of distribution
-
-	socats unpack directory now has full version, e.g. socat-1.5.0.0/
-
-	corrected docu of option verify
-
-corrections:
-	fixed tcpwrappers integration - initial fix provided by Rudolf Cejka
-
-	exec with pipes,stderr produced error
-
-	setuid-early was ignored with many address types
-
-	some minor corrections
-
-####################### V 1.4.3.1:
-
-corrections:
-	PROBLEM: UNIX socket listen accepted only one (or a few) connections.
-	FIX: do not remove listening UNIX socket in child process
-
-	PROBLEM: SIGSEGV when TCP part of SSL connect failed
-	FIX: check ssl pointer before calling SSL_shutdown
-
-	In debug mode, show connect client port even when connect fails
-
-####################### V 1.4.3.0:
-
-new features:
-	socat options -L, -W for application level locking
-
-	options "lockfile", "waitlock" for address level locking
-	(Stefan Luethje)
-
-	option "readbytes" limits read length (Adam Osuchowski)
-
-	option "retry" for unix-connect, unix-listen, tcp6-listen (Dale Dude)
-
-	pty symlink, unix listen socket, and named pipe are per default removed
-	after use; option unlink-close overrides this new behaviour and also
-	controls removal of other socat generated files (Stefan Luethje)
-
-corrections:
-	option "retry" did not work with tcp-listen
-
-	EPIPE condition could result in a 100% CPU loop
-
-further changes:
-	support systems without SHUT_RD etc.
-	handle more size_t types
-	try to find makedepend options with gcc 3 (richard/OpenMacNews)
-
-####################### V 1.4.2.0:
-
-new features:
-	option "connect-timeout" limits wait time for connect operations
-	(requested by Giulio Orsero)
-
-	option "dhparam" for explicit Diffie-Hellman parameter file
-
-corrections:
-	support for OpenSSL DSA certificates (Miika Komu)
-
-	create install directories before copying files (Miika Komu)
-
-	when exiting on signal, return status 128+signum instead of 1
-
-	on EPIPE and ECONNRESET, only issue a warning (Santiago Garcia
-	Mantinan)
-
-	-lu could cause a core dump on long messages
-
-further changes:
-	modifications to simplify using socats features in applications
-
-####################### V 1.4.1.0:
-
-new features:
-	option "wait-slave" blocks open of pty master side until a client
-	connects, "pty-intervall" controls polling
-
-	option -h as synonym to -? for help (contributed by Christian
-	Lademann)
-
-	filan prints formatted time stamps and rdev (disable with -r)
-
-	redirect filan's output, so stdout is not affected (contributed by
-	Luigi Iotti) 
-
-	filan option -L to follow symbolic links
-
-	filan shows termios control characters
-
-corrections:
-	proxy address no longer performs unsolicited retries
-
-	filan -f no longer needs read permission to analyze a file (but still
-	needs access permission to directory, of course)
-
-porting:
-	Option dsusp
-	FreeBSD options noopt, nopush, md5sig
-	OpenBSD options sack-disable, signature-enable
-	HP-UX, Solaris options abort-threshold, conn-abort-threshold
-	HP-UX options b900, b3600, b7200
-	Tru64/OSF1 options keepinit, paws, sackena, tsoptena
-
-further corrections:
-	address pty now uses ptmx as default if openpty is also available
-
-####################### V 1.4.0.3:
-
-security:
-	Socat security advisory 1
-	CVE-2004-1484:
-	fix to a syslog() based format string vulnerability that can lead to
-	remote code execution. See advisory socat-adv-1.txt
-
-####################### V 1.4.0.2:
-
-corrections:
-	exec'd write-only addresses get a chance to flush before being killed
-
-	error handler: print notice on error-exit
-
-	filan printed wrong file type information
-
-####################### V 1.4.0.1:
-
-corrections:
-	socks4a constructed invalid header. Problem found, reported, and fixed
-	by Thomas Themel, by Peter Palfrader, and by rik
-
-	with nofork, don't forget to apply some process related options
-	(chroot, setsid, setpgid, ...)
-
-####################### V 1.4.0.0:
-
-new features:
-	simple openssl server (ssl-l), experimental openssl trust
-
-	new options "cafile", "capath", "key", "cert", "egd", and "pseudo" for
-	openssl
-
-	new options "retry", "forever", and "intervall"
-
-	option "fork" for address TCP improves `gender changer�
-
-	options "sigint", "sigquit", and "sighup" control passing of signals to
-	sub process (thanks to David Shea who contributed to this issue)
-
-	readline takes respect to the prompt issued by the peer address
-
-	options "prompt" and "noprompt" allow to override readline's new
-	default behaviour
-
-	readline supports invisible password with option "noecho"
-
-	socat option -lp allows to set hostname in log output
-
-	socat option -lu turns on microsecond resolution in log output
-
-
-corrections:
-	before reading available data, check if writing on other channel is
-	possible
-
-	tcp6, udp6: support hostname specification (not only IP address), and
-	map IP4 names to IP6 addresses
-
-	openssl client checks server certificate per default
-
-	support unidirectional communication with exec/system subprocess
-
-	try to restore original terminal settings when terminating
-
-	test.sh uses tmp dir /tmp/$USER/$$ instead of /tmp/$$ 
-
-	socks4 failed on platforms where long does not have 32 bits
-	(thanks to Peter Palfrader and Thomas Seyrat)
-
-	hstrerror substitute wrote wrong messages (HP-UX, Solaris)
-
-	proxy error message was truncated when answer contained multiple spaces
-
-
-porting:
-	compiles with AIX xlc, HP-UX cc, Tru64 cc (but might not link)
-
-####################### V 1.3.2.2:
-
-corrections:
-	PROXY CONNECT failed when the status reply from the proxy server
-	contained more than one consecutive spaces. Problem reported by
-	Alexandre Bezroutchko
-
-	do not SIGSEGV when proxy address fails to resolve server name
-
-	udp-listen failed on systems where AF_INET != SOCK_DGRAM (e.g. SunOS).
-	Problem reported by Christoph Schittel
-
-	test.sh only tests available features
-
-	added missing IP and TCP options in filan analyzer
-
-	do not apply stdio address options to both directions when in 
-	unidirectional mode
-
-	on systems lacking /dev/*random and egd, provide (weak) entropy from
-	libc random()
-
-
-porting:
-	changes for HP-UX (VREPRINT, h_NETDB_INTERNAL)
-
-	compiles on True64, FreeBSD (again), NetBSD, OpenBSD
-
-	support for  long long  as  st_ino type (Cygwin 1.5)
-
-	compile on systems where pty can not be featured
-
-####################### V 1.3.2.1:
-
-corrections:
-	"final" solution for the ENOCHLD problem
-
-	corrected "make strip"
-
-	default gcc debug/opt is "-O" again
-
-	check for /proc at runtime, even if configure found it
-
-	src.rpm accidently supported SuSE instead of RedHat
-
-####################### V 1.3.2.0:
-
-new features:
-	option "nofork" connects an exec'd script or program directly
-	to the file descriptors of the other address, circumventing the socat
-	transfer engine
-
-	support for files >2GB, using ftruncate64(), lseek64(), stat64()
-
-	filan has new "simple" output style (filan -s)
-
-
-porting:
-	options "binary" and "text" for controlling line termination on Cygwin
-	file system access (hint from Yang Wu-Zhou)
-
-	fix by Yang Wu-Zhou for the Cygwin "No Children" problem
-
-	improved support for OSR: _SVID3; no IS_SOCK, no F_GETOWN (thanks to
-	John DuBois)
-
-	minor corrections to avoid warnings with gcc 3
-
-
-further corrections and minor improvements:
-	configure script is generated with autoconf 2.57 (no longer 2.52)
-
-	configure passes CFLAGS to Makefile
-
-	option -??? for complete list of address options and their short forms
-
-	program name in syslog messages is derived from argv[0]
-
-	SIGHUP now prints notice instead of error
-
-	EIO during read of pty now gives Notice instead of Error, and
-	triggers EOF
-
-	use of hstrerror() for printing resolver error messages
-
-	setgrent() got required endgrent()
-
-####################### V 1.3.1.0:
-
-new features:
-	integration of Wietse Venema's tcpwrapper library (libwrap)
-
-	with "proxy" address, option "resolve" controls if hostname or IP
-	address is sent in request
-
-	option "lowport" establishes limited authorization for TCP and UDP
-	connections 
-
-	improvement of .spec file for RPM creation (thanks to Gerd v. Egidy)
-	An accompanying change in the numbering scheme results in an 
-	incompatibility with earlier socat RPMs!
-
-
-solved problems and bugs:
-	PROBLEM: socat daemon terminated when the address of a connecting
-	client did not match range option value instead of continue listening
-	SOLVED: in this case, print warning instead of error to keep daemon
-	active 
-
-	PROBLEM: tcp-listen with fork sometimes left excessive number of zombie
-	processes
-	SOLVED: dont assume that each exiting child process generates SIGCHLD
-
-	when converting CRNL to CR, socat converted to NL
-
-
-further corrections:
-	configure script now disables features that depend on missing files
-	making it more robust in "unsupported" environments
-
-	server.pem permissions corrected to 600
-
-	"make install" now does not strip; use "make strip; make install"
-	if you like strip (suggested by Peter Bray)
-
-####################### V 1.3.0.1:
-
-solved problems and bugs:
-	PROBLEM: OPENSSL did not apply tcp, ip, and socket options
-	SOLVED: OPENSSL now correctly handles the options list
-
-	PROBLEM: CRNL to NL and CRNL to CR conversions failed when CRNL crossed
-	block boundary
-	SOLVED: these conversions now simply strip all CR's or NL's from input
-	stream 
-
-
-porting:
-	SunOS ptys now work on x86, too (thanks to Peter Bray)
-
-	configure looks for freeware libs in /pkgs/lib/ (thanks to Peter Bray)
-
-
-further corrections:
-	added WITH_PROXY value to -V output
-
-	added compile dependencies of WITH_PTY and WITH_PROXY
-
-	-?? did not print option group of proxy options
-
-	corrected syntax for bind option in docu
-
-	corrected an issue with stdio in unidirectional mode
-
-	options socksport and proxyport support service names
-
-	ftp.sh script supports proxy address
-
-	man page no longer installed with execute permissions (thanks to Peter
-	Bray) 
-
-	fixed a malloc call bug that could cause SIGSEGV or false "out of
-	memory" errors on EXEC and SYSTEM, depending on program name length and
-	libc.
-
-####################### V 1.3.0.0:
-
-new features:
-	proxy connect with optional proxy authentication
-
-	combined hex and text dump mode, credits to Gregory Margo
-
-	address pty applies options user, group, and perm to device
-
-
-solved problems and bugs:
-	PROBLEM: option reuseport was not applied (BSD, AIX)
-	SOLVED:	option reuseport now in phase PASTSOCKET instead of PREBIND,
-		credits to Jean-Baptiste Marchand
-
-	PROBLEM: ignoreeof with stdio was ignored
-	SOLVED: ignoreeof now works correctly with address stdio
-
-	PROBLEM: ftp.sh did not use user supplied password
-	SOLVED: ftp.sh now correctly passes password from command line
-
-	PROBLEM: server.pem had expired
-	SOLVED: new server.pem valid for ten years
-
-	PROBLEM: socks notice printed wrong port on some platforms
-	SOLVED: socks now uses correct byte-order for port number in notice
-
-
-further corrections:
-	option name o_trunc corrected to o-trunc
-
-	combined use of -u and -U is now detected and prevented
-
-	made message system a little more robust against format string attacks
-
-
-####################### V 1.2.0.0:
-
-new features:
-	address pty for putting socat behind a new pseudo terminal that may
-	fake a serial line, modem etc.
-
-	experimental openssl integration
-	(it does not provide any trust between the peers because is does not
-	 check certificates!)
-
-	options flock-ex, flock-ex-nb, flock-sh, flock-sh-nb to control all
-	locking mechanism provided by flock()
-
-	options setsid and setpgid now available with all address types
-
-	option ctty (controlling terminal) now available for all TERMIOS
-	addresses 
-
-	option truncate (a hybrid of open(.., O_TRUNC) and ftruncate()) is
-	replaced by options o-trunc and ftruncate=offset
-
-	option sourceport now available with TCP and UDP listen addresses to
-	restrict incoming client connections
-
-	unidirectional mode right-to-left (-U)
-
-
-solved problems and bugs:
-	PROBLEM: addresses without required parameters but an option containing
-		a '/' were incorrectly interpreted as implicit GOPEN address
-	SOLVED: if an address does not have ':' separator but contains '/',
-		check if the slash is before the first ',' before assuming
-		implicit GOPEN.
-
-
-porting:
-	ptys under SunOS work now due to use of stream options
-
-
-further corrections:
-	with -d -d -d -d -D, don't print debug info during file analysis
-
-
-####################### V 1.1.0.1:
-
-new features:
-	.spec file for RPM generation
-
-
-solved problems and bugs:
-	PROBLEM: GOPEN on socket did not apply option unlink-late
-	SOLUTION: GOPEN for socket now applies group NAMED, phase PASTOPEN
-		options 
-
-	PROBLEM: with unidirectional mode, an unnecessary close timeout was
-		applied
-	SOLUTION: in unidirectional mode, terminate without wait time
-
-	PROBLEM: using GOPEN on a unix domain socket failed for datagram
-		sockets
-	SOLUTION: when connect() fails with EPROTOTYPE, use a datagram socket
-
-
-further corrections:
-
-	open() flag options had names starting with "o_", now corrected to "o-"
-
-	in docu, *-listen addresses were called *_listen
-
-	address unix now called unix-connect because it does not handle unix
-	datagram sockets
-
-	in test.sh, apply global command line options with all tests
-
-
-####################### V 1.1.0.0:
-
-new features:
-	regular man page and html doc - thanks to kromJx for prototype
-
-	new address type "readline", utilizing GNU readline and history libs
-
-	address option "history-file" for readline
-
-	new option "dash" to "exec" address that allows to start login shells
-
-	syslog facility can be set per command line option
-
-	new address option "tcp-quickack", found in Linux 2.4
-
-	option -g prevents option group checking
-
-	filan and procan can print usage
-
-	procan prints rlimit infos
-
-
-solved problems and bugs:
-	PROBLEM: raw IP socket SIGSEGV'ed when it had been shut down.
-	SOLVED: set eof flag of channel on shutdown.
-
-	PROBLEM: if channel 2 uses a single non-socket FD in bidirectional mode
-		and has data available while channel 1 reaches EOF, the data is
-		lost. 
-	SOLVED: during one loop run, first handle all data transfers and
-		_afterwards_ handle EOF. 
-
-	PROBLEM: despite to option NONBLOCK, the connect() call blocked
-	SOLVED: option NONBLOCK is now applied in phase FD instead of LATE
-
-	PROBLEM: UNLINK options issued error when file did not exist,
-		terminating socat
-	SOLVED: failure of unlink() is only warning if errno==ENOENT
-
-	PROBLEM: TCP6-LISTEN required numeric port specification
-	SOLVED: now uses common TCP service resolver
-
-	PROBLEM: with PIPE, wrong FDs were shown for data transfer loop
-	SOLVED: retrieval of FDs now pays respect to PIPE pecularities
-
-	PROBLEM: using address EXEC against an address with IGNOREEOF, socat
-		never terminated
-	SOLVED: corrected EOF handling of sigchld
-
-
-porting:
-	MacOS and old AIX versions now have pty
-
-	flock() now available on Linux (configure check was wrong)
-
-	named pipe were generated using mknod(), which requires root under BSD
-	now they are generated using mkfifo
-
-
-further corrections:
-	lots of address options that were "forgotten" at runtime are now
-	available 
-
-	option BINDTODEVICE now also called SO-BINDTODEVICE, IF
-
-	"make install" now installs binaries with ownership 0:0
-
-
-####################### V 1.0.4.2:
-
-solved problems and bugs:
-	PROBLEM: EOF of one stream caused close of other stream, giving it no
-	chance to go down regularly
-	SOLVED: EOF of one stream now causes shutdown of write part of other
-	stream
-
-	PROBLEM: sending mail via socks address to qmail showed that crlf
-	option does not work
-	SOLVED: socks address applies PH_LATE options
-
-	PROBLEM: in debug mode, no info about socat and platform was issued
-	SOLVED: print socat version and uname output in debug mode
-
-	PROBLEM: invoking socat with -t and no following parameters caused
-	SIGSEGV
-	SOLVED: -t and -b now check next argv entry
-
-	PROBLEM: when opening of logfile (-lf) failed, no error was reported
-	and no further messages were printed
-	SOLVED: check result of fopen and print error message if it failed
-
-new features:
-	address type UDP-LISTEN now supports option fork: it internally applies
-	socket option SO_REUSEADDR so a new UDP socket can bind to port after
-	`accepting� a connection (child processes might live forever though)
-	(suggestion from Damjan Lango)
-
-
-####################### V 1.0.4.1:
-
-solved problems and bugs:
-	PROB: assert in libc caused an endless recursion
-	SOLVED: no longer catch SIGABRT
-
-	PROB: socat printed wrong verbose prefix for "right to left" packets
-	SOLVED: new parameter for xiotransfer() passes correct prefix
-
-new features:
-	in debug mode, socat prints its command line arguments
-	in verbose mode, escape special characters and replace unprintables
-		with '.'. Patch from Adrian Thurston.
-
-
-####################### V 1.0.4.0:
-
-solved problems and bugs:
-	Debug output for lstat and fstat said "stat"
-
-further corrections:
-	FreeBSD now includes libutil.h
-
-new features:
-	option setsid with exec/pty
-	option setpgid with exec/pty
-	option ctty with exec/pty
-	TCP V6 connect test
-	gettimeofday in sycls.c (no use yet)
-
-porting:
-	before Gethostbyname, invoke inet_aton for MacOSX
-
-
-####################### V 1.0.3.0:
-
-solved problems and bugs:
-
-	PROB: test 9 of test.sh (echo via file) failed on some platforms,
-	socat exited without error message
-	SOLVED: _xioopen_named_early(): preset statbuf.st_mode with 0
-
-	PROB: test 17 hung forever
-	REASON: child death before select loop did not result in EOF
-	SOLVED: check of existence of children before starting select loop
-
-	PROB: test 17 failed
-	REASON: child dead triggered EOF before last data was read
-	SOLVED: after child death, read last data before setting EOF
-
-	PROB: filan showed that exec processes incorrectly had fd3 open
-	REASON: inherited open fd3 from main process
-	SOLVED: set CLOEXEC flag on pty fd in main process
-
-	PROB: help printed "undef" instead of group "FORK"
-	SOLVED: added "FORK" to group name array
-
-	PROB: fatal messages did not include severity classifier
-	SOLVED: added "F" to severity classifier array 
-
-	PROB: IP6 addresses where printed incorrectly
-	SOLVED: removed type casts to unsigned short *
-
-further corrections:
-	socat catches illegal -l modes
-	corrected error message on setsockopt(linger)
-	option tabdly is of type uint
-	correction for UDP over IP6
-	more cpp conditionals, esp. for IP6 situations
-	better handling of group NAMED options with listening UNIX sockets
-	applyopts2 now includes last given phase
-	corrected option group handling for most address types
-	introduce dropping of unappliable options (dropopts, dropopts2)
-	gopen now accepts socket and unix-socket options
-	exec and system now accept all socket and termios options
-	child process for exec and system addresses with option pty
-	improved descriptions and options for EXAMPLES
-	printf format for file mode changed to "0%03o" with length spec.
-	added va_end() in branch of msg()
-	changed phase of lock options from PASTOPEN to FD
-	support up to four early dying processes
-
-structural changes:
-	xiosysincludes now includes sysincludes.h for non xio files
-
-new features:
-	option umask
-	CHANGES file
-	TYPE_DOUBLE, u_double
-	OFUNC_OFFSET
-	added getsid(), setsid(), send() to sycls
-	procan prints sid (session id)
-	mail.sh gets -f (from) option
-	new EXAMPLEs for file creation
-	gatherinfo.sh now tells about failures
-	test.sh can check for much more address/option combinations
-
-porting:
-	ispeed, ospeed for termios on FreeBSD
-	getpgid() conditional for MacOS 10
-	added ranlib in Makefile.in for MacOS 10
-	disable pty option if no pty mechanism is available (MacOS 10)
-	now compiles and runs on MacOS 10 (still some tests fail)
-	setgroups() conditional for cygwin
-	sighandler_t defined conditionally
-	use gcc option -D_GNU_SOURCE
diff --git a/EXAMPLES b/EXAMPLES
index 51b10ff..9ace4c4 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -67,7 +67,7 @@ $ socat \
 	TCP-LISTEN:8000,crlf \
 	SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat"
 
-// A less primitive HTTP echo server that sends back not only the reqest but
+// A less primitive HTTP echo server that sends back not only the request but
 // also server and client address and port. Might have portability issues with
 // echo
 $ socat -T 1 -d -d \
@@ -131,7 +131,7 @@ $ socat \
 ///////////////////////////////////////////////////////////////////////////////
 // Intrusion testing
 
-// Found an XWindow Server behind IP filters with FTP data hole? (you are
+// Found an X-Window Server behind IP filters with FTP data hole? (you are
 // lucky!) 
 // prepare your host:
 # rm -f /tmp/.X11-unix/X1
@@ -241,7 +241,7 @@ $ socat - /tmp/postoffice
 // Uses of filan
 // See what your operating system opens for you
 $ filan
-// or if that was too detailled
+// or if that was too detailed
 $ filan -s
 // See what file descriptors are passed via exec function
 $ socat - EXEC:"filan -s",nofork
@@ -342,7 +342,7 @@ socat \
 // three main versions for entering password:
 // 1) from your TTY; have 10 seconds to enter password:
 (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty
-// 2) from XWindows (DISPLAY !); again 10 seconds
+// 2) from X-Windows (DISPLAY !); again 10 seconds
 (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty,setsid
 // 3) from script
 (sleep 5; echo PASSWORD; echo ls; sleep 1) |./socat - EXEC:'ssh server',pty,setsid,ctty
diff --git a/FAQ b/FAQ
index 51d8c1b..d3845eb 100644
--- a/FAQ
+++ b/FAQ
@@ -60,7 +60,7 @@ Q: When I specify a dual address (two partial addresses linked with "!!") on
 the command line, I get some message "event not found", and my shell history
 has the line truncated. Not even protecting the '!'s with '\' helps.
 
-A: '!' is appearently used by your shell as history expansion character. Say
+A: '!' is apparently used by your shell as history expansion character. Say
 "set +H" and add this line to your (bash) profile.
 
 
diff --git a/Makefile.in b/Makefile.in
index 631d31d..6187393 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ SHFILES = socat-chain.sh socat-mux.sh socat-broker.sh \
 	daemon.sh mail.sh ftp.sh readline.sh \
 	socat_buildscript_for_android.sh
 TESTFILES = test.sh socks4echo.sh proxyecho.sh readline-test.sh \
-	proxy.sh socks4a-echo.sh
+	proxy.sh socks4a-echo.sh socks5server-echo.sh
 
 all: progs doc
 
diff --git a/PORTING b/PORTING
index 0571bf7..2cbb8f1 100644
--- a/PORTING
+++ b/PORTING
@@ -51,7 +51,7 @@ ACTIVE PHASE:
   . xioopts.h: enum e_optcode  (sorted numerically/alphabetically by name)
   . xio-*.c: select the appropriate address file (e.g., xio-tcp.c for
     TCP-options) and make a record of type struct optdesc: opt_newoption
-  . xio-*.h: the declation of struct optdesc
+  . xio-*.h: the declaration of struct optdesc
   . xioopts.c: add records to  struct optname optionnames  for all appropriate
     names (sorted strictly ASCII for binary search)
   . filan.c: add the option to the appropriate array (sockopts, ipopts,
diff --git a/README b/README
index c48c095..da6f64a 100644
--- a/README
+++ b/README
@@ -58,18 +58,25 @@ Rocky 9
 Cygwin 10.0
 
 
-install
--------
+build
+-----
+
+You need at least gcc and make.
+A few libraries are required for full features:
+Debian:     libssl-dev    libreadline-dev libwrap0-dev
+Red Hat:    openssl-devel readline-devel  tcp_wrappers-libs
+Arch Linux: openssl       readline
+
 
 Get the tarball and extract it:
 	tar xzf socat.tar.gz
-	cd socat-1.8.0.2
+	cd socat-1.8.0.3
 	./configure
 	make
 	su
 	make install	# installs socat, filan, and procan in /usr/local/bin
 
-For compiling socat, gcc (or clang) is recommended.
+For compiling socat, gcc or a compatible compiler (e.g. clang) is recommended.
 If gcc (or a compiler with similar front end) is not available, the configure
 script might fail to determine some features
 
diff --git a/README.FIPS b/README.FIPS
index 0452844..2b92ea0 100644
--- a/README.FIPS
+++ b/README.FIPS
@@ -29,7 +29,7 @@ initializes things so after a fork, the child must reinitialize.  When the
 ssl code detects a forks occur and if FIPS mode was enabled, it reinitializes 
 FIPS by disabling and then enabling it again.
 
-To produce Davids enviroment, do the following:
+To produce Davids environment, do the following:
 To build openssl
 download  OpenSSL 0.9.7j-fips-dev from
 http://www.openssl.org/source/OpenSSL-fips-1.0.tar.gz
diff --git a/SECURITY b/SECURITY
index 0e10075..27f295a 100644
--- a/SECURITY
+++ b/SECURITY
@@ -24,7 +24,7 @@ avoid accessing files in world-writable directories like /tmp
 
 * When using socat with system, exec, or in a shell script, know what you do
 
-* With system and exec, use absolute pathes or set the path option
+* With system and exec, use absolute paths or set the path option
 
 * When starting programs with socat, consider using the chroot option (this
 requires root, so use the substuser option too).
diff --git a/VERSION b/VERSION
index 2b16796..12355b9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-"1.8.0.2"
+"1.8.0.3"
diff --git a/compat.h b/compat.h
index 72e73c7..ecfa27c 100644
--- a/compat.h
+++ b/compat.h
@@ -98,6 +98,10 @@ typedef int sig_atomic_t;
 #  define SOL_IPV6 IPPROTO_IPV6
 #endif
 
+#ifndef EAI_NODATA
+#  define EAI_NODATA 7 	/* for old FreeBSD */
+#endif
+
 #define F_uint8_t "%hu"
 #define F_uint8_x "%02hx"
 #define F_int8_t  "%hd"
diff --git a/config.h.in b/config.h.in
index 682913e..cd2fdeb 100644
--- a/config.h.in
+++ b/config.h.in
@@ -162,6 +162,12 @@
 /* Define if you have the clock_gettime function */
 #undef HAVE_CLOCK_GETTIME
 
+/* Define if you have the getresuid function */
+#undef HAVE_GETRESUID
+
+/* Define if you have the getresgid function */
+#undef HAVE_GETRESGID
+
 /* Define if you have the strtoll function */
 #undef HAVE_STRTOLL
 
@@ -282,6 +288,9 @@
 /* Define if you have the <linux/if_tun.h> header file.  */
 #undef HAVE_LINUX_IF_TUN_H
 
+/* Define if you have the <netinet/dccp.h> header file.  */
+#undef HAVE_NETINET_DCCP_H
+
 /* Define if you have the <linux/dccp.h> header file.  */
 #undef HAVE_LINUX_DCCP_H
 
@@ -333,6 +342,9 @@
 /* Define if you have the <readline/history.h> header file. */
 #undef HAVE_READLINE_HISTORY_H
 
+/* Define if you have the <mqueue.h> header file. */
+#undef HAVE_MQUEUE_H
+
 /* Define if you have the readline library. */
 #undef HAVE_LIBREADLINE
 
diff --git a/configure.ac b/configure.ac
index b0227ec..f36a27b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,7 +39,7 @@ AC_PROG_RANLIB
 AC_SUBST(AR)
 AC_CHECK_PROG(AR, ar, ar, gar)
 #
-# we need to explicitely call this here; otherwise, with --disable-libwrap we
+# we need to explicitly call this here; otherwise, with --disable-libwrap we
 # fail
 AC_LANG_COMPILER_REQUIRE()
 
@@ -409,21 +409,33 @@ AC_ARG_ENABLE(dccp, [  --disable-dccp           disable DCCP support],
 	       [AC_MSG_RESULT(yes);   WITH_DCCP=1 ])
 
 if test -n "$WITH_DCCP"; then
-AC_MSG_CHECKING(for IPPROTO_DCCP)
-AC_CACHE_VAL(sc_cv_define_ipproto_dccp,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>],
-[IPPROTO_DCCP;],
-[sc_cv_define_ipproto_dccp=yes],
-[sc_cv_define_ipproto_dccp=no])])
-AC_MSG_RESULT($sc_cv_define_ipproto_dccp)
-if test $sc_cv_define_ipproto_dccp = yes; then
-   AC_DEFINE(WITH_DCCP)
+   AC_CHECK_HEADER(netinet/dccp.h,
+     AC_DEFINE(HAVE_NETINET_DCCP_H))
    AC_CHECK_HEADER(linux/dccp.h,
      AC_DEFINE(HAVE_LINUX_DCCP_H))
-else
-   AC_MSG_WARN([IPPROTO_DCCP undefined, disabling DCCP support])
 fi
+if test -n "$WITH_DCCP"; then
+   AC_MSG_CHECKING(for IPPROTO_DCCP)
+   AC_CACHE_VAL(sc_cv_define_ipproto_dccp,
+   [AC_TRY_COMPILE([#include <sys/types.h>
+   #include <netinet/in.h>],
+   [IPPROTO_DCCP;],
+   [sc_cv_define_ipproto_dccp=yes],
+   [sc_cv_define_ipproto_dccp=no; WITH_DCCP=])])
+   AC_MSG_RESULT($sc_cv_define_ipproto_dccp)
+fi
+if test -n "$WITH_DCCP"; then
+   AC_MSG_CHECKING(for SOCK_DCCP)
+   AC_CACHE_VAL(sc_cv_define_sock_dccp,
+   [AC_TRY_COMPILE([#include <sys/types.h>
+   #include <netinet/in.h>],
+   [SOCK_DCCP;],
+   [sc_cv_define_sock_dccp=yes],
+   [sc_cv_define_sock_dccp=no; WITH_DCCP=])])
+   AC_MSG_RESULT($sc_cv_define_sock_dccp)
+fi
+if test -n "$WITH_DCCP"; then
+   AC_DEFINE(WITH_DCCP)
 fi
 
 AC_MSG_CHECKING(whether to include vsock support)
@@ -489,6 +501,13 @@ AC_ARG_ENABLE(posixmq, [  --disable-posixmq       disable POSIX MQ support],
 	       *) WITH_POSIXMQ=1; AC_MSG_RESULT(yes);;
 	       esac],
 	       [WITH_POSIXMQ=1; AC_MSG_RESULT(yes)])
+if test "$WITH_POSIXMQ"; then
+    AC_CHECK_HEADERS(mqueue.h)
+    if test "x$ac_cv_header_mqueue_h" != xyes; then
+	AC_MSG_WARN([Header mqueue.h not found, disabling POSIX MQ])
+	WITH_POSIXMQ=
+    fi
+fi
 if test "$WITH_POSIXMQ"; then
     case "`uname`" in
     Linux) AC_DEFINE(WITH_POSIXMQ)
@@ -652,23 +671,16 @@ if test -n "$WITH_OPENSSL"; then
   AC_CACHE_VAL(sc_cv_have_openssl_ssl_h,
     [AC_TRY_COMPILE([#include <openssl/ssl.h>],[;],
       [sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE=""; ],
-      [sc_cv_have_openssl_ssl_h=no
-       if test "$OPENSSL_BASE"; then
-	  Ds="$OPENSSL_BASE"
-       else
-          Ds="/sw /usr/local /opt/freeware /usr/sfw /usr/local/ssl"
-       fi
-       for D in $Ds; do
-	I="$D/include"
-	i="$I/openssl/ssl.h"
-	if test -r "$i"; then
-	  #V_INCL="$V_INCL -I$I"
-	  CPPFLAGS="$CPPFLAGS -I$I"
-	  AC_MSG_NOTICE(found $i)
-	  sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE="$D"
-	  break;
-	fi
-      done])
+      [
+        # Another attempt to compile with OPENSSL_NO_KRB5
+	AC_MSG_NOTICE(trying with -DOPENSSL_NO_KRB5)
+	CFLAGS_ORIG="$CFLAGS"
+	CFLAGS="$CFLAGS -DOPENSSL_NO_KRB5"
+	AC_TRY_COMPILE([#include <openssl/ssl.h>],[;],
+	  [sc_cv_have_openssl_ssl_h=yes],
+	  [sc_cv_have_openssl_ssl_h=no
+	   CFLAGS="$CFLAGS_ORIG"])
+    ])
   ])
   if test "$sc_cv_have_openssl_ssl_h" = "yes"; then
     AC_DEFINE(HAVE_OPENSSL_SSL_H)
@@ -1722,6 +1734,8 @@ AC_CHECK_PROTOTYPE_LIB(gettimeofday)
 
 AC_CHECK_FUNC(clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME), AC_CHECK_LIB(rt, clock_gettime, [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_CLOCK_GETTIME)]))
 
+AC_CHECK_FUNCS(getresuid getresgid)
+
 dnl Search for flock()
 # with Linux it's in libc, with AIX in libbsd
 AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK),
@@ -2248,7 +2262,7 @@ AC_TRY_COMPILE([#include <resolv.h>],
 
 dnl "tcpd" "tcpwrappers"
 # on some platforms, raw linking with libwrap fails because allow_severity and
-# deny_severity are not explicitely defined. Thus we put the libwrap part to
+# deny_severity are not explicitly defined. Thus we put the libwrap part to
 # the end
 AC_MSG_CHECKING(whether to include libwrap support)
 AC_ARG_ENABLE(libwrap, [  --disable-libwrap       disable libwrap support],
@@ -2303,7 +2317,7 @@ int allow_severity,deny_severity;],[hosts_access(0)],
 	AC_TRY_LINK([#include <sys/types.h>
 #include <tcpd.h>
 int allow_severity,deny_severity;],[hosts_access(0)],
-      	  [sc_cv_have_libwrap='yes'],
+	  [sc_cv_have_libwrap='yes'],
 	  [sc_cv_have_libwrap='no'])
       ]
       )
diff --git a/doc/socat-genericsocket.html b/doc/socat-genericsocket.html
index 0525696..2ad1440 100644
--- a/doc/socat-genericsocket.html
+++ b/doc/socat-genericsocket.html
@@ -10,7 +10,7 @@
 <h2>Introduction</h2>
 <p>Beginning with version 1.7.0 socat provides means to freely control 
   important aspects of socket handling. This allows to experiment with socket
-  types and protocols that are not explicitely implemented in socat.
+  types and protocols that are not explicitly implemented in socat.
 </p>
 
 <p>The related socat features fall into three major categories:<p>
@@ -216,7 +216,7 @@ struct sockaddr_at {
 </p>
   
 <p>The address family component must be omitted from the socket address because
-  it is added by socat implicitely. The resulting hexadecimal representation of
+  it is added by socat implicitly. The resulting hexadecimal representation of
   the target socket address is therefore:
 </p>
 <tt>x40x00xff00xf3x00x0000000000000000</tt>
@@ -287,7 +287,7 @@ struct sockaddr_at {
 and for bind and range options. The basis is the <tt>struct sockaddr_*</tt> for
 the respective address family that should be declared in the C include files.
 Please keep in mind that their first two bytes (<tt>sa_family</tt> and - on BSD
-- <tt>sa_len</tt>) are implicitely prepended by socat.</p>
+- <tt>sa_len</tt>) are implicitly prepended by socat.</p>
 
 <h4>Linux on 32bit Intel:</h4>
 
diff --git a/doc/socat.yo b/doc/socat.yo
index abfd991..106686a 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -313,6 +313,7 @@ label(ADDRESS_CREAT)dit(bf(tt(CREATE:<filename>)))
    if <filename> refers to a socket, this is an error.nl() 
    Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED) nl()
    Useful options:
+   link(mode)(OPTION_UMASK),
    link(mode)(OPTION_MODE),
    link(user)(OPTION_USER),
    link(group)(OPTION_GROUP),
@@ -332,7 +333,7 @@ label(ADDRESS_DCCP_CONNECT)dit(bf(tt(DCCP-CONNECT:<host>:<port>)) (bf(tt(DCCP:<h
    link(connect-timeout)(OPTION_CONNECT_TIMEOUT),
    link(tos)(OPTION_TOS),
    link(dccp-set-ccid)(OPTION_DCCP_SET_CCID),
-   link(nonblock)(OPTION_NONBLOCK),
+   link(nonblock)(OPTION_O_NONBLOCK),
    link(sourceport)(OPTION_SOURCEPORT),
    link(retry)(OPTION_RETRY),
    link(readbytes)(OPTION_READBYTES)nl()
@@ -583,7 +584,7 @@ label(ADDRESS_OPEN)dit(bf(tt(OPEN:<filename>)))
    Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl()
    Useful options:
    link(creat)(OPTION_O_CREAT),
-   link(excl)(OPTION_EXCL),
+   link(excl)(OPTION_O_EXCL),
    link(noatime)(OPTION_O_NOATIME),
    link(nofollow)(OPTION_NOFOLLOW),
    link(append)(OPTION_APPEND),
@@ -747,7 +748,7 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>)))
    Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl()
    Useful options:
    link(rdonly)(OPTION_RDONLY),
-   link(nonblock)(OPTION_NONBLOCK),
+   link(nonblock)(OPTION_O_NONBLOCK),
    link(group)(OPTION_GROUP),
    link(user)(OPTION_USER),
    link(mode)(OPTION_MODE),
@@ -773,50 +774,65 @@ label(ADDRESS_SOCKETPAIR)dit(bf(tt(SOCKETPAIR)))
    See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE)
 
 label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>)))
-   Opens the specified POSIX message queue and reads messages (packets). It
-   keeps the boundaries.nl()
+   Opens or creates the specified POSIX message queue and reads messages
+   (packets). It keeps the packet boundaries.nl()
    This is a read-only address, see options link(-u)(option_u) and
    link(-U)(option_U) and link(dual addresses)(ADDRESS_DUAL).nl()
    Socat() provides this address type only on Linux because POSIX MQ is based
    on UNIX filedescriptors there.nl()
-   This feature is new in version 1.8.0.0 and might change in the future,
-   therefore it is link(experimental)(option_experimental).nl()
    Useful options:
    link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY),
    link(unlink-early)(OPTION_UNLINK_EARLY),
-   link(unlink-close)(OPTION_UNLINK_CLOSE)
+   link(unlink-close)(OPTION_UNLINK_CLOSE),
+   link(o-nonblock)(OPTION_O_NONBLOCK),
+   link(o-creat)(OPTION_O_CREAT),
+   link(o-excl)(OPTION_O_EXCL),
+   link(umask)(OPTION_UMASK)
 
 label(ADDRESS_POSIXMQ_RECEIVE)dit(bf(tt(POSIXMQ-RECEIVE:/<mqueue>)))
 dit(bf(tt(POSIXMQ-RECV:/<mqueue>)))
-   Opens the specified POSIX message queue and reads one message (packet).nl()
+   Opens or creates the specified POSIX message queue and reads one message
+   (packet).nl()
    This is a read-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ)
    for more info.nl()
    Example: link(POSIX MQ recv with fork)(EXAMPLE_POSIXMQ_RECV_FORK)nl()
-   This feature is link(experimental)(option_experimental).nl()
    Useful options:
    link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY),
    link(fork)(OPTION_FORK),
    link(max-children)(OPTION_MAX_CHILDREN),
    link(unlink-early)(OPTION_UNLINK_EARLY),
-   link(unlink-close)(OPTION_UNLINK_CLOSE)
+   link(unlink-close)(OPTION_UNLINK_CLOSE),
+   link(o-creat)(OPTION_O_CREAT),
+   link(o-excl)(OPTION_O_EXCL),
+   link(umask)(OPTION_UMASK)
 
 label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>)))
-   Opens the specified POSIX message queue and writes messages (packets).nl()
+   Opens or creates the specified POSIX message queue and writes messages
+   (packets).nl()
    This is a write-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ)
    for more info.nl()
    (link(Example)(EXAMPLE_POSIXMQ_SEND))nl()
-   This feature is link(experimental)(option_experimental).nl()
    Useful options:
    link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY),
+   link(posixmq-flush)(OPTION_POSIXMQ_FLUSH),
    link(fork)(OPTION_FORK),
    link(max-children)(OPTION_MAX_CHILDREN),
    link(unlink-early)(OPTION_UNLINK_EARLY),
-   link(unlink-close)(OPTION_UNLINK_CLOSE)
+   link(unlink-close)(OPTION_UNLINK_CLOSE),
+   link(o-creat)(OPTION_O_CREAT),
+   link(o-excl)(OPTION_O_EXCL),
+   link(umask)(OPTION_UMASK)
+
+label(ADDRESS_POSIXMQ_WRITE)dit(bf(tt(POSIXMQ-WRITE:/<mqueue>)))
+   Does the same as link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND).
 
 label(ADDRESS_POSIXMQ_BIDIRECTIONAL)dit(bf(tt(POSIXMQ-BIDIRECTIONAL:/mqueue)))
-   Opens the specified POSIX message queue and writes and reads messages
-   (packet). This is probably rarely useful but has been implemented for
-   functional completeness.
+dit(bf(tt(POSIXMQ:/mqueue)))
+   Opens or creates the specified POSIX message queue in read and/or write mode
+   depending on context, then reads and/or writes messages (packets).
+   In bidirectional mode this is just another echo service.nl()
+   See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) and
+   link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND) for more info.
 
 label(ADDRESS_PROXY_CONNECT)dit(bf(tt(PROXY:<proxy>:<hostname>:<port>)))
    Connects to an HTTP proxy server on port 8080 using TCP/IP  version 4 or 6
@@ -882,7 +898,7 @@ label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT:<host>:<port>)))
    link(mtudiscover)(OPTION_MTUDISCOVER),
    link(sctp-maxseg)(OPTION_SCTP_MAXSEG),
    link(sctp-nodelay)(OPTION_SCTP_NODELAY),
-   link(nonblock)(OPTION_NONBLOCK),
+   link(nonblock)(OPTION_O_NONBLOCK),
    link(sourceport)(OPTION_SOURCEPORT),
    link(retry)(OPTION_RETRY),
    link(readbytes)(OPTION_READBYTES)nl()
@@ -1103,11 +1119,11 @@ label(ADDRESS_SOCKS4A)dit(bf(tt(SOCKS4A:<socks-server>:<host>:<port>)))
    Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(SOCKS4)(GROUP_SOCKS),link(RETRY)(GROUP_RETRY) nl()
 
 label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port>:<target-host>:<target-port>)))
+dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<target-host>:<target-port>)))
    Connects via <socks-server> [link(IP address)(TYPE_IP_ADDRESS)]
    to <target-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)]
    on <target-port> [link(TCP service)(TYPE_TCP_SERVICE)],
    using socks version 5 protocol over TCP. Currently no authentication mechanism is provided.nl()
-   This address type is experimental.nl()
    Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
    Useful options:
    link(socksport)(OPTION_SOCKSPORT),
@@ -1122,10 +1138,11 @@ label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port
    link(TCP)(ADDRESS_TCP_CONNECT)
 
 label(ADDRESS_SOCKS5_LISTEN)dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<socks-port>:<listen-host>:<listen-port>)))
+dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<listen-host>:<listen-port>)))
    Connects to <socks-server> [link(IP address)(TYPE_IP_ADDRESS)]
    using socks version 5 protocol over TCP
    and makes it listen for incoming connections on <listen-port> [link(TCP service)(TYPE_TCP_SERVICE)], binding to <-listen-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)]
-   Currently not authentication mechanism is provided. This address type is experimental.
+   Currently not authentication mechanism is provided.nl()
    Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
    Useful options:
    link(sourceport)(OPTION_SOURCEPORT),
@@ -1233,7 +1250,7 @@ label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP:<host>:<port>)))
    link(mtudiscover)(OPTION_MTUDISCOVER),
    link(mss)(OPTION_MSS),
    link(nodelay)(OPTION_TCP_NODELAY),
-   link(nonblock)(OPTION_NONBLOCK),
+   link(nonblock)(OPTION_O_NONBLOCK),
    link(readbytes)(OPTION_READBYTES)nl()
    See also:
    link(TCP4)(ADDRESS_TCP4_CONNECT),
@@ -1290,7 +1307,7 @@ label(ADDRESS_TCP6_LISTEN)dit(bf(tt(TCP6-LISTEN:<port>)))
    link(ipv6only)(OPTION_IPV6_V6ONLY)nl()
    Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl()
 label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>])))
-   Creates a Linux TUN/TAP device and optionally assignes it the address and
+   Creates a Linux TUN/TAP device and optionally assigns it the address and
    netmask given by the parameters. The resulting network interface is almost
    ready for use by other processes; socat serves its "wire side". This address
    requires read and write access to the tunnel cloning device, usually
@@ -1418,7 +1435,8 @@ label(ADDRESS_UDP_SENDTO)dit(bf(tt(UDP-SENDTO:<host>:<port>)))
    link(pf)(OPTION_PROTOCOL_FAMILY). It sends packets to and receives packets
    from that peer socket only.  
    This address effectively implements a datagram client.
-   It works well with socat UDP-RECVFROM and UDP-RECV address peers.nl()
+   It works well with socat UDP-RECVFROM and UDP-RECV address peers.
+   When the peer might send data first, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is preferable.nl()
    Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl()
    Useful options:
    link(ttl)(OPTION_TTL),
@@ -1456,7 +1474,8 @@ label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:<port>)))
    label(NOTE_RECVFROM)Note: When the second address fails before entering the transfer loop the
    packet is dropped. Use option link(retry)(OPTION_RETRY) or
    link(forever)(OPTION_FOREVER) on the second address to avoid data loss.
-   nl()
+   When you know the peer address, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is
+   preferable.nl()
    Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
    Useful options:
    link(fork)(OPTION_FORK),
@@ -1839,8 +1858,10 @@ label(OPTION_MODE)dit(bf(tt(mode=<mode>)))
    system calls, socat() uses the code(chmod()) system call after opening the
    filesystem entry or binding to the unixdomain() socket (race condition!).
    Otherwise, socat() sets the mode of the stream
-   using code(fchmod()). 
-   These calls might require ownership or root privilege.
+   using code(fchmod()) which, btw, might not have any effect.nl()
+   These calls might require ownership or root privilege.nl()
+   Note: this option can only tighten the permissions implied by processes
+   umask. See option link(umask)(OPTION_UMASK) to loosen permissions.
 label(OPTION_PERM_LATE)dit(bf(tt(perm-late=<mode>)))
    Sets the permissions of the fd to value <mode>
    [link(mode_t)(TYPE_MODE_T)] using the code(fchmod()) system call after
@@ -1852,7 +1873,7 @@ label(OPTION_APPEND)dit(bf(tt(append[=<bool>])))
    socat() uses the code(O_APPEND) flag with the code(open()) system call
    (link(example)(EXAMPLE_OPTION_APPEND)).
    Otherwise, socat() applies the code(fcntl(fd, F_SETFL, O_APPEND)) call.
-label(OPTION_NONBLOCK)dit(bf(tt(nonblock[=<bool>])))
+label(OPTION_O_NONBLOCK)dit(bf(tt(nonblock[=<bool>])))
    Tries to open or use file in nonblocking mode. Its only effects are that the
    code(connect()) call of TCP addresses does not block, and that opening a
    named pipe for reading does not block.
@@ -1987,13 +2008,13 @@ E.g., option `creat' sets the code(O_CREAT) flag. When the used address does
 not use code(open()) (e.g.STDIO), the code(fcntl(..., F_SETFL, ...)) call is
 used instead.nl()
 See also options link(append)(OPTION_APPEND) and
-link(nonblock)(OPTION_NONBLOCK).
+link(nonblock)(OPTION_O_NONBLOCK).
 startdit()
 label(OPTION_O_CREAT)dit(bf(tt(creat[=<bool>])))
    Creates the file if it does not exist (link(example)(EXAMPLE_OPTION_CREAT)).
 label(OPTION_DSYNC)dit(bf(tt(dsync[=<bool>])))
    Blocks code(write()) calls until metainfo is physically written to media.
-label(OPTION_EXCL)dit(bf(tt(excl[=<bool>])))
+label(OPTION_O_EXCL)dit(bf(tt(excl[=<bool>])))
    With option creat, if file exists this is an error.
 label(OPTION_LARGEFILE)dit(bf(tt(largefile[=<bool>])))
    On 32 bit systems, allows a file larger than 2^31 bytes.
@@ -2108,8 +2129,9 @@ label(OPTION_CHDIR)dit(bf(tt(chdir=<filename>))) dit(bf(tt(cd=<filename>)))
 label(OPTION_UMASK)dit(bf(tt(umask=<mode>)))
    Sets the umask of the process to <mode> [link(mode_t)(TYPE_MODE_T)] before
    opening the address. Useful when file system entries are created or a shell
-   or program is invoked. Usually the value is specified as octal number.nl()
-   The processes tt(umask) value is inherited by child processes.
+   or program is invoked. Usually the value is specified as octal number with
+   leading '0'.nl()
+   The processes tt(umask) value is inherited by child processes.nl()
    Note: umask is an inverted value: creating a file with umask=0026 results in
    permissions 0640.
 enddit()
@@ -2136,7 +2158,7 @@ label(OPTION_SETGID)dit(bf(tt(setgid=<group>)))
    processing the address. This call might require root privilege. Please note
    that this option does not drop other group related privileges.
 label(OPTION_SETGID_EARLY)dit(bf(tt(setgid-early=<group>)))
-   Like link(setgit)(OPTION_SETGID) but is performed before opening the address.
+   Like link(setgid)(OPTION_SETGID) but is performed before opening the address.
 label(OPTION_SETUID)dit(bf(tt(setuid=<user>)))
    Changes the link(<user>)(TYPE_USER) (owner) of the process after processing
    the address. This call might require root privilege. Please note that this
@@ -2164,9 +2186,9 @@ label(OPTION_SETSID)dit(bf(tt(setsid)))
    Makes the process the leader of a new session (link(example)(EXAMPLE_OPTION_SETSID)).
 label(OPTION_NETNS)dit(bf(tt(netns=<net-namespace-name>)))
    Before opening the address it tries to switch to the named network namespace.
-   After opening the address it switches back to the previous namespace.
-   (link(Example with TCP forwarder)(EXAMPLE_OPTION_NETNS),
-   link(example with virtual network connection)(EXAMPLE_TUN_NETNS).nl()
+   After opening the address it switches back to the previous namespace
+   (link(example with TCP forwarder)(EXAMPLE_OPTION_NETNS),
+   link(example with virtual network connection)(EXAMPLE_TUN_NETNS)).nl()
    Only on Linux; requires root; use option tt(--experimental).nl()
 enddit()
 
@@ -2189,7 +2211,7 @@ label(OPTION_NOECHO)dit(bf(tt(noecho=<pattern>)))
    Specifies a regular pattern for a prompt that prevents the following input
    line from being displayed on the screen and from being added to the history.
    The prompt is defined as the text that was output to the readline address 
-   after the lastest newline character and before an input character was
+   after the last newline character and before an input character was
    typed. The pattern is a regular expression, e.g.
    "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See NOEXPAND(regex(7)) for details.
    (link(example)(EXAMPLE_OPTION_NOECHO))
@@ -2368,7 +2390,7 @@ COMMENT(label(OPTION_SECURITYENCRYPTIONNETWORK)dit(bf(tt(securityencryptionnetwo
 COMMENT(label(OPTION_SECURITYENCRYPTIONTRANSPORT)dit(bf(tt(securityencryptiontransport)))
    Set the code(SO_SECURITY_ENCRYPTION_TRANSPORT) socket option.)
 COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=<pid_t>)))
-   Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.)
+   Set the SIOCSPGRP with code(ioctl()) to enable SIGIO.)
 COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs)))
    Set the code(SO_USE_IFBUFS) socket option.)
 label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp)))
@@ -2394,6 +2416,12 @@ label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=<level>:<optname>:<op
    Like tt(setsockopt), but <optval> is a link(string)(TYPE_STRING).
    This string is passed to the function with trailing null character, and the
    length parameter is automatically derived from the data.
+label(OPTION_SETSOCKOPT_SOCKET)dit(bf(tt(setsockopt-socket=<level>:<optname>:<optval>)))
+   Like tt(setsockopt), but is applied to the socket before other operations
+   (code(bind()), code(connect()), code(accept()), ...)
+label(OPTION_SETSOCKOPT_CONNECTED)dit(bf(tt(setsockopt-connected=<level>:<optname>:<optval>)))
+   Like tt(setsockopt), but is applied only when the socket has been connected
+   by a code(connect()) or code(listen()) call.
 enddit()
 
 startdit()enddit()nl()
@@ -2525,7 +2553,8 @@ dit(bf(tt(ipv6-join-source-group=<multicast-address:interface-index:source-addre
    IPv4 variant. The option takes the IP address of the multicast group,
    info about the desired network interface and the source IP address of the
    multicast traffic. The indices of active network interfaces can be shown
-   using the utility procan().
+   using the utility procan().nl()
+   This feature is experimental.
 label(OPTION_IP_MULTICAST_IF)
 dit(bf(tt(ip-multicast-if=<hostname>)))
    Specifies hostname or address of the network interface to be used for
@@ -2976,6 +3005,8 @@ label(OPTION_NOFORK)dit(bf(tt(nofork)))
    it() the first socat address cannot be OPENSSL or READLINE
    it() socat options -b, -t, -D, -l, -v, -x become useless
    it() for both addresses, options ignoreeof, cr, and crnl become useless
+   it() for both addresses, address specific end/shutdown handling (e.g.,
+   graceful socket shutdown) and related options become useless
    it() for the second address (the one with option nofork), options 
       append, metaCOMMENT(async,) cloexec, flock, user, group, mode, nonblock,
       perm-late, setlk, and setpgid cannot be applied. Some of these could be
@@ -3345,7 +3376,7 @@ label(OPTION_OPENSSL_PSEUDO)dit(bf(tt(pseudo)))
    gathering daemon can be utilized, this option activates a mechanism for
    providing pseudo entropy. This is achieved by taking the current time in
    microseconds for feeding the libc pseudo random number generator with an
-   initial value. openssl is then feeded with output from NOEXPAND(random()) calls.nl()
+   initial value. openssl is then fed with output from NOEXPAND(random()) calls.nl()
    NOTE:This mechanism is not sufficient for generation of secure keys!
 label(OPTION_OPENSSL_COMPRESS)dit(bf(tt(compress)))
    Enable or disable the use of compression for a connection. Setting this to
@@ -3490,6 +3521,15 @@ startdit()
 label(OPTION_POSIXMQ_PRIORITY)dit(bf(tt(posixmq-priority (mq-prio))))
    Sets the priority of messages (packets) written to the queue, or the minimal
    priority of packet read from the queue.
+label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush))))
+   "Consumes" (drops) all messages currently in the queue before starting
+   transfers.
+label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg))))
+   Sets the maxmsg parameter of the POSIX message queue when creating it.nl()
+   Note: This option applies only when the queue does not already exist.
+label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize))))
+   Sets the msgsize parameter of the POSIX message queue when creating it.nl()
+   Note: This option applies only when the queue does not already exist.
 enddit()
 
 
@@ -3512,7 +3552,8 @@ label(TYPE_COMMAND_LINE)dit(command-line)
    A string specifying a program name and its arguments, separated by single
    spaces. 
 label(TYPE_DATA)dit(data)
-   This is a more general data specification. The given text string contains
+   This is a more general data specification, "dalan" (low level data
+   description language). The given text string contains
    information about the target data type and value. Generally a leading
    character specifies the type of the following data item. In its specific
    context a default data type may exist.nl()
@@ -3528,12 +3569,12 @@ label(TYPE_DATA)dit(data)
    dit(b)  A signed byte (signed char).nl()
    dit(B)  An unsigned byte (unsigned char).nl()
    dit(x)  Following is an even number of hex digits, stored as sequence of
-   bytes.nl()
+   bytes, the data length is the resulting number of bytes.nl()
    Example:    bf(x7f000001) (IP address 127.0.0.1)
    dit(")  Following is a string that is used with the common conversions 
    \n \r \t \f \b \a \e \0; the string must be closed with '"'. Please note
    that the quotes and backslashes need to be escaped from shell and socat()
-   conversion.nl()
+   conversion. No implicit \0 is appended.nl()
    Example:    bf("Hello world!\n")
    dit(')  A single char, with the usual conversions. Please note that the
    quotes and backslashes need to be escaped from shell and socat() conversion.
@@ -3581,10 +3622,10 @@ label(TYPE_LONG)dit(long)
 label(TYPE_LONGLONG)dit(long long)
    A number read with code(strtoll()). The value must fit into a C long long.
 label(TYPE_OFF)dit(off_t)
-   An implementation dependend signed number, usually 32 bits, read with strtol
+   An implementation dependent signed number, usually 32 bits, read with strtol
    or strtoll.
 label(TYPE_OFF64)dit(off64_t)
-   An implementation dependend signed number, usually 64 bits, read with strtol
+   An implementation dependent signed number, usually 64 bits, read with strtol
    or strtoll.
 label(TYPE_MODE_T)dit(mode_t)
    An unsigned integer, read with code(strtoul()), specifying mode (permission)
@@ -3972,7 +4013,7 @@ prompts.
 label(EXAMPLE_ADDRESS_PTY)
 label(EXAMPLE_OPTION_SYMBOLIC_LINK)
 label(EXAMPLE_OPTION_WAIT_SLAVE)
-label(EXAMPLE_OPTION_NONBLOCK)
+label(EXAMPLE_OPTION_O_NONBLOCK)
 mancommand(\.LP)
 mancommand(\.nf)
 mancommand(\fBsocat \\)
@@ -4445,14 +4486,14 @@ both devices. Use pppd on device tt(/var/run/ppp) then.
 label(EXAMPLE_POSIXMQ_SEND)
 mancommand(\.LP)
 mancommand(\.nf)
-mancommand(\fBsocat --experimental -u \\)
+mancommand(\fBsocat -u \\)
 mancommand(\.RS)
 mancommand(\fBSTDIO \\ 
 	POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10\fP)
 mancommand(\.RE)
 mancommand(\.fi)
 
-htmlcommand(<hr><div class="shell">socat --experimental -u &#x5C;
+htmlcommand(<hr><div class="shell">socat -u &#x5C;
     STDIO &#x5C;
     POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10</div>)
 
@@ -4464,7 +4505,7 @@ label(EXAMPLE_POSIXMQ_RECV_FORK)
 
 mancommand(\.LP)
 mancommand(\.nf)
-mancommand(\fBsocat --experimental -u \\)
+mancommand(\fBsocat -u \\)
 mancommand(\.RS)
 mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\ 
 	SYSTEM:"worker.sh"\fP)
@@ -4472,7 +4513,7 @@ mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\
 mancommand(\.RE)
 mancommand(\.fi)
 
-htmlcommand(<hr><div class="shell">socat --experimental -u &#x5C;
+htmlcommand(<hr><div class="shell">socat -u &#x5C;
     POSIXMQ-RECV:/queue1,fork,max-children=3 &#x5C;
     SYSTEM:"worker.sh"</div>)
 
diff --git a/error.h b/error.h
index 9853f8a..0cc4fac 100644
--- a/error.h
+++ b/error.h
@@ -183,7 +183,7 @@
 #define Debug18(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18)
 #endif /* !(WITH_MSGLEVEL <= E_DEBUG) */
 
-/* message with software controlled serverity */
+/* message with software controlled severity */
 #if WITH_MSGLEVEL <= E_FATAL
 #define Msg(l,m) msg(l,"%s",m)
 #define Msg1(l,m,a1) msg(l,m,a1)
diff --git a/fdname.c b/fdname.c
index e226bda..af7afc0 100644
--- a/fdname.c
+++ b/fdname.c
@@ -226,7 +226,7 @@ int sockname(int fd, FILE *outfile, char style) {
 #define FDNAME_OPTLEN 256
 #define FDNAME_NAMELEN 256
    socklen_t optlen;
-#if HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R
+#if (WITH_IP4 || WITH_IP6) && ( HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R )
    struct protoent protoent, *protoentp;
 #endif
 #define PROTONAMEMAX 1024
@@ -278,7 +278,7 @@ int sockname(int fd, FILE *outfile, char style) {
    Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen);
 #endif
 
-#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE)
+#if (WITH_IP4 || WITH_IP6) && ( defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) )
 #if HAVE_GETPROTOBYNUMBER_R==1 /* Linux */
    rc = getprotobynumber_r(proto, &protoent, protoname, sizeof(protoname), &protoentp);
    if (protoentp == NULL) {
diff --git a/filan.c b/filan.c
index 36def50..fb9229c 100644
--- a/filan.c
+++ b/filan.c
@@ -393,7 +393,7 @@ int filan_stat(
       break;
 #ifdef S_IFLNK
    case (S_IFLNK):	/* 10, symbolic link */
-      /* we wait for freadlink() sytem call */
+      /* we wait for freadlink() system call */
       break;
 #endif /* S_IFLNK */
       break;
@@ -804,13 +804,13 @@ int ipan(int fd, FILE *outfile) {
    }
    /* want to pass the fd to the next layer protocol. */
 #if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE)
-   if (Getsockopt(fd, SOL_SOCKET,
+   if (
 #ifdef SO_PROTOCOL
-		  SO_PROTOCOL,
+       Getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &optproto, &optlen)
 #elif defined(SO_PROTOTYPE)
-		  SO_PROTOTYPE,
+       Getsockopt(fd, SOL_SOCKET, SO_PROTOTYPE, &optproto, &optlen)
 #endif
-		  &optproto, &optlen) >= 0) {
+       >= 0) {
       switch (optproto) {
 #if WITH_TCP
       case IPPROTO_TCP: tcpan(fd, outfile); break;
diff --git a/filan_main.c b/filan_main.c
index 24dd5e9..d90432f 100644
--- a/filan_main.c
+++ b/filan_main.c
@@ -167,7 +167,7 @@ int main(int argc, const char *argv[]) {
    Nanosleep(&waittime, NULL);
 
    if (style == 0) {
-      /* this style gives detailled infos, but requires a file descriptor */
+      /* This style gives detailed infos, but requires a file descriptor */
       if (filename) {
 #if LATER /* this is just in case that S_ISSOCK does not work */
 	 struct stat buf;
diff --git a/hostan.c b/hostan.c
index 80ea569..4258d3c 100644
--- a/hostan.c
+++ b/hostan.c
@@ -33,6 +33,11 @@ int hostan(FILE *outfile) {
 #endif
    fprintf(outfile, "sizeof(size_t)    = %u\n", (unsigned int)sizeof(size_t));
 
+   if ((char)-1 > 0)
+      fprintf(outfile, "typedef unsigned char       char;\n");
+   else
+      fprintf(outfile, "typedef signed char         char;\n");
+
 #  if HAVE_BASIC_SIZE_T==2
    fprintf(outfile, "typedef unsigned short      size_t;     /* sizeof(size_t) = %u */\n", (unsigned int)sizeof(size_t));
 #elif HAVE_BASIC_SIZE_T==4
diff --git a/procan-cdefs.c b/procan-cdefs.c
index d9587f8..af56e69 100644
--- a/procan-cdefs.c
+++ b/procan-cdefs.c
@@ -15,30 +15,91 @@
 #include "procan.h"
 
 int procan_cdefs(FILE *outfile) {
-   /* basic C/system constants */
+   /* System constants */
+#ifdef __KERNEL__
+   fprintf(outfile, "__KERNEL__                = \"%s\"\n", __KERNEL__);
+#endif
+#ifdef __GLIBC__
+   fprintf(outfile, "__GLIBC__                 = %d\n", __GLIBC__);
+#endif
+   /* Basic C/system constants */
 #ifdef FD_SETSIZE
-   fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE);
+   fprintf(outfile, "#define FD_SETSIZE  %u\n", FD_SETSIZE);
 #endif
 #ifdef NFDBITS
-   fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS);
+   fprintf(outfile, "#define NFDBITS     %d\n", (int)NFDBITS);
 #endif
 #ifdef O_RDONLY
-   fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY);
+   fprintf(outfile, "#define O_RDONLY    %u\n", O_RDONLY);
 #endif
 #ifdef O_WRONLY
-   fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY);
+   fprintf(outfile, "#define O_WRONLY    %u\n", O_WRONLY);
 #endif
 #ifdef O_RDWR
-   fprintf(outfile, "#define O_RDWR %u\n", O_RDWR);
+   fprintf(outfile, "#define O_RDWR      %u\n", O_RDWR);
+#endif
+#ifdef O_CREAT
+   fprintf(outfile, "#define O_CREAT     0x%06x  /* 0%08o */\n", O_CREAT, O_CREAT);
+#endif
+#ifdef O_EXCL
+   fprintf(outfile, "#define O_EXCL      0x%06x  /* 0%08o */\n", O_EXCL, O_EXCL);
+#endif
+#ifdef O_NOCTTY
+   fprintf(outfile, "#define O_NOCTTY    0x%06x  /* 0%08o */\n", O_NOCTTY, O_NOCTTY);
+#endif
+#ifdef O_TRUNC
+   fprintf(outfile, "#define O_TRUNC     0x%06x  /* 0%08o */\n", O_TRUNC, O_TRUNC);
+#endif
+#ifdef O_APPEND
+   fprintf(outfile, "#define O_APPEND    0x%06x  /* 0%08o */\n", O_APPEND, O_APPEND);
+#endif
+#ifdef O_NONBLOCK
+   fprintf(outfile, "#define O_NONBLOCK  0x%06x  /* 0%08o */\n", O_NONBLOCK, O_NONBLOCK);
+#endif
+#ifdef O_NDELAY
+   fprintf(outfile, "#define O_NDELAY    0x%06x  /* 0%08o */\n", O_NDELAY, O_NDELAY);
+#endif
+#ifdef O_SYNC
+   fprintf(outfile, "#define O_SYNC      0x%06x  /* 0%08o */\n", O_SYNC, O_SYNC);
+#endif
+#ifdef O_FSYNC
+   fprintf(outfile, "#define O_FSYNC     0x%06x  /* 0%08o */\n", O_FSYNC, O_FSYNC);
+#endif
+#ifdef O_LARGEFILE
+   fprintf(outfile, "#define O_LARGEFILE 0x%06x  /* 0%08o */\n", O_LARGEFILE, O_LARGEFILE);
+#endif
+#ifdef O_DIRECTORY
+   fprintf(outfile, "#define O_DIRECTORY 0x%06x  /* 0%08o */\n", O_DIRECTORY, O_DIRECTORY);
+#endif
+#ifdef O_NOFOLLOW
+   fprintf(outfile, "#define O_NOFOLLOW  0x%06x  /* 0%08o */\n", O_NOFOLLOW, O_NOFOLLOW);
+#endif
+#ifdef O_CLOEXEC
+   fprintf(outfile, "#define O_CLOEXEC   0x%06x  /* 0%08o */\n", O_CLOEXEC, O_CLOEXEC);
+#endif
+#ifdef O_DIRECT
+   fprintf(outfile, "#define O_DIRECT    0x%06x  /* 0%08o */\n", O_DIRECT, O_DIRECT);
+#endif
+#ifdef O_NOATIME
+   fprintf(outfile, "#define O_NOATIME   0x%06x  /* 0%08o */\n", O_NOATIME, O_NOATIME);
+#endif
+#ifdef O_PATH
+   fprintf(outfile, "#define O_PATH      0x%06x  /* 0%08o */\n", O_PATH, O_PATH);
+#endif
+#ifdef O_DSYNC
+   fprintf(outfile, "#define O_DSYNC     0x%06x  /* 0%08o */\n", O_SYNC, O_SYNC);
+#endif
+#ifdef O_TMPFILE
+   fprintf(outfile, "#define O_TMPFILE   0x%06x  /* 0%08o */\n", O_TMPFILE, O_TMPFILE);
 #endif
 #ifdef SHUT_RD
-   fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD);
+   fprintf(outfile, "#define SHUT_RD     %u\n", SHUT_RD);
 #endif
 #ifdef SHUT_WR
-   fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR);
+   fprintf(outfile, "#define SHUT_WR     %u\n", SHUT_WR);
 #endif
 #ifdef SHUT_RDWR
-   fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR);
+   fprintf(outfile, "#define SHUT_RDWR   %u\n", SHUT_RDWR);
 #endif
 
    /* Compile time controls */
@@ -51,40 +112,40 @@ int procan_cdefs(FILE *outfile) {
 
    /* termios constants */
 #ifdef CRDLY
-   fprintf(outfile, "#define CRDLY 0%011o\n", CRDLY);
+   fprintf(outfile, "#define CRDLY       0x%08x  /* 0%011o */\n", CRDLY, CRDLY);
 #endif
 #ifdef CR0
-   fprintf(outfile, "#define CR0 0%011o\n", CR0);
+   fprintf(outfile, "#define CR0         0x%08x  /* 0%011o */\n", CR0, CR0);
 #endif
 #ifdef CR1
-   fprintf(outfile, "#define CR1 0%011o\n", CR1);
+   fprintf(outfile, "#define CR1         0x%08x  /* 0%011o */\n", CR1, CR1);
 #endif
 #ifdef CR2
-   fprintf(outfile, "#define CR2 0%011o\n", CR2);
+   fprintf(outfile, "#define CR2         0x%08x  /* 0%011o */\n", CR2, CR2);
 #endif
 #ifdef CR3
-   fprintf(outfile, "#define CR3 0%011o\n", CR3);
+   fprintf(outfile, "#define CR3         0x%08x  /* 0%011o */\n", CR3, CR3);
 #endif
 #ifdef TABDLY
-   fprintf(outfile, "#define TABDLY 0%011o\n", TABDLY);
+   fprintf(outfile, "#define TABDLY      0x%08x  /* 0%011o */\n", TABDLY, TABDLY);
 #endif
 #ifdef TAB0
-   fprintf(outfile, "#define TAB0 0%011o\n", TAB0);
+   fprintf(outfile, "#define TAB0        0x%08x  /* 0%011o */\n", TAB0, TAB0);
 #endif
 #ifdef TAB1
-   fprintf(outfile, "#define TAB1 0%011o\n", TAB1);
+   fprintf(outfile, "#define TAB1        0x%08x  /* 0%011o */\n", TAB1, TAB1);
 #endif
 #ifdef TAB2
-   fprintf(outfile, "#define TAB2 0%011o\n", TAB2);
+   fprintf(outfile, "#define TAB2        0x%08x  /* 0%011o */\n", TAB2, TAB2);
 #endif
 #ifdef TAB3
-   fprintf(outfile, "#define TAB3 0%011o\n", TAB3);
+   fprintf(outfile, "#define TAB3        0x%08x  /* 0%011o */\n", TAB3, TAB3);
 #endif
 #ifdef CSIZE
-   fprintf(outfile, "#define CSIZE 0%011o\n", CSIZE);
+   fprintf(outfile, "#define CSIZE       0x%08x  /* 0%011o */\n", CSIZE, CSIZE);
 #endif
 #ifdef TIOCEXCL
-   fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL);
+   fprintf(outfile, "#define TIOCEXCL    0x%lx\n", (unsigned long)TIOCEXCL);
 #endif
 
    /* stdio constants */
@@ -188,5 +249,78 @@ int procan_cdefs(FILE *outfile) {
 #ifdef TCP_MAXSEG
    fprintf(outfile, "#define TCP_MAXSEG %d\n",   TCP_MAXSEG);
 #endif
+#ifdef AI_PASSIVE
+   fprintf(outfile, "#define AI_PASSIVE     0x%02x\n", AI_PASSIVE);
+#endif
+#ifdef AI_CANONNAME
+   fprintf(outfile, "#define AI_CANONNAME   0x%02x\n", AI_CANONNAME);
+#endif
+#ifdef AI_NUMERICHOST
+   fprintf(outfile, "#define AI_NUMERICHOST 0x%02x\n", AI_NUMERICHOST);
+#endif
+#ifdef AI_V4MAPPED
+   fprintf(outfile, "#define AI_V4MAPPED    0x%02x\n", AI_V4MAPPED);
+#endif
+#ifdef AI_ALL
+   fprintf(outfile, "#define AI_ALL         0x%02x\n", AI_ALL);
+#endif
+#ifdef AI_ADDRCONFIG
+   fprintf(outfile, "#define AI_ADDRCONFIG  0x%02x\n", AI_ADDRCONFIG);
+#endif
+#ifdef EAI_BADFLAGS
+   fprintf(outfile, "#define EAI_BADFLAGS    %d\n", EAI_BADFLAGS);
+#endif
+#ifdef EAI_NONAME
+   fprintf(outfile, "#define EAI_NONAME      %d\n", EAI_NONAME);
+#endif
+#ifdef EAI_AGAIN
+   fprintf(outfile, "#define EAI_AGAIN       %d\n", EAI_AGAIN);
+#endif
+#ifdef EAI_FAIL
+   fprintf(outfile, "#define EAI_FAIL        %d\n", EAI_FAIL);
+#endif
+#ifdef EAI_FAMILY
+   fprintf(outfile, "#define EAI_FAMILY      %d\n", EAI_FAMILY);
+#endif
+#ifdef EAI_SOCKTYPE
+   fprintf(outfile, "#define EAI_SOCKTYPE    %d\n", EAI_SOCKTYPE);
+#endif
+#ifdef EAI_SERVICE
+   fprintf(outfile, "#define EAI_SERVICE     %d\n", EAI_SERVICE);
+#endif
+#ifdef EAI_MEMORY
+   fprintf(outfile, "#define EAI_MEMORY      %d\n", EAI_MEMORY);
+#endif
+#ifdef EAI_SYSTEM
+   fprintf(outfile, "#define EAI_SYSTEM      %d\n", EAI_SYSTEM);
+#endif
+#ifdef EAI_OVERFLOW
+   fprintf(outfile, "#define EAI_OVERFLOW    %d\n", EAI_OVERFLOW);
+#endif
+#ifdef EAI_NODATA
+   fprintf(outfile, "#define EAI_NODATA      %d\n", EAI_NODATA);
+#endif
+#ifdef EAI_ADDRFAMILY
+   fprintf(outfile, "#define EAI_ADDRFAMILY  %d\n", EAI_ADDRFAMILY);
+#endif
+#ifdef EAI_INPROGRESS
+   fprintf(outfile, "#define EAI_INPROGRESS  %d\n", EAI_INPROGRESS);
+#endif
+#ifdef EAI_CANCELED
+   fprintf(outfile, "#define EAI_CANCELED    %d\n", EAI_CANCELED);
+#endif
+#ifdef EAI_NOTCANCELED
+   fprintf(outfile, "#define EAI_NOTCANCELED %d\n", EAI_NOTCANCELED);
+#endif
+#ifdef EAI_ALLDONE
+   fprintf(outfile, "#define EAI_ALLDONE     %d\n", EAI_ALLDONE);
+#endif
+#ifdef EAI_INTR
+   fprintf(outfile, "#define EAI_INTR        %d\n", EAI_INTR);
+#endif
+#ifdef EAI_IDN_ENCODE
+   fprintf(outfile, "#define EAI_IDN_ENCODE  %d\n", EAI_IDN_ENCODE);
+#endif
+
    return 0;
 }
diff --git a/procan.c b/procan.c
index 22dd5e4..f51751c 100644
--- a/procan.c
+++ b/procan.c
@@ -187,10 +187,30 @@ int procan(FILE *outfile) {
    fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2));
 
    /* process owner, groups */
+#if HAVE_GETRESUID
+   {
+      uid_t ruid, euid, suid;
+      getresuid(&ruid, &euid, &suid);
+      fprintf(outfile, "user id  = "F_uid"\n", ruid);
+      fprintf(outfile, "effective user id  = "F_uid"\n", euid);
+      fprintf(outfile, "saved set-user id  = "F_uid"\n", suid);
+   }
+#else /* !HAVE_GETRESUID */
    fprintf(outfile, "user id  = "F_uid"\n", Getuid());
    fprintf(outfile, "effective user id  = "F_uid"\n", Geteuid());
+#endif /* !HAVE_GETRESUID */
+#if HAVE_GETRESGID
+   {
+      gid_t rgid, egid, sgid;
+      getresgid(&rgid, &egid, &sgid);
+      fprintf(outfile, "group id = "F_gid"\n", rgid);
+      fprintf(outfile, "effective group id = "F_gid"\n", egid);
+      fprintf(outfile, "saved set-group id = "F_gid"\n", sgid);
+   }
+#else /* !HAVE_GETRESGID */
    fprintf(outfile, "group id = "F_gid"\n", Getgid());
    fprintf(outfile, "effective group id = "F_gid"\n", Getegid());
+#endif /* !HAVE_GETRESGID */
 
    /* Simple process features */
    fprintf(outfile, "\n");
diff --git a/procan_main.c b/procan_main.c
index 7f70402..18b33de 100644
--- a/procan_main.c
+++ b/procan_main.c
@@ -13,6 +13,9 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r
 #if HAVE_SYS_SELECT_H
 #include <sys/select.h>	/* select(), fdset on FreeBSD */
 #endif
+#if HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>	/* uname(), struct utsname */
+#endif
 #include "mytypes.h"
 #include "error.h"
 #include "procan.h"
@@ -22,6 +25,13 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r
 #define WITH_HELP 1
 
 static void procan_usage(FILE *fd);
+static void procan_version(FILE *fd);
+
+const char copyright_procan[] = "procan by Gerhard Rieger and contributors - see www.dest-unreach.org";
+static const char procanversion[] =
+#include "./VERSION"
+      ;
+static const char timestamp[] = BUILD_DATE;
 
 
 int main(int argc, const char *argv[]) {
@@ -39,8 +49,8 @@ int main(int argc, const char *argv[]) {
       case '?': case 'h': procan_usage(stdout); exit(0);
 #endif /* WITH_HELP */
       case 'c': procan_cdefs(stdout); exit(0);
-#if LATER
       case 'V': procan_version(stdout); exit(0);
+#if LATER
       case 'l': diag_set(arg1[0][2], &arg1[0][3]); break;
       case 'd': diag_set('d', NULL); break;
 #endif
@@ -80,9 +90,7 @@ static void procan_usage(FILE *fd) {
    fputs("Usage:\n", fd);
    fputs("procan [options]\n", fd);
    fputs("   options:\n", fd);
-#if LATER
    fputs("      -V     print version information to stdout, and exit\n", fd);
-#endif
 #if WITH_HELP
    fputs("      -?|-h  print a help text describing command line options\n", fd);
 #endif
@@ -100,3 +108,17 @@ static void procan_usage(FILE *fd) {
 #endif
 }
 #endif /* WITH_HELP */
+
+
+void procan_version(
+	FILE *fd)
+{
+   struct utsname ubuf;
+
+   fputs(copyright_procan, fd); fputc('\n', fd);
+   fprintf(fd, "procan version %s on %s\n", procanversion, timestamp);
+   uname(&ubuf);
+   fprintf(fd, "   running on %s version %s, release %s, machine %s\n",
+	   ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine);
+   return;
+}
diff --git a/readline-test.sh b/readline-test.sh
index 26f392f..569bde6 100755
--- a/readline-test.sh
+++ b/readline-test.sh
@@ -36,7 +36,7 @@ $ECHO
 
 if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then
     $ECHO "Authentication failed" >&2
-    exit -1
+    exit 1
 fi
 
 while $ECHO "$PROMPT\c"; read -r COMMAND; do
diff --git a/readline.sh b/readline.sh
index 1045303..2f08c04 100755
--- a/readline.sh
+++ b/readline.sh
@@ -4,15 +4,19 @@
 # Published under the GNU General Public License V.2, see file COPYING
 
 # this is an attempt for a socat based readline wrapper
-# usage: readline.sh <command>
+# usage: readline.sh [options] <program>
 
 withhistfile=1
 
+STDERR=
 while true; do
     case "X$1" in
-    X-nh|X-nohist*) withhistfile=; shift; continue ;;
-    *) break;;
+	X-lf?*) STDERR="${1:3}" ;;
+	X-lf) shift; STDERR="$1" ;;
+	X-nh|X-nohist*) withhistfile= ;;
+	*) break;;
     esac
+    shift
 done
 
 PROGRAM="$@"
@@ -25,12 +29,18 @@ fi
 #
 #
 
-if test -w .; then
+#if test -w .; then
+if [ -z "$STDERR" ] && find . -maxdepth 0 -user $USER ! -perm /022 -print |grep ^ >/dev/null; then
+    # When cwd is owned by $USER and it is neither group nor world writable
     STDERR=./socat-readline.${1##*/}.log
     rm -f $STDERR
-else
+    echo "$0: logs go to $STDERR" >&2
+elif [ -z "$STDERR" ]; then
+    echo "$0: insecure working directory, no logs are written" >&2
     STDERR=/dev/null
+else
+    echo "$0: logs go to $STDERR" >&2
 fi
 
-exec socat -d readline"$HISTOPT",noecho='[Pp]assword:' exec:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR
+exec socat -d READLINE"$HISTOPT",noecho='[Pp]assword:' EXEC:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR
 
diff --git a/socat-broker.sh b/socat-broker.sh
index ccdea6f..b4b6dd2 100755
--- a/socat-broker.sh
+++ b/socat-broker.sh
@@ -37,6 +37,7 @@ while [ "$1" ]; do
 	X-q) QUIET=1; OPTS="-d0" ;;
 	X-d*|X-l?*) OPTS="$OPTS $1" ;;
 	X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;;
+	X--experimental) ;;
 	X-) break ;;
 	X-*) echo "Unknown option \"$1\"" >&2
 	     usage >&2
diff --git a/socat-chain.sh b/socat-chain.sh
index fa8e93e..357aff0 100755
--- a/socat-chain.sh
+++ b/socat-chain.sh
@@ -77,6 +77,7 @@ while [ "$1" ]; do
 	X-q) QUIET=1; OPTS="-d0" ;;
 	X-d*|X-l?*) OPTS="$OPTS $1" ;;
 	X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;;
+	X--experimental) ;;
 	X-) break ;;
 	X-*) echo "$0: Unknown option \"$1\"" >&2
 	     usage >&2
diff --git a/socat-mux.sh b/socat-mux.sh
index 084c0e6..204cd89 100755
--- a/socat-mux.sh
+++ b/socat-mux.sh
@@ -2,7 +2,7 @@
 # Copyright Gerhard Rieger and contributors (see file CHANGES)
 # Published under the GNU General Public License V.2, see file COPYING
 
-# Shell script to build a many-to-one, one-to-all communication
+# Shell script to establish many-to-one, one-to-all communications.
 # It starts two Socat instances that communicate via IPv4 broadcast,
 # the first of which forks a child process for each connected client.
 
@@ -43,6 +43,7 @@ while [ "$1" ]; do
 	X-q) QUIET=1; OPTS="-d0" ;;
 	X-d*|X-l?*) OPTS="$OPTS $1" ;;
 	X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;;
+	X--experimental) ;;
 	X-) break ;;
 	X-*) echo "$0: Unknown option \"$1\"" >&2
 	     usage >&2
diff --git a/socat.c b/socat.c
index cf1685d..3e9cc91 100644
--- a/socat.c
+++ b/socat.c
@@ -282,6 +282,8 @@ int main(int argc, const char *argv[]) {
 	    socat_opts.total_timeout.tv_usec =
 	       (rto-socat_opts.total_timeout.tv_sec) * 1000000;
 	 }
+	 xioparms.total_timeout.tv_sec  = socat_opts.total_timeout.tv_sec;
+	 xioparms.total_timeout.tv_usec = socat_opts.total_timeout.tv_usec;
 	 break;
       case 'u':  if (arg1[0][2])  { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); }
 	 socat_opts.lefttoright = true; break;
@@ -783,7 +785,7 @@ int socat(const char *address1, const char *address2) {
       int i;
       for (i = 0; i < NUMUNKNOWN; ++i) {
 	 if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown[i]) {
-	    /* child has alread died... but it might have put regular data into
+	    /* Child has already died... but it might have put regular data into
 	       the communication channel, so continue */
 	    Info2("child "F_pid" has already died with status %d",
 		  XIO_RDSTREAM(sock1)->para.exec.pid, statunknown[i]);
@@ -826,7 +828,7 @@ int socat(const char *address1, const char *address2) {
       int i;
       for (i = 0; i < NUMUNKNOWN; ++i) {
 	 if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown[i]) {
-	    /* child has alread died... but it might have put regular data into
+	    /* Child has already died... but it might have put regular data into
 	       the communication channel, so continue */
 	    Info2("child "F_pid" has already died with status %d",
 		  XIO_RDSTREAM(sock2)->para.exec.pid, statunknown[i]);
@@ -863,11 +865,12 @@ int childleftdata(xiofile_t *xfd) {
        XIO_RDSTREAM(xfd)->para.exec.pid == 0) {
       struct timeval timeout = { 0, 0 };
 
-      if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) {
-	 in.fd = XIO_GETRDFD(xfd);
-	 in.events = POLLIN/*|POLLRDBAND*/;
-	 in.revents = 0;
-      }
+      if (XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)
+	 return 0;
+
+      in.fd = XIO_GETRDFD(xfd);
+      in.events = POLLIN/*|POLLRDBAND*/;
+      in.revents = 0;
       do {
 	 int _errno;
 	 retval = xiopoll(&in, 1, &timeout);
@@ -875,7 +878,7 @@ int childleftdata(xiofile_t *xfd) {
       } while (retval < 0 && errno == EINTR);
 
       if (retval < 0) {
-	 Error5("xiopoll({%d,%0o}, 1, {"F_tv_sec"."F_tv_usec"}): %s",
+	 Error5("xiopoll({%d,0%o}, 1, {"F_tv_sec"."F_tv_usec"}): %s",
 		in.fd, in.events, timeout.tv_sec, timeout.tv_usec,
 		strerror(errno));
 	 return -1;
@@ -1013,7 +1016,7 @@ int _socat(void) {
       /* for ignoreeof */
       if (polling) {
 	 if (!wasaction) {
-	    if (socat_opts.total_timeout.tv_usec <= 1000000) {
+	    if (socat_opts.total_timeout.tv_usec < 1000000) {
 	       if (total_timeout.tv_usec < socat_opts.pollintv.tv_usec) {
 		  total_timeout.tv_usec += 1000000;
 		  total_timeout.tv_sec  -= 1;
@@ -1131,7 +1134,7 @@ int _socat(void) {
 	 */
 
       if (retval < 0) {
-	 Error11("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, {"F_tv_sec"."F_tv_usec"}): %s",
+	 Error11("xiopoll({%d,0%o}{%d,0%o}{%d,0%o}{%d,0%o}, 4, {"F_tv_sec"."F_tv_usec"}): %s",
 		 fds[0].fd, fds[0].events, fds[1].fd, fds[1].events,
 		 fds[2].fd, fds[2].events, fds[3].fd, fds[3].events,
 		 timeout.tv_sec, timeout.tv_usec, strerror(errno));
@@ -1336,7 +1339,6 @@ int _socat(void) {
    should be at least MAXTIMESTAMPLEN bytes long.
    returns 0 on success or -1 if an error occurred */
 int gettimestamp(char *timestamp) {
-   size_t bytes;
 #if HAVE_CLOCK_GETTIME
    struct timespec now;
 #elif HAVE_PROTOTYPE_LIB_gettimeofday
@@ -1364,17 +1366,16 @@ int gettimestamp(char *timestamp) {
    }
 #endif
 #if HAVE_STRFTIME
-   bytes = strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt));
+   strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt));
 #if HAVE_CLOCK_GETTIME
-   bytes += sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000);
+   sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000);
 #elif HAVE_PROTOTYPE_LIB_gettimeofday
-   bytes += sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec);
+   sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec);
 #else
    strncpy(&timestamp[bytes++], " ", 2);
 #endif
 #else
    strcpy(timestamp, ctime(&nowt));
-   bytes = strlen(timestamp);
 #endif
    return 0;
 }
diff --git a/socat.spec b/socat.spec
index 3d2b7a1..55e1d70 100644
--- a/socat.spec
+++ b/socat.spec
@@ -1,6 +1,6 @@
 
 %define majorver 1.8
-%define minorver 0.2
+%define minorver 0.3
 
 Summary: socat - multipurpose relay
 Name: socat
diff --git a/socks4a-echo.sh b/socks4a-echo.sh
index 7360366..91d255a 100755
--- a/socks4a-echo.sh
+++ b/socks4a-echo.sh
@@ -37,7 +37,7 @@ esac
 if   [ $(echo "x\c") = "x" ]; then E=""
 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
 else
-    echo "cannot suppress trailing newline on echo" >&2
+    echo "$0: cannot suppress trailing newline on echo" >&2
     exit 1
 fi
 ECHO="echo $E"
@@ -58,7 +58,7 @@ else
 fi
 if [ "$vn" != $($ECHO "\04") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks version requested" >&2
+    echo "$0 invalid socks version requested" >&2
     exit
 fi
 
@@ -69,7 +69,7 @@ else
 fi
 if [ "$cd" != $($ECHO "\01") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks operation requested" >&2
+    echo "$0: invalid socks operation requested" >&2
     exit
 fi
 
@@ -82,7 +82,7 @@ a=$(dd bs=1 count=6 2>/dev/null)
 if [ "$a" != "$($ECHO "}m\0\0\0\01")" ]; then
     sleep 1
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks address or port requested" >&2
+    echo "$0: wrong socks address or port requested" >&2
     exit
 fi
 
@@ -93,7 +93,7 @@ else
 fi
 if [ "$u" != "nobody" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks user requested" >&2
+    echo "$0: wrong socks user requested" >&2
     exit
 fi
 
@@ -104,7 +104,7 @@ else
 fi
 if [ "$h" != "localhost" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks address requested" >&2
+    echo "$0: wrong socks address requested" >&2
     exit
 fi
 
diff --git a/socks4echo.sh b/socks4echo.sh
index 48ea536..44c631a 100755
--- a/socks4echo.sh
+++ b/socks4echo.sh
@@ -9,6 +9,7 @@
 # it is required for test.sh
 # for TCP, use this script as:
 # socat tcp-l:1080,reuseaddr,crlf system:"socks4echo.sh"
+# Then connect with a socks4 request for 32.98.76.54:32109 and user nobody
 
 # older bash and ksh do not have -n option to read command; we try dd then
 #if echo a |read -n 1 null >/dev/null 2>&1; then
@@ -36,7 +37,7 @@ esac
 if   [ $(echo "x\c") = "x" ]; then E=""
 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
 else
-    echo "cannot suppress trailing newline on echo" >&2
+    echo "$0: cannot suppress trailing newline on echo" >&2
     exit 1
 fi
 ECHO="echo $E"
@@ -57,7 +58,7 @@ else
 fi
 if [ "$vn" != $($ECHO "\04") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks version requested" >&2
+    echo "$0: invalid socks version requested" >&2
     exit
 fi
 
@@ -68,7 +69,7 @@ else
 fi
 if [ "$cd" != $($ECHO "\01") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks operation requested" >&2
+    echo "$0: invalid socks operation requested" >&2
     exit
 fi
 
@@ -91,7 +92,7 @@ else
 fi
 if [ "$u" != "nobody" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks user requested (expected \"nobody\")" >&2
+    echo "$0: wrong socks user requested (expected \"nobody\")" >&2
     exit
 fi
 
diff --git a/socks5server-echo.sh b/socks5server-echo.sh
new file mode 100755
index 0000000..04e562a
--- /dev/null
+++ b/socks5server-echo.sh
@@ -0,0 +1,67 @@
+#! /usr/bin/env bash
+# Source: socks5connect-echo.sh
+
+# Copyright Gerhard Rieger and contributors (see file CHANGES)
+# Published under the GNU General Public License V.2, see file COPYING
+
+# Performs primitive simulation of a socks5 server with echo function via stdio.
+# Accepts and answers SOCKS5 CONNECT request without authentication to
+# 8.8.8.8:80, however is does not connect there but just echoes data.
+# It is required for test.sh
+# For TCP, use this script as:
+# socat TCP-L:1080,reuseaddr EXEC:"socks5connect-echo.sh"
+
+#set -vx
+
+if [ "$SOCAT" ]; then
+    :
+elif type socat >/dev/null 2>&1; then
+    SOCAT=socat
+else
+    SOCAT=./socat
+fi
+
+case `uname` in
+HP-UX|OSF1)
+    CAT="$SOCAT -u STDIN STDOUT"
+    ;;
+*)
+    CAT=cat
+    ;;
+esac
+
+A="7f000001"
+P="0050"
+
+# Read and parse SOCKS5 greeting
+read _ v b c _ <<<"$($SOCAT -u -,readbytes=3 - |od -t x1)"
+#echo "$v $b $c" >&2
+if [ "$v" != 05 ]; then echo "$0: Packet1: expected version x05, got \"$v\"" >&2; exit 1; fi
+if [ "$b" != 01 ]; then echo "$0: Packet1: expected 01 auth methods, got \"$b\"" >&2; exit 1; fi
+if [ "$c" != 00 ]; then echo "$0: Packet1: expected auth method 00, got \"$c\"" >&2; exit 1; fi
+# Send answer
+echo -en "\x05\x00"
+
+# Read and parse SOCKS5 connect request
+read _ v b c d a1 a2 a3 a4 p1 p2 _ <<<"$($SOCAT -u -,readbytes=10 - |od -t x1)"
+#echo "$v $b $c $d $a1 $a2 $a3 $a4 $p1 $p2" >&2
+a="$a1$a2$a3$a4"
+p="$p1$p2"
+if [ "$v" != 05 ];   then echo "$0: Packet2: expected version x05, got \"$v\"" >&2; exit 1; fi
+if [ "$b" != 01 ] && [ "$b" != 02 ];   then echo "$0: Packet2: expected connect request 01 or bind request 02, got \"$b\"" >&2; exit 1; fi
+if [ "$c" != 00 ];   then echo "$0: Packet2: expected reserved 00, got \"$c\"" >&2; exit 1; fi
+if [ "$d" != 01 ];   then echo "$0: Packet2: expected address type 01, got \"$d\"" >&2; exit 1; fi
+if [ "$a" != "$A" ]; then echo "$0: Packet2: expected address $A, got \"$a\"" >&2; exit 1; fi
+if [ "$p" != "$P" ]; then echo "$0: Packet2: expected port $P, got \"$p\"" >&2; exit 1; fi
+if [ "$z" != "" ];   then echo "$0: Packet2: trailing data \"$z\"" >&2; exit 1; fi
+# Send answer
+echo -en "\x05\x00\x00\x01\x10\x00\x1f\x64\x1f\x64"
+
+# Bind/listen/passive mode
+if [ "$b" == 02 ]; then
+    sleep 1 	# pretend to be waiting for connection
+    echo -en "\x05\x00\x00\x01\x10\xff\x1f\x64\x23\x28"
+fi
+
+# perform echo function
+$CAT
diff --git a/sslcls.c b/sslcls.c
index 4e29d71..700b2a3 100644
--- a/sslcls.c
+++ b/sslcls.c
@@ -368,6 +368,7 @@ int sycSSL_connect(SSL *ssl) {
    int result;
    Debug1("SSL_connect(%p)", ssl);
    result = SSL_connect(ssl);
+   if (!diag_in_handler) diag_flush();
    Debug1("SSL_connect() -> %d", result);
    return result;
 }
diff --git a/sycls.c b/sycls.c
index 900cee3..3eb0058 100644
--- a/sycls.c
+++ b/sycls.c
@@ -1421,11 +1421,11 @@ unsigned int Sleep(unsigned int seconds) {
 #if HAVE_NANOSLEEP
 unsigned int Nanosleep(const struct timespec *req, struct timespec *rem) {
    int retval, _errno;
-   Debug3("nanosleep({"F_time",%ld},%p)", req->tv_sec, req->tv_nsec, rem);
+   Debug3("nanosleep({"F_time".%09ld}, %p)", req->tv_sec, req->tv_nsec, rem);
    retval = nanosleep(req, rem);
    _errno = errno;
    if (rem) {
-      Debug3("nanosleep(,{"F_time",%ld}) -> %d",
+      Debug3("nanosleep(,{"F_time".%09ld}) -> %d",
 	     rem->tv_sec, rem->tv_nsec, retval);
    } else {
       Debug1("nanosleep() -> %d", retval);
@@ -1513,6 +1513,9 @@ void *Malloc(size_t size) {
       Error1("malloc("F_Zd"): out of memory", size);
       return NULL;
    }
+#if WITH_DEVTESTS
+   memset(result, 0x55, size);
+#endif /* WITH_DEVTESTS */
    return result;
 }
 
@@ -1540,6 +1543,18 @@ void *Realloc(void *ptr, size_t size) {
    return result;
 }
 
+/* Like Realloc(), but gets info about old size for overwrite test */
+void *Realloc3(void *ptr, size_t size, size_t oldsize) {
+   void *result = Realloc(ptr, size);
+   if (result == NULL)
+      return result;
+#if WITH_DEVTESTS
+   if (size > oldsize)
+      memset(result+oldsize, 0x55, size-oldsize);
+#endif /* WITH_DEVTESTS */
+   return result;
+}
+
 #if _WITH_TERMIOS
 int Tcgetattr(int fd, struct termios *termios_p) {
    int i, result, _errno;
diff --git a/sycls.h b/sycls.h
index 8f8ded5..fe9bb70 100644
--- a/sycls.h
+++ b/sycls.h
@@ -148,6 +148,7 @@ struct hostent *Getipnodebyname(const char *name, int af, int flags,
 void *Malloc(size_t size);
 void *Calloc(size_t nmemb, size_t size);
 void *Realloc(void *ptr, size_t size);
+void *Realloc3(void *ptr, size_t size, size_t oldsize);
 int Tcgetattr(int fd, struct termios *termios_p);
 int Tcsetattr(int fd, int optional_actions, struct termios *termios_p);
 char *Ttyname(int fd);
@@ -257,6 +258,7 @@ void Add_history(const char *string);
 #define Malloc(s) malloc(s)
 #define Calloc(n,s) calloc(n,s)
 #define Realloc(p,s) realloc(p,s)
+#define Realloc3(p,s,o) realloc(p,s)
 #define Tcgetattr(f,t) tcgetattr(f,t)
 #define Tcsetattr(f,o,t) tcsetattr(f,o,t)
 #define Ttyname(f) ttyname(f)
diff --git a/sysincludes.h b/sysincludes.h
index f51e368..a8e60be 100644
--- a/sysincludes.h
+++ b/sysincludes.h
@@ -150,6 +150,9 @@
 #if HAVE_LINUX_IF_TUN_H
 #include <linux/if_tun.h>
 #endif
+#if HAVE_NETINET_DCCP_H
+#include <netinet/dccp.h>
+#endif
 #if HAVE_LINUX_DCCP_H
 #include <linux/dccp.h>
 #endif
@@ -182,7 +185,7 @@
 #if WITH_NAMESPACES && HAVE_SCHED_H
 #include <sched.h>
 #endif
-#if WITH_POSIXMQ
+#if WITH_POSIXMQ && HAVE_MQUEUE_H
 #include <mqueue.h> 		/* POSIX MQ */
 #endif
 #if WITH_READLINE
diff --git a/sysutils.c b/sysutils.c
index ee24454..f25531a 100644
--- a/sysutils.c
+++ b/sysutils.c
@@ -27,9 +27,22 @@ const int one = 1;
    Returns <0 on unhandled error, errno valid
    Will only return <0 or bytes
 */
-ssize_t writefull(int fd, const void *buff, size_t bytes) {
+/* Assuming your pipe size is 65536 - find out with:
+   filan -i 1 |grep F_GETPIPE_SZ |sed 's|.*\(F_GETPIPE_SZ=[1-9][0-9]*\).*|\1|'
+   Then we can test partial write with something like:
+   socat -d4 -lu -b 262144 -u /dev/zero,readbytes=262144 -,o-nonblock |{ sleep 3; wc -c; }
+*/
+ssize_t writefull(
+	int fd,
+	const void *buff,
+	size_t bytes,
+	const struct timeval *tmo0) {
    size_t writt = 0;
    ssize_t chk;
+   struct pollfd pfd;
+   struct timeval tmo = { 0 };
+   int rc;
+
    while (1) {
       chk = Write(fd, (const char *)buff + writt, bytes - writt);
       if (chk < 0) {
@@ -40,15 +53,34 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) {
 	 case EWOULDBLOCK:
 #endif
 	    Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno));
-	    Sleep(1); continue;
-	 default: return -1;
+	    pfd.fd      = fd;
+	    pfd.events  = POLLOUT;
+	    pfd.revents = 0;
+	    if (tmo0 != NULL) {
+	       tmo.tv_sec  = tmo0->tv_sec;
+	       tmo.tv_usec = tmo0->tv_usec;
+	    }
+	    rc = xiopoll(&pfd, 1, (tmo.tv_sec!=0 || tmo.tv_usec!=0) ? &tmo : NULL);
+	    if (rc == 0) {
+	       Notice("inactivity timeout triggered");
+	       errno = ETIMEDOUT;
+	       return -1;
+	    }
+	    continue;
+	 default:
+	    return -1;
 	 }
+      } else if (chk == bytes) {
+	 /* First attempt, complete write */
+	 return chk;
       } else if (writt+chk < bytes) {
-	 Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (rev.direction is blocked)",
+	 Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (meanwhile, other direction is blocked)",
 	       fd, (const char *)buff+writt, bytes-writt, chk);
 	 writt += chk;
-      } else {
-	 writt = bytes;
+      } else if (writt == 0) {
+	 /* First attempt, write complete - no extra message */
+	 return chk;
+      } else { 	/* write completed */
 	 break;
       }
    }
@@ -548,7 +580,7 @@ int getusergroups(const char *user, gid_t *list, int *ngroups) {
    /* we prefer getgrouplist because it may be much faster with many groups, but it is not standard */
    gid_t grp, twogrps[2];
    int two = 2;
-   /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an abitrary supplementary group id that we then pass in a second call to getgrouplist. */
+   /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an arbitrary supplementary group id that we then pass in a second call to getgrouplist. */
    grp = 0;
    Getgrouplist(user, grp, twogrps, &two);
    if (two == 1) {
@@ -677,7 +709,7 @@ int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout) {
 }
 
 
-#if WITH_TCP || WITH_UDP
+#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE
 /* returns port in network byte order;
    ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as
    TCP */
@@ -702,10 +734,10 @@ int parseport(const char *portname, int ipproto) {
 
    return se->s_port;
 }
-#endif /* WITH_TCP || WITH_UDP */
+#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */
 
 
-#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE
+#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE
 /* check the systems interfaces for ifname and return its index
    or -1 if no interface with this name was found
    The system calls require an arbitrary socket; the calling program may
@@ -729,8 +761,8 @@ int ifindexbyname(const char *ifname, int anysock) {
    }
    if (anysock >= 0) {
       s = anysock;
-   } else  if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
-      Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno));
+   } else  if ((s = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+      Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno));
       return -1;
    }
 
@@ -756,10 +788,10 @@ int ifindexbyname(const char *ifname, int anysock) {
    return -1;
 #endif /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */
 }
-#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */
+#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */
 
 
-#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE
+#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE
 /* like ifindexbyname(), but also allows the index number as input - in this
    case it does not lookup the index.
    writes the resulting index to *ifindex and returns 0,
@@ -783,7 +815,7 @@ int ifindex(const char *ifname, unsigned int *ifindex, int anysock) {
    *ifindex = val;
    return 0;
 }
-#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */
+#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */
 
 
 int _xiosetenv(const char *envname, const char *value, int overwrite, const char *sep) {
diff --git a/sysutils.h b/sysutils.h
index 5e8ae10..cfdff04 100644
--- a/sysutils.h
+++ b/sysutils.h
@@ -47,7 +47,7 @@ struct xiorange {
 extern const int one;
 #endif
 
-extern ssize_t writefull(int fd, const void *buff, size_t bytes);
+extern ssize_t writefull(int fd, const void *buff, size_t bytes, const struct timeval *tmo0);
 
 #if _WITH_SOCKET
 extern socklen_t socket_init(int af, union sockaddr_union *sa);
diff --git a/test.sh b/test.sh
index 5204ac7..62df2e8 100755
--- a/test.sh
+++ b/test.sh
@@ -39,7 +39,7 @@ usage() {
     $ECHO "Usage: $0 <options> [<test-spec> ...]"
     $ECHO "options:"
     $ECHO "\t-h \t\tShow this help"
-    $ECHO "\t-t <sec> \tBase for timeouts in seconds, default: 0.1"
+    $ECHO "\t-t <sec> \tBase for timeouts in seconds, default is automatically determined"
     $ECHO "\t-v \t\tBe more verbose, show failed commands"
     $ECHO "\t-n <num> \tOnly perform test with given number"
     $ECHO "\t-N <num> \tOnly perform tests starting with given number"
@@ -48,6 +48,7 @@ usage() {
     $ECHO "\t-d \t\tShow log output of commands, even when they did not fail (not yet completed)"
     $ECHO "\t-D \t\tOutput some platform/system specific defines (variables)"
     $ECHO "\t--internet \tAllow tests that send packets to Internet"
+    $ECHO "\t--experimental \tApply --experimental option to Socat"
     $ECHO "\t--expect-fail N1,N2,... \tIgnore failure of these tests"
     $ECHO "\ttest-spec \Number of test or name of test"
     $ECHO "Contents of environment variable OPTS are passed to Socat invocations, e.'g:"
@@ -65,6 +66,7 @@ VERBOSE=
 DEBUG=
 DEFS=
 INTERNET=
+EXPERIMENTAL=
 OPT_EXPECT_FAIL= EXPECT_FAIL=
 while [ "$1" ]; do
     case "X$1" in
@@ -78,8 +80,9 @@ while [ "$1" ]; do
 	X-n)   shift; NUMCOND="test \$N -eq $1" ;;
 	X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;;
 	X-N)   shift; NUMCOND="test \$N -ge $1" ;;
-	X-C)   rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;;
+	X-C)   rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* testalt.* ;;
 	X--internet|X-internet)	INTERNET=1 ;; 	# allow access to 3rd party Internet hosts
+	X--experimental) 	EXPERIMENTAL=1 ;;
 	X--expect-fail|X-expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;;
 	X-*)   echo "Unknown option \"$1\"" >&2
                usage >&2
@@ -90,9 +93,12 @@ while [ "$1" ]; do
 done
 debug=$DEBUG
 
+# Applying patch 1.8.0.3 to 1.8.0.2 generates this non executably
+[ -f ./socks5server-echo.sh ] && chmod a+x ./socks5server-echo.sh
+  
 [ "$DEFS" ] && echo "BASH_VERSION=\"$BASH_VERSION\"" >&2
 
-[ "$DEFS" ] && echo "ECHO_E=\"$ECHO_E\"" >&2
+[ "$DEFS" ] && echo "ECHO=\"$ECHO\"" >&2
 
 UNAME=`uname`
 [ "$DEFS" ] && echo "UNAME=\"$UNAME\"" >&2
@@ -109,6 +115,24 @@ MICROS=${S}${uS}
 MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0}
 # changed below again
 
+divide_uint_by_1000000 () {
+    x=$1
+    if [ ${#x} -ge 7 ]; then
+	echo ${x%??????}.${x: -6};
+    else
+	y=000000$x;
+	f=${y: -6};
+	echo 0.$f;
+    fi
+}
+
+
+# output the value in seconds for n * val_t
+relsecs () {
+    local n="$1"
+    divide_uint_by_1000000 $((n*MICROS))
+}
+
 _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}"
 [ -z "$SECONDs" ] && SECONDs=0
 [ "$DEFS" ] && echo "SECONDs=\"$SECONDs\"" >&2
@@ -129,21 +153,22 @@ if [ -z "$PROCAN" ]; then if test -x ./procan; then PROCAN="./procan"; elif type
 if [ -z "$FILAN" ]; then if test -x ./filan; then FILAN="./filan"; elif ! type filan >/dev/null 2>&1; then FILAN=filan; elif test -x ${SOCAT%/*}/filan; then FILAN=${SOCAT%/*}/filan; else FILAN=false; fi; fi
 [ "$DEFS" ] && echo "FILAN=\"$FILAN\"" >&2
 
+if ! sleep 0.1 2>/dev/null; then
+    sleep () {
+	$SOCAT -T "$1" PIPE PIPE
+    }
+fi
+
 if [ -z "$val_t" ]; then
-    # Determine the time Socat needs for an empty run
+    # Estimate the time Socat needs for an empty run
+    sleep 0.5 	# immediately after build the first runs are extremely fast
     $SOCAT /dev/null /dev/null 	# populate caches
-    MILLIs=$(bash -c 'time socat /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.)
+    MILLIs=$(bash -c "time for _ in {1..3}; do $SOCAT -d0 $opts /dev/null /dev/null; done" 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.)
     while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done 	# strip leading '0' to avoid octal
     [ -z "$MILLIs" ] && MILLIs=1
-    [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2
-
-    # On my idle development computer this value flaps from 0.001 to 0.004
-    # 0.001 lets many tests fail, so we triple the result
-    MILLIs=$((3*MILLIs))
-    [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (2)" >&2
+    [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\"" >&2
     MICROS=${MILLIs}000
 
-    #set -vx
     case $MICROS in
 	???????*) val_t=${MICROS%??????}.${MICROS: -6} ;;
 	*)        x=000000$MICROS; val_t=0.${x: -6} ;;
@@ -183,7 +208,7 @@ PATH=$PATH:/sbin 	# RHEL6:ip
 case "$0" in
     */*) PATH="${0%/*}:$PATH"
 esac
-PATH=.:$PATH 	# for usleep,relsleep
+PATH=.:$PATH 	# for relsleep
 [ "$DEFS" ] && echo "PATH=\"$PATH\"" >&2
 
 #OPENSSL_RAND="-rand /dev/egd-pool"
@@ -191,6 +216,13 @@ PATH=.:$PATH 	# for usleep,relsleep
 MISCDELAY=1
 
 OPTS="$opt_t $OPTS"
+
+if [ "$EXPERIMENTAL" ]; then
+    if $SOCAT -h |grep -e --experimental >/dev/null; then
+	OPTS="$OPTS --experimental"
+    fi
+fi
+
 opts="$OPTS"
 [ "$DEFS" ] && echo "opts=\"$opts\"" >&2
 
@@ -230,12 +262,12 @@ fi
 
 # for some tests we need a network interface
 if type ip >/dev/null 2>&1; then
-    INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/")
+    INTERFACE=$(ip r get 9.9.9.9 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/")
 else
     case "$UNAME" in
 	Linux)
 	    if [ "$IP" ]; then
-		INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')"
+		INTERFACE="$($IP route get 9.9.9.9 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')"
 	    else
 		INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')"
 	    fi ;;
@@ -267,7 +299,7 @@ FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print
 [ "$DEFS" ] && echo "FOPEN_MAX=\"$FOPEN_MAX\"" >&2
 PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)"
 [ "$DEFS" ] && echo "PF_INET6=\"$PF_INET6\"" >&2
-TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)"
+TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |{ read _ _ v; echo "$v"; })"
 [ "$DEFS" ] && echo "TIOCEXCL=\"$TIOCEXCL\"" >&2
 SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)"
 [ "$DEFS" ] && echo "SOL_SOCKET=\"$SOL_SOCKET\"" >&2
@@ -280,89 +312,6 @@ SIZE_T=$($PROCAN |grep "^[^[:space:]]*size_t" |awk '{print($3);}')
 #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi
 #[ "$DEFS" ] && echo "AI_ADDRCONFIG=\"$AI_ADDRCONFIG\"" >&2
 
-# SSL certificate contents
-TESTCERT_CONF=testcert.conf
-TESTCERT6_CONF=testcert6.conf
-TESTALT_CONF=testalt.conf
-#
-TESTCERT_COMMONNAME="$LOCALHOST"
-TESTCERT_COMMONNAME6="$LOCALHOST6"
-TESTCERT_COUNTRYNAME="XY"
-TESTCERT_LOCALITYNAME="Lunar Base"
-TESTCERT_ORGANIZATIONALUNITNAME="socat"
-TESTCERT_ORGANIZATIONNAME="dest-unreach"
-TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
-TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
-RSABITS=2048 	# Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536
-DSABITS=2048
-cat >$TESTCERT_CONF <<EOF
-prompt=no
-
-[ req ]
-default_bits = $RSABITS
-distinguished_name=Test
-
-[ Test ]
-countryName=$TESTCERT_COUNTRYNAME
-commonName=$TESTCERT_COMMONNAME
-O=$TESTCERT_ORGANIZATIONNAME
-OU=$TESTCERT_ORGANIZATIONALUNITNAME
-L=$TESTCERT_LOCALITYNAME
-
-EOF
-
-cat >$TESTCERT6_CONF <<EOF
-prompt=no
-
-[ req ]
-default_bits = $RESBITS
-distinguished_name=Test
-
-[ Test ]
-countryName=$TESTCERT_COUNTRYNAME
-commonName=$TESTCERT_COMMONNAME6
-O=$TESTCERT_ORGANIZATIONNAME
-OU=$TESTCERT_ORGANIZATIONALUNITNAME
-L=$TESTCERT_LOCALITYNAME
-
-EOF
-
-cat >$TESTALT_CONF <<EOF
-# config for generation of self signed certificate with IP addresses in
-# SubjectAltNames
-prompt=no
-
-[ req ]
-default_bits       = $RSABITS
-distinguished_name = subject
-x509_extensions    = x509_ext
-
-[ subject ]
-countryName=$TESTCERT_COUNTRYNAME
-commonName=servername
-O=$TESTCERT_ORGANIZATIONNAME
-OU=$TESTCERT_ORGANIZATIONALUNITNAME
-L=$TESTCERT_LOCALITYNAME
-
-[ x509_ext ]
-subjectAltName     = @alternate_names
-
-[ alternate_names ]
-DNS.1 = localhost
-DNS.2 = localhost4
-DNS.3 = localhost6
-IP.1  = 127.0.0.1
-IP.2  = ::1
-
-EOF
-
-# clean up from previous runs
-rm -f testcli.{crt,key,pem}
-rm -f testsrv.{crt,key,pem}
-rm -f testcli6.{crt,key,pem}
-rm -f testsrv6.{crt,key,pem}
-rm -f testalt.{crt,key,pem}
-
 CAT="cat"
 OD_C="od -c"
 
@@ -380,47 +329,6 @@ tolower () {
     esac
 }
 
-if ! which usleep >/dev/null 2>&1; then
-cat >usleep <<EOF
-#! /usr/bin/env bash
-# temporary script from Socat test.sh:
-# sleep for a number of µs
-u=\$1
-l=\${#u}
-i=0
-[ "\$l" -gt 6 ] && i=\${u%??????}
-u0=000000\$u
-s=\${i}.\${u0: -6:6};
-#echo \$s
-sleep \$s
-EOF
-chmod a+x usleep
-fi
-
-# precision sleep; takes seconds with fractional part; sleep does this on all test platforms
-if false; then
-psleep () {
-    local T="$1"
-    [ "$T" = 0 ] && T=0.000002
-    #$SOCAT -T "$T" PIPE PIPE 2>/dev/null
-    sleep "$T"
-}
-# time in microseconds to wait in some situations
-if ! type usleep >/dev/null 2>&1 ||
-       usleep 0 2>&1 |grep -q deprecated; then
-    usleep () {
-	local n="$1"
-	case "$n" in
-	*???????) S="${n%??????}"; uS="${n:${#n}-6}" ;;
-	*) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;;
-	esac
-	#$SOCAT -T "$S.$uS" PIPE PIPE 2>/dev/null
-	sleep "$S.$uS"
-    }
-fi
-#USLEEP=usleep
-fi
-
 # calculate the time i*MICROS, output as float number for us with -t
 reltime () {
     local n="$1"
@@ -433,11 +341,12 @@ reltime () {
     echo "$S.$uS"
 }
 
-# A sleep with configurable clocking ($vat_t)
+# A sleep with configurable clocking ($val_t)
 # val_t should be at least the time that a Socat invocation, no action, and
 # termination takes
 relsleep () {
-    usleep $(($1*MICROS))
+    #sleep $(($1*MICROS/1000000))
+    sleep $(divide_uint_by_1000000 $(($1*MICROS)) )
 }
 
 cat >relsleep <<-'EOF'
@@ -543,7 +452,7 @@ fi
 
 # need output like "644"
 case "$UNAME" in
-    Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;;
+    #Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;;
     FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;;
     *) fileperms() {
 	    local p s=0 c
@@ -583,7 +492,7 @@ if2bc4() {
 case "$UNAME" in
 Linux)
   if [ "$IP" ]; then
-    BROADCASTIF=$($IP r get 8.8.8.8 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/')
+    BROADCASTIF=$($IP r get 9.9.9.9 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/')
   else
     BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}')
   fi
@@ -657,20 +566,12 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256col
 		RED="\0033[31m"
 		GREEN="\0033[32m"
 		YELLOW="\0033[33m"
-#		if [ "$UNAME" = SunOS ]; then
-#		    NORMAL="\0033[30m"
-#		else
-		    NORMAL="\0033[39m"
-#		fi
-	else
+		NORMAL="\0033[39m"
+	else 	# "\101"
 		RED="\033[31m"
 		GREEN="\033[32m"
 		YELLOW="\033[33m"
-#		if [ "$UNAME" = SunOS ]; then
-#		    NORMAL="\033[30m"
-#		else
-		    NORMAL="\033[39m"
-#		fi
+		NORMAL="\033[39m"
 	fi
 	OK="${GREEN}OK${NORMAL}"
 	FAILED="${RED}FAILED${NORMAL}"
@@ -689,42 +590,6 @@ if [ -x /usr/xpg4/bin/id ]; then
     PATH="/usr/xpg4/bin:$PATH"
 fi
 
-OPENSSL_S_CLIENT_4=
-OPENSSL_S_CLIENT_DTLS=
-init_openssl_s_client () {
-    if openssl s_client -help 2>&1 |grep -q ' -4 '; then
-	OPENSSL_S_CLIENT_4="-4"
-    else
-	OPENSSL_S_CLIENT_4=" "
-    fi
-    if openssl s_client -help 2>&1 | grep -q ' -dtls '; then
-	OPENSSL_S_CLIENT_DTLS=-dtls
-    else
-	OPENSSL_S_CLIENT_DTLS=-dtls1
-    fi
-}
-
-OPENSSL_S_SERVER_4=
-OPENSSL_S_SERVER_DTLS=
-OPENSSL_S_SERVER_NO_IGN_EOF=
-init_openssl_s_server () {
-    if openssl s_server -help 2>&1 |grep -q ' -4 '; then
-	OPENSSL_S_SERVER_4="-4"
-    else
-	OPENSSL_S_SERVER_4=" "
-    fi
-    if openssl s_server -help 2>&1 | grep -q ' -dtls '; then
-	OPENSSL_S_SERVER_DTLS="-dtls"
-    else
-	OPENSSL_S_SERVER_DTLS="-dtls1"
-    fi
-    if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then
-	OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof"
-    else
-	OPENSSL_S_SERVER_NO_IGN_EOF=" "
-    fi
-}
-
 
 [ -z "$TESTS" ] && TESTS="consistency functions filan"
 # use '%' as separation char
@@ -744,6 +609,8 @@ mkdir -p "$TD"
 
 echo "Using temp directory $TD"
 
+RESULTS="$TD/results.txt" 	# file for list of results
+
 case "$TESTS" in
 *%consistency%*)
 # test if addresses are sorted alphabetically:
@@ -752,7 +619,7 @@ TF="$TD/socat-q"
 IFS="$($ECHO ' \n\t')"
 if ! $SOCAT -hhh >/dev/null; then
     echo "Failed: $SOCAT -hhh" >&2
-    exit -1
+    exit 2
 fi
 $SOCAT -hhh |sed -n '/^   address-head:/,/^   opts:/ p' |grep -v -e "^   address-head:" -e "^   opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF"
 $SOCAT -hhh |sed -n '/^   address-head:/,/^   opts:/ p' |grep -v -e "^   address-head:" -e "^   opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' |LC_ALL=C sort |diff "$TF" - >"$TF-diff"
@@ -785,6 +652,63 @@ fi
 /bin/rm "$TF-diff"
 esac
 
+case "$TESTS" in
+*%consistency%*)
+    # Test if help shows option types without inconsistency
+    $ECHO "testing if help shows option types correctly...\c"
+    TF="$TD/socat-hhh"
+    LINE="$($SOCAT -hhh |grep "^[[:space:]]*ip-add-source-membership\>")"
+    if [ -z "$LINE" ]; then
+	$ECHO $CANT
+    else
+	TYPE="$($ECHO "$LINE" |sed 's/^.*type=\([^[:space:]][^[:space:]]*\).*/\1/')"
+	if [ "$TYPE" != "IP-MREQ-SOURCE" ]; then
+	    $ECHO "\n*** help does not show option types correctly" >&2
+	    exit 1
+	else
+	    echo " ok"
+	fi
+    fi
+esac
+
+case "$TESTS" in
+*%consistency%*)
+    # Test if help shows option phases without inconsistency
+    $ECHO "testing if help shows option phases correctly...\c"
+    TF="$TD/socat-hhh"
+    LINE="$($SOCAT -hhh |grep "^[[:space:]]*dash\>")"
+    if [ -z "$LINE" ]; then
+	$ECHO $CANT
+    else
+	PHASE="$($ECHO "$LINE" |sed 's/^.*phase=\([^[:space:]][^[:space:]]*\).*/\1/')"
+	if [ "$PHASE" != "PREEXEC" ]; then
+	    $ECHO "\n*** help does not show option phases correctly" >&2
+	    exit 1
+	else
+	    echo " ok"
+	fi
+    fi
+esac
+
+case "$TESTS" in
+*%consistency%*)
+    # Test if help shows option groups without inconsistency
+    $ECHO "testing if help shows option groups correctly...\c"
+    TF="$TD/socat-hhh"
+    LINE="$($SOCAT -hhh |grep "^[[:space:]]*udplite-recv-cscov\>")"
+    if [ -z "$LINE" ]; then
+	$ECHO $CANT
+    else
+	GROUP="$($ECHO "$LINE" |sed 's/^.*groups=\([^[:space:]][^[:space:]]*\).*/\1/')"
+	if [ "$GROUP" != "UDPLITE" ]; then
+	    $ECHO "\n*** help does not show option groups correctly" >&2
+	    exit 1
+	else
+	    echo " ok"
+	fi
+    fi
+esac
+
 #==============================================================================
 
 N=1
@@ -794,18 +718,41 @@ numCANT=0
 listOK=
 listFAIL=
 listCANT=
-namesFAIL=
+
+ok () {
+    numOK=$((numOK+1))
+    listOK="$listOK $N"
+    do_result OK
+}
+
+cant () {
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+    do_result CANT
+}
+
+failed () {
+    numFAIL=$((numFAIL+1))
+    listFAIL="$listFAIL $N"
+    do_result FAILED
+}
+
+do_result () {
+    #echo "RESULTS=\"$RESULTS\"" >&2; exit
+    echo "$N $NAME $1" >>$RESULTS
+}
 
 #==============================================================================
 # test if selected socat features work ("FUNCTIONS")
 
 testecho () {
     local N="$1"
-    local title="$2"
-    local arg1="$3";	[ -z "$arg1" ] && arg1="-"
-    local arg2="$4";	[ -z "$arg2" ] && arg2="echo"
-    local opts="$5"
-    local T="$6";	[ -z "$T" ] && T=0 	# fractional seconds
+    local NAME="$2"
+    local title="$3"
+    local arg1="$4";	[ -z "$arg1" ] && arg1="-"
+    local arg2="$5";	[ -z "$arg2" ] && arg2="echo"
+    local opts="$6"
+    local T="$7";	[ -z "$T" ] && T=0 	# fractional seconds
     local tf="$td/test$N.stdout"
     local te="$td/test$N.stderr"
     local tdiff="$td/test$N.diff"
@@ -817,7 +764,7 @@ testecho () {
     #echo "$da" |$cmd >"$tf" 2>"$te"
     { sleep $T; echo "$da"; sleep $T; } | { $TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc"; } &
     pid1=$!
-    #sleep 5 && kill $rc1 2>/dev/null &
+    #sleep 5 && kill $pid1 2>/dev/null &
 #    rc2=$!
     wait $pid1
 #    kill $rc2 2>/dev/null
@@ -825,22 +772,19 @@ testecho () {
 	$PRINTF "$FAILED: $TRACE $SOCAT:\n"
 	echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
 	cat "$te" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$SOCAT $opts $arg1 $arg2" >&2; fi
 	if [ -n "$debug" ]; then cat $te >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     else
 	$PRINTF "$FAILED:\n"
 	echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
 	cat "$te" >&2
 	echo diff: >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     fi
     fi # NUMCOND
 }
@@ -849,11 +793,12 @@ testecho () {
 # flush of od buffers
 testod () {
     local num="$1"
-    local title="$2"
-    local arg1="$3";	[ -z "$arg1" ] && arg1="-"
-    local arg2="$4";	[ -z "$arg2" ] && arg2="echo"
-    local opts="$5"
-    local T="$6";	[ -z "$T" ] && T=0 	# fractional seconds
+    local NAME="$2"
+    local title="$3"
+    local arg1="$4";	[ -z "$arg1" ] && arg1="-"
+    local arg2="$5";	[ -z "$arg2" ] && arg2="echo"
+    local opts="$6"
+    local T="$7";	[ -z "$T" ] && T=0 	# fractional seconds
     local tf="$td/test$N.stdout"
     local te="$td/test$N.stderr"
     local tr="$td/test$N.ref"
@@ -868,25 +813,36 @@ testod () {
 	$PRINTF "$FAILED: $TRACE $SOCAT:\n"
 	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $num"
+	failed
 #    elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then
     elif diff "$tr" "$tf" >"$tdiff" 2>&1; then
 	$PRINTF "$OK\n"
 	if [ -n "$debug" ]; then cat $te; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     else
 	$PRINTF "$FAILED: diff:\n"
 	echo "$TRACE $SOCAT $opts $arg1 $arg2"
 	cat "$te"
 	cat "$tdiff"
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $num"
+	failed
     fi
     fi # NUMCOND
 }
 
+# bash before version 3 aborts scripts that contain unquoted '=~'
+# Therefore we create a shell script and quotedly fill it with '=~' for newer
+# bashes [regexp regular expressions]
+mkdir -p $td/bin
+rm -f $td/bin/re_match
+if [ "${BASH_VERSION%%[.]*}" -le 2 ]; then
+    echo '[ -n "$(echo "$1" |sed -n "/$2/ p")" ]' >$td/bin/re_match
+else
+    echo '[[ "$1" =~ $2 ]]' >$td/bin/re_match
+fi
+chmod a+x $td/bin/re_match
+PATH=$PATH:$td/bin
+
+
 # test if the socat executable has these features compiled in
 # print the first missing address type
 testfeats () {
@@ -904,7 +860,8 @@ testfeats () {
 	    fi
 	fi
 	if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then
-	    if [[ "$A" =~ OPENSSL.* ]]; then
+#	    if [[ "$A" =~ OPENSSL.* ]]; then
+	    if re_match "$A" "OPENSSL.*"; then
 		gentestcert testsrv
 		gentestcert testcli
 	    fi
@@ -955,6 +912,10 @@ testoptions () {
 # if not: prints ev.message to stderr, returns 1
 childprocess () {
     local l
+    case "$1" in
+	[1-9]*) ;;
+	*) echo "childprocess \"$1\": not a number" >&2; exit 2 ;;
+    esac
     case "$UNAME" in
     AIX)     l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;;
     FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;;
@@ -978,6 +939,10 @@ childprocess () {
 childpids () {
     local recursive i
     if [ "X$1" = "X-r" ]; then recursive=1; shift; fi
+    case "$1" in
+	[1-9]*) ;;
+	*) echo "childpids \"$1\": not a number" >&2; exit 2 ;;
+    esac
     case "$UNAME" in
     AIX)     l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;;
     FreeBSD) l="$(ps -fl   |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
@@ -1053,7 +1018,7 @@ runsip4 () {
     CYGWIN*) l=$(ipconfig |grep IPv4);;
     *)     l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
     esac
-    [ -z "$l" ] && return 1    
+    [ -z "$l" ] && return 1
     # existence of interface might not suffice, check for routeability:
     case "$UNAME" in
     Darwin) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;;
@@ -1076,9 +1041,9 @@ runsip6 () {
     AIX)   l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;;
     HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;;
     Linux) if [ "$IP" ]; then
-	       l=$($IP address |$GREP_E 'inet6 ::1/128')
+	       l="$($IP address |$GREP_E 'inet6 ::1/128')"
 	   else
-	       l=$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?')
+	       l="$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?')"
 	   fi ;;
     NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1\>');;
     OSF1)  l=$($IFCONFIG -a |grep ' inet6 ') ;;
@@ -1087,7 +1052,7 @@ runsip6 () {
     CYGWIN*) l=$(ipconfig |grep IPv6);;
     *)     l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
     esac
-    [ -z "$l" ] && return 1    
+    [ -z "$l" ] && return 1
     # existence of interface might not suffice, check for routeability:
     case "$UNAME" in
     Darwin) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;;
@@ -1183,11 +1148,146 @@ runsunix () {
 
 routesip6 () {
     runsip6 >/dev/null || { echo route6; return 1; }
-    ping -c 1 -s 0 -6 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; }
+    $PING6 -c 1 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; }
     return 0;
 }
 
 
+# SSL needs runsip6(), thus moved down
+
+# SSL certificate contents
+TESTCERT_CONF=testcert.conf
+TESTCERT6_CONF=testcert6.conf
+TESTALT_CONF=testalt.conf
+#
+TESTCERT_COMMONNAME="$LOCALHOST"
+TESTCERT_COMMONNAME6="$LOCALHOST6"
+TESTCERT_COUNTRYNAME="XY"
+TESTCERT_LOCALITYNAME="Lunar Base"
+TESTCERT_ORGANIZATIONALUNITNAME="socat"
+TESTCERT_ORGANIZATIONNAME="dest-unreach"
+TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
+TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
+RSABITS=2048 	# Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536
+DSABITS=2048
+cat >$TESTCERT_CONF <<EOF
+prompt=no
+
+[ req ]
+default_bits = $RSABITS
+distinguished_name=Test
+
+[ Test ]
+countryName=$TESTCERT_COUNTRYNAME
+commonName=$TESTCERT_COMMONNAME
+O=$TESTCERT_ORGANIZATIONNAME
+OU=$TESTCERT_ORGANIZATIONALUNITNAME
+L=$TESTCERT_LOCALITYNAME
+
+EOF
+
+cat >$TESTCERT6_CONF <<EOF
+prompt=no
+
+[ req ]
+default_bits = $RESBITS
+distinguished_name=Test
+
+[ Test ]
+countryName=$TESTCERT_COUNTRYNAME
+commonName=$TESTCERT_COMMONNAME6
+O=$TESTCERT_ORGANIZATIONNAME
+OU=$TESTCERT_ORGANIZATIONALUNITNAME
+L=$TESTCERT_LOCALITYNAME
+
+EOF
+
+cat >$TESTALT_CONF <<EOF
+# config for generation of self signed certificate with IP addresses in
+# SubjectAltNames
+prompt=no
+
+[ req ]
+default_bits       = $RSABITS
+distinguished_name = subject
+x509_extensions    = x509_ext
+
+[ subject ]
+countryName=$TESTCERT_COUNTRYNAME
+commonName=servername
+O=$TESTCERT_ORGANIZATIONNAME
+OU=$TESTCERT_ORGANIZATIONALUNITNAME
+L=$TESTCERT_LOCALITYNAME
+
+[ x509_ext ]
+subjectAltName     = @alternate_names
+
+[ alternate_names ]
+DNS.1 = localhost
+DNS.2 = localhost4
+DNS.3 = localhost6
+IP.1  = 127.0.0.1
+EOF
+
+if runsip6; then
+   cat >>$TESTALT_CONF <<EOF
+IP.2  = ::1
+EOF
+fi
+
+
+# clean up from previous runs
+rm -f testcli.{crt,key,pem}
+rm -f testsrv.{crt,key,pem}
+rm -f testcli6.{crt,key,pem}
+rm -f testsrv6.{crt,key,pem}
+rm -f testalt.{crt,key,pem}
+
+OPENSSL_S_CLIENT_4=
+OPENSSL_S_CLIENT_DTLS=
+init_openssl_s_client () {
+    if openssl s_client -help 2>&1 |grep -q ' -4 '; then
+	OPENSSL_S_CLIENT_4="-4"
+    else
+	OPENSSL_S_CLIENT_4=" "
+    fi
+    if openssl s_client -help 2>&1 | grep -q ' -dtls1_2 '; then
+	OPENSSL_S_CLIENT_DTLS="-dtls1_2"
+    elif openssl s_client -help 2>&1 | grep -q ' -dtls1 '; then
+	OPENSSL_S_CLIENT_DTLS="-dtls1"
+    elif openssl s_client -help 2>&1 | grep -q ' -dtls '; then
+	OPENSSL_S_CLIENT_DTLS="-dtls"
+    else
+	OPENSSL_S_CLIENT_DTLS=
+    fi
+}
+
+OPENSSL_S_SERVER_4=
+OPENSSL_S_SERVER_DTLS=
+OPENSSL_S_SERVER_NO_IGN_EOF=
+init_openssl_s_server () {
+    if openssl s_server -help 2>&1 |grep -q ' -4 '; then
+	OPENSSL_S_SERVER_4="-4"
+    else
+	OPENSSL_S_SERVER_4=" "
+    fi
+    if openssl s_server -help 2>&1 | grep -q ' -dtls1_2 '; then
+	OPENSSL_S_SERVER_DTLS="-dtls1_2"
+    elif openssl s_server -help 2>&1 | grep -q ' -dtls1 '; then
+	OPENSSL_S_SERVER_DTLS="-dtls1"
+    elif openssl s_server -help 2>&1 | grep -q ' -dtls '; then
+	OPENSSL_S_SERVER_DTLS="-dtls"
+    else
+	OPENSSL_S_SERVER_DTLS=
+    fi
+    if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then
+	OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof"
+    else
+	OPENSSL_S_SERVER_NO_IGN_EOF=" "
+    fi
+}
+
+
 # Perform a couple of checks to make sure the test has a chance of a useful
 # result:
 # platform is supported, features compiled in, addresses and options
@@ -1215,13 +1315,6 @@ checkconds() {
 	[ "$i" ] && { echo "Only on (one of) $unames"; return 255; }
     fi
 
-    if [ "$root" = "root" ]; then
-	if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
-	    echo "Must be root"
-	    return 255
-	fi
-    fi
-
     if [ "$progs" ]; then
 	for i in $progs; do
 	    if ! type  >/dev/null 2>&1; then
@@ -1262,11 +1355,20 @@ checkconds() {
     fi
 
     if [ "$inet" ]; then
-	if [ -z "$NTERNET" ]; then
+	if [ -z "$INTERNET" ]; then
 	    echo "Use test.sh option --internet"
 	    return 255
 	fi
     fi
+
+    # Only at the end, so we get a better overview of missing features
+    if [ "$root" = "root" ]; then
+	if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
+	    echo "Must be root"
+	    return 255
+	fi
+    fi
+
     return 0
 }
 
@@ -1298,7 +1400,7 @@ waitip4proto () {
 #	SunOS)   l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;;
 #	HP-UX)   l=$(netstat -an |grep '^raw        0      0  .*[0-9*]\.'$proto' .* \*\.\* ') ;;
 #	OSF1)    l=$(/usr/sbin/netstat -an |grep '^raw        0      0  .*[0-9*]\.'$proto' [ ]*\*\.\*') ;;
- 	*)       #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;;
+	*)       #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;;
 		 relsleep 5;  return 0 ;;
 	esac
 	[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
@@ -1391,6 +1493,24 @@ checktcpport () {
     return 1
 }
 
+waittcpport () {
+    local port="$1"
+    local logic="$2" 	# 0..wait until free; 1..wait until listening (default)
+    local timeout="$3"
+    while true; do
+#echo "timeout=\"$timeout\"" >&2
+	if [ "$logic" = 0 ]; then
+	    if checktcpport $1; then break; fi
+	else
+	    if ! checktcpport $1; then break; fi
+	fi
+	if [ $timeout -le 0 ]; then return 1; fi
+	sleep 1
+	let --timeout;
+    done
+    return 0;
+}
+
 checktcp4port () {
     checktcpport $1
 }
@@ -1423,7 +1543,7 @@ waittcp4port () {
 	OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp        0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
 	CYGWIN*) l=$(netstat -an -p TCP |grep '^  TCP    [0-9.]*:'$port' .* LISTENING') ;;
 	DragonFly)  l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
- 	*)       l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;;
+	*)       l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1504,7 +1624,7 @@ waitudp4port () {
 	HP-UX)   l=$(netstat -an |grep '^udp        0      0  .*[0-9*]\.'$port' .* \*\.\* ') ;;
 	OSF1)    l=$(/usr/sbin/netstat -an |grep '^udp        0      0  .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
 	DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
- 	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
+	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1565,7 +1685,7 @@ waitsctp4port () {
     while [ $timeout -gt 0 ]; do
 	case "$UNAME" in
 	Linux) if [ "$SS" ]; then
-		   l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>")
+		   l=$($SS -4 -a -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>")
 	       else
 		   l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN')
 	       fi ;;
@@ -1580,7 +1700,7 @@ waitsctp4port () {
 #	HP-UX)   l=$(netstat -an |grep '^tcp        0      0  .*[0-9*]\.'$port' .* LISTEN$') ;;
 #	OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp        0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
 #	CYGWIN*) l=$(netstat -an -p TCP |grep '^  TCP    [0-9.]*:'$port' .* LISTENING') ;;
- 	*)       l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
+	*)       l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1610,6 +1730,7 @@ waitudplite4port () {
 	    Linux) #if [ "$SS" ]; then
 		#l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
 		#else
+		# On Ubuntu-20 only netstat shows udplite ports
 		if ! netstat -nU >/dev/null 2>&1; then
                     return 0    # speculative
 		fi
@@ -1644,6 +1765,51 @@ waitudplite4port () {
     return 1
 }
 
+# wait until an DCCP4 listen port is ready
+waitdccp4port () {
+    local port="$1"
+    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
+	case "$UNAME" in
+	Linux)
+	    # On Ubuntu-20, only ss shows DCCP ports
+		if [ "$SS" ]; then
+		   l=$($SS -4 -a -n 2>/dev/null |grep "^dccp.*LISTEN .*:$port\>")
+	       else
+		   l=$(netstat -n -a |grep '^dccp .*[0-9*]:'$port' .* LISTEN')
+	       fi ;;
+#	FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
+#	NetBSD)  l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
+#	Darwin) case "$(uname -r)" in
+#		[1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
+#		*) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
+#		esac ;;
+#	AIX)	 l=$(netstat -an |grep '^tcp[^6]       0      0 .*[*0-9]\.'$port' .* LISTEN$') ;;
+	SunOS)   l=$(netstat -an -f inet -P dccp |grep '.*[1-9*]\.'$port' .*\*                0 .* LISTEN') ;;
+#	HP-UX)   l=$(netstat -an |grep '^tcp        0      0  .*[0-9*]\.'$port' .* LISTEN$') ;;
+#	OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp        0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
+#	CYGWIN*) l=$(netstat -an -p TCP |grep '^  TCP    [0-9.]*:'$port' .* LISTENING') ;;
+	*)       l=$(netstat -an |grep -i 'dccp .*[0-9*][:.]'$port' .* listen') ;;
+	esac
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
+	sleep $val_t
+	timeout=$((timeout-1))
+    done
+
+    $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
+    return 1
+}
+
 # check if a TCP6 port is in use
 # exits with 0 when it is not used
 checktcp6port () {
@@ -1675,7 +1841,7 @@ waittcp6port () {
 	SunOS)   l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
 	#OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp6       0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
 	DragonFly)  l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
- 	*)       l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;;
+	*)       l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1718,14 +1884,14 @@ waitudp6port () {
 	   fi ;;
 	FreeBSD) l=$(netstat -an |$GREP_E '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
 	NetBSD)  l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;;
-    	OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
+	OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
 	Darwin)  l=$(netstat -an |$GREP_E '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
 	AIX)	 l=$(netstat -an |grep '^udp[6 ]       0      0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
 	SunOS)   l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
 	#HP-UX)   l=$(netstat -an |grep '^udp        0      0  .*[0-9*]\.'$port' ') ;;
 	#OSF1)    l=$(/usr/sbin/netstat -an |grep '^udp6       0      0  .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
 	DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
- 	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
+	*)       l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1760,9 +1926,9 @@ waitsctp6port () {
     while [ $timeout -gt 0 ]; do
 	case "$UNAME" in
 	Linux) if [ "$SS" ]; then
-		   l=$($SS -6 -n 2>/dev/null |grep "^LISTEN .*:$port\>")
+		   l=$($SS -6 -a -n 2>/dev/null |grep "^sctp .*LISTEN .*:$port\>")
 	       else
-		   l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN')
+		   l=$(netstat -an |grep '^sctp[6 ] .* \*:'$port' .* LISTEN')
 	       fi ;;
 #	FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;;
 #	NetBSD)  l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
@@ -1770,7 +1936,7 @@ waitsctp6port () {
 #	AIX)	 l=$(netstat -an |grep '^tcp[6 ]       0      0 .*[*0-9]\.'$port' .* LISTEN$') ;;
 	SunOS)   l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
 #	#OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp6       0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
- 	*)       l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
+	*)       l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
 	esac
 	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
 	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
@@ -1831,6 +1997,45 @@ waitudplite6port () {
     return 1
 }
 
+# wait until a dccp6 listen port is ready
+# not all (Linux) variants show this in netstat
+waitdccp6port () {
+    local port="$1"
+    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
+	case "$UNAME" in
+	Linux) if [ "$SS" ]; then
+		   l=$($SS -6 -a -n 2>/dev/null |grep "^dccp .*LISTEN .*:$port\>")
+	       else
+		   l=$(netstat -an |grep '^dccp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN')
+	       fi ;;
+#	FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;;
+#	NetBSD)  l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
+#	OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
+#	AIX)	 l=$(netstat -an |grep '^tcp[6 ]       0      0 .*[*0-9]\.'$port' .* LISTEN$') ;;
+	SunOS)   l=$(netstat -an -f inet6 -P dccp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
+#	#OSF1)    l=$(/usr/sbin/netstat -an |grep '^tcp6       0      0  .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
+	*)       l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
+	esac
+	if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
+	    \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
+	    set ${vx}vx
+	    return 0
+	fi
+	sleep $val_t
+	timeout=$((timeout-1))
+    done
+
+    $ECHO "!port $port timed out! \c" >&2
+    set ${vx}vx
+    return 1
+}
+
 # we need this misleading function name for canonical reasons
 waitunixport () {
     waitfile "$1" "$2" "$3"
@@ -1874,6 +2079,26 @@ case "$UNAME" in
     *)     SOCK_SEQPACKET=5 ;;
 esac
 
+
+HAVEDNS=1
+if [ "$INTERNET" ]; then
+    # No "-s 24" on Solaris
+    if ! ping -c 1 "9.9.9.9" >/dev/null 2>&1; then
+	echo "$0: Option --internet but no connectivity" >&2
+	HAVEDNS=
+    elif type nslookup >/dev/null 2>&1; then
+	if ! nslookup server-4.dest-unreach.net. |grep '^Name:' >/dev/null 2>&1; then
+	    echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2
+	    HAVEDNS=
+	fi
+    elif type host >/dev/null 2>&1; then
+	if ! host server-4.dest-unreach.net. |grep "has address" >/dev/null 2>&1; then
+	    echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2
+	    HAVEDNS=
+	fi
+    fi
+fi
+
 # generate a test certificate and key
 gentestcert () {
     local name="$1"
@@ -1937,7 +2162,7 @@ NAME=UNISTDIO
 case "$TESTS " in
 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
 TEST="$NAME: unidirectional throughput from stdin to stdout"
-testecho "$N" "$TEST" "stdin" "stdout" "$opts -u"
+testecho "$N" "$NAME" "$TEST" "stdin" "stdout" "$opts -u"
 esac
 N=$((N+1))
 
@@ -1948,7 +2173,7 @@ NAME=UNPIPESTDIO
 case "$TESTS" in
 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
 TEST="$NAME: stdio with simple echo via internal pipe"
-testecho "$N" "$TEST" "stdio" "pipe" "$opts"
+testecho "$N" "$NAME" "$TEST" "stdio" "pipe" "$opts"
 esac
 N=$((N+1))
 
@@ -1957,7 +2182,7 @@ NAME=UNPIPESHORT
 case "$TESTS" in
 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
 TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe"
-testecho "$N" "$TEST" "-" "pipe" "$opts"
+testecho "$N" "$NAME" "$TEST" "-" "pipe" "$opts"
 esac
 N=$((N+1))
 
@@ -1965,8 +2190,8 @@ N=$((N+1))
 NAME=DUALSTDIO
 case "$TESTS" in
 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
-TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe"
-testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts"
+TEST="$NAME: split form of stdio ('stdin!!stdout') with simple echo via internal pipe"
+testecho "$N" "$NAME" "$TEST" "stdin!!stdout" "pipe" "$opts"
 esac
 N=$((N+1))
 
@@ -1974,8 +2199,8 @@ N=$((N+1))
 NAME=DUALSHORTSTDIO
 case "$TESTS" in
 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
-TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe"
-testecho "$N" "$TEST" "-!!-" "pipe" "$opts"
+TEST="$NAME: short split form of stdio ('-!!-') with simple echo via internal pipe"
+testecho "$N" "$NAME" "$TEST" "-!!-" "pipe" "$opts"
 esac
 N=$((N+1))
 
@@ -1984,7 +2209,7 @@ NAME=DUALFDS
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fd%*|*%$NAME%*)
 TEST="$NAME: file descriptors with simple echo via internal pipe"
-testecho "$N" "$TEST" "0!!1" "pipe" "$opts"
+testecho "$N" "$NAME" "$TEST" "0!!1" "pipe" "$opts"
 esac
 N=$((N+1))
 
@@ -1996,7 +2221,7 @@ TEST="$NAME: simple echo via named pipe"
 # with MacOS, this test hangs if nonblock is not used. Is an OS bug.
 tp="$td/pipe$N"
 # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?)
-testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock" "$opts"
 esac
 N=$((N+1))
 
@@ -2006,7 +2231,7 @@ case "$TESTS" in
 *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*)
 TEST="$NAME: simple echo via named pipe, specified twice"
 tp="$td/pipe$N"
-testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts"
 esac
 N=$((N+1))
 
@@ -2016,7 +2241,7 @@ case "$TESTS" in
 *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*)
 TEST="$NAME: simple echo via file"
 tf="$td/file$N"
-testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts"
 esac
 N=$((N+1))
 
@@ -2025,7 +2250,7 @@ NAME=EXECSOCKETPAIR
 case "$TESTS" in
 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
 TEST="$NAME: simple echo via exec of cat with socketpair"
-testecho "$N" "$TEST" "" "EXEC:$CAT" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT" "$opts"
 esac
 N=$((N+1))
 
@@ -2033,7 +2258,7 @@ NAME=SYSTEMSOCKETPAIR
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
 TEST="$NAME: simple echo via system() of cat with socketpair"
-testecho "$N" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t"
 esac
 N=$((N+1))
 
@@ -2042,7 +2267,7 @@ NAME=EXECPIPES
 case "$TESTS" in
 *%$N%*|*%functions%*|*%exec%*|*%pipe%*|*%$NAME%*)
 TEST="$NAME: simple echo via exec of cat with pipes"
-testecho "$N" "$TEST" "" "EXEC:$CAT,pipes" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes" "$opts"
 esac
 N=$((N+1))
 
@@ -2050,7 +2275,7 @@ NAME=SYSTEMPIPES
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: simple echo via system() of cat with pipes"
-testecho "$N" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts"
 esac
 N=$((N+1))
 
@@ -2062,10 +2287,9 @@ TEST="$NAME: simple echo via exec of cat with pseudo terminal"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
 fi
 esac
 N=$((N+1))
@@ -2077,10 +2301,9 @@ TEST="$NAME: simple echo via system() of cat with pseudo terminal"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
 fi
 esac
 N=$((N+1))
@@ -2090,7 +2313,7 @@ NAME=SYSTEMPIPESFDS
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: simple echo via system() of cat with pipes, non stdio"
-testecho "$N" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts"
 esac
 N=$((N+1))
 
@@ -2099,12 +2322,12 @@ NAME=DUALSYSTEMFDS
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
 TEST="$NAME: echo via dual system() of cat"
-testecho "$N" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t"
+testecho "$N" "$NAME" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t"
 esac
 N=$((N+1))
 
 
-# test: send EOF to exec'ed sub process, let it finish its operation, and 
+# test: send EOF to exec'ed sub process, let it finish its operation, and
 # check if the sub process returns its data before terminating.
 NAME=EXECSOCKETPAIRFLUSH
 # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data
@@ -2112,7 +2335,7 @@ NAME=EXECSOCKETPAIRFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
 TEST="$NAME: call to od via exec with socketpair"
-testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts"
+testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C" "$opts"
 esac
 N=$((N+1))
 
@@ -2120,7 +2343,7 @@ NAME=SYSTEMSOCKETPAIRFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
 TEST="$NAME: call to od via system() with socketpair"
-testod "$N" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t
+testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t
 esac
 N=$((N+1))
 
@@ -2129,7 +2352,7 @@ NAME=EXECPIPESFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%exec%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: call to od via EXEC with pipes"
-testod "$N" "$TEST" "" "EXEC:$OD_C,pipes" "$opts"
+testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C,pipes" "$opts"
 esac
 N=$((N+1))
 
@@ -2137,7 +2360,7 @@ NAME=SYSTEMPIPESFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: call to od via system() with pipes"
-testod "$N" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t"
+testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t"
 esac
 N=$((N+1))
 
@@ -2149,10 +2372,9 @@ N=$((N+1))
 #TEST="$NAME: call to od via exec with pseudo terminal"
 #if ! testfeats pty >/dev/null; then
 #    $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
-#    listCANT="$listCANT $N"
+#    cant
 #else
-#testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts"
+#testod "$N" "$NAME" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts"
 #fi
 #esac
 #N=$((N+1))
@@ -2165,10 +2387,9 @@ N=$((N+1))
 #TEST="$NAME: call to od via system() with pseudo terminal"
 #if ! testfeats pty >/dev/null; then
 #    $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
-#    listCANT="$listCANT $N"
+#    cant
 #else
-#testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts"
+#testod "$N" "$NAME" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts"
 #fi
 #esac
 #N=$((N+1))
@@ -2178,7 +2399,7 @@ NAME=SYSTEMPIPESFDSFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: call to od via system() with pipes, non stdio"
-testod "$N" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t"
+testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t"
 esac
 N=$((N+1))
 
@@ -2186,7 +2407,7 @@ NAME=DUALSYSTEMFDSFLUSH
 case "$TESTS" in
 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
 TEST="$NAME: call to od via dual system()"
-testod "$N" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t"
+testod "$N" "$NAME" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t"
 esac
 N=$((N+1))
 
@@ -2198,18 +2419,15 @@ TEST="$NAME: simple echo via self receiving raw IPv4 protocol"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats rawip) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts"
 fi
 esac
 N=$((N+1))
@@ -2221,18 +2439,15 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats rawip) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts"
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -2244,18 +2459,15 @@ TEST="$NAME: simple echo via self receiving raw IPv6 protocol"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts"
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -2267,25 +2479,23 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts"
 fi
 esac
 N=$((N+1))
 
 newport() {
-     _PORT=$((_PORT+1))
+    _PORT=$((_PORT+1))
      while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done
+     #while ! eval check${1}port $_PORT 2>/dev/null; do sleep 1; _PORT=$((_PORT+1)); done
      #echo "PORT=$_PORT" >&2
      PORT=$_PORT
 }
@@ -2297,12 +2507,11 @@ TEST="$NAME: echo via self connection of TCP IPv4 socket"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     newport tcp4 	# provide free port number in $PORT
     #ts="127.0.0.1:$tsl"
-    testecho "$N" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts"
 fi
 esac
 N=$((N+1))
@@ -2315,11 +2524,10 @@ case "$TESTS" in
 TEST="$NAME: echo via self connection of UDP IPv4 socket"
 if [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     newport udp4 	# provide free port number in $PORT
-    testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts"
 fi
 esac
 fi # NUMCOND
@@ -2333,16 +2541,14 @@ TEST="$NAME: echo via self connection of UDP IPv6 socket"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats udp ip6 >/dev/null || ! runsudp6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/file$N"
     newport udp6 	# provide free port number in $PORT
-    testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts"
+    testecho "$N" "$NAME" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts"
 fi
 esac
 N=$((N+1))
@@ -2356,7 +2562,7 @@ TEST="$NAME: echo via two unidirectional UDP IPv4 sockets"
 tf="$td/file$N"
 newport udp4; PORT1=$PORT 	# get free port
 newport udp4; PORT2=$PORT 	# get free port
-testecho "$N" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts"
 esac
 fi # NUMCOND
 N=$((N+1))
@@ -2392,8 +2598,7 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    echo "rc=$rc2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
@@ -2401,13 +2606,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $bg 2>/dev/null
 esac
@@ -2426,8 +2629,7 @@ elif ! cond=$(checkconds "" "" "" \
 			 "so-reuseaddr" \
 			 "tcp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2448,9 +2650,7 @@ if [ $? -ne 0 ]; then
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED\n"
 	echo "$CMD0 &"
@@ -2459,17 +2659,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	cat "${te}1" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
 fi
 kill $pid1 2>/dev/null
 wait
@@ -2486,20 +2683,16 @@ TEST="$NAME: echo via connection to TCP V6 socket"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2520,8 +2713,7 @@ if [ $? -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     echo "$CMD1 &"
@@ -2530,16 +2722,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo diff:
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 fi
@@ -2556,20 +2746,16 @@ TEST="$NAME: echo via connection to TCP socket, v4 by target"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions pf) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2590,9 +2776,7 @@ if [ $? -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
@@ -2600,17 +2784,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 fi
@@ -2626,20 +2807,16 @@ TEST="$NAME: echo via connection to TCP socket, v6 by target"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions pf) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2660,9 +2837,7 @@ if [ $? -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
@@ -2670,17 +2845,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 fi
@@ -2698,16 +2870,13 @@ TEST="$NAME: option ipv6-v6only=0 listens on IPv4"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions ipv6-v6only); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2727,18 +2896,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 fi
@@ -2755,16 +2921,13 @@ TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions ipv6-v6only); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2782,17 +2945,14 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -eq 0 ]; then
    $PRINTF "$FAILED:\n"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED:\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid; wait
 wait
@@ -2808,16 +2968,13 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runstcp6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions ipv6-v6only); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2837,18 +2994,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi
@@ -2862,12 +3016,10 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2888,8 +3040,7 @@ if [ $? -ne 0 ]; then
    cat "${te}1" >&2
    echo "$CMD2"
    cat "${te}2" >&2
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED (diff):\n"
    echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &"
@@ -2898,16 +3049,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}2" >&2
    echo "// diff:" >&2
    cat "$tdiff" >&2
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null; wait
 fi
@@ -2921,16 +3070,13 @@ TEST="$NAME: option -4 for IPv4 preference on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions ipv6-v6only); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -2950,18 +3096,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi
@@ -2975,12 +3118,10 @@ TEST="$NAME: option -6 for IPv6 preference on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -3000,18 +3141,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 wait
@@ -3026,16 +3164,13 @@ TEST="$NAME: pf=4 overrides option -6 on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions ipv6-v6only); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -3055,18 +3190,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi
@@ -3080,12 +3212,10 @@ TEST="$NAME: pf=6 overrides option -4 on listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -3105,18 +3235,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
@@ -3145,26 +3272,25 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
+   $PRINTF "$FAILED (rc2=$rc2)\n"
    echo "$CMD1 &"
+   cat "${te}1" >&2
    echo "$CMD2"
-   cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   cat "${te}2" >&2
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
-   $PRINTF "$FAILED\n"
+   $PRINTF "$FAILED (diff)\n"
    echo "$CMD1 &"
-   cat "${te}1"
+   cat "${te}1" >&2
    echo "$CMD2"
-   cat "${te}2"
-   cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   cat "${te}2" >&2
+   echo "// diff:" >&2
+   cat "$tdiff" >&2
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3178,8 +3304,7 @@ TEST="$NAME: echo via connection to UDP V6 socket"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -3197,22 +3322,25 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 rc2=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
-   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
+   $PRINTF "$FAILED (rc2=$rc2)\n"
    echo "$CMD1 &"
+   cat "${te}1" >&2
    echo "$CMD2"
-   cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   cat "${te}2" >&2
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
-   $PRINTF "$FAILED\n"
-   cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   $PRINTF "$FAILED (diff)\n"
+   echo "$CMD1 &"
+   cat "${te}1" >&2
+   echo "$CMD2"
+   cat "${te}2" >&2
+   echo "// diff:" >&2
+   cat "$tdiff" >&2
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # ! testfeats
 esac
@@ -3237,18 +3365,15 @@ if [ $? -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 elif ! diff "$tf1" "$tf2" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # NUMCOND
 esac
@@ -3278,8 +3403,7 @@ if [ ! -p "$tp" ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 else
 #echo "$da" >"$tp"	# might hang forever
 echo "$da" >"$tp" & export pid=$!; (relsleep 1; kill $pid 2>/dev/null) &
@@ -3295,13 +3419,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED: diff:\n"
 	cat "$tdiff"
     fi
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi
 wait
@@ -3336,8 +3458,7 @@ if [ $? -ne 0 ]; then
     cat "${te}s"
     echo "$CMD"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$FAILED:\n"
@@ -3346,13 +3467,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     echo "$CMD"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi # !(rc -ne 0)
 wait
 fi # NUMCOND
@@ -3385,8 +3504,7 @@ if [ $? -ne 0 ]; then
     cat "${te}s"
     echo "$CMD"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$FAILED:\n"
@@ -3395,13 +3513,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     echo "$CMD"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi # !(rc -ne 0)
 wait
 fi # NUMCOND
@@ -3435,8 +3551,7 @@ if [ $? -ne 0 ]; then
     cat "${te}s"
     echo "$CMD"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then
     $PRINTF "$FAILED:\n"
     echo "$SRV &"
@@ -3444,13 +3559,11 @@ elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then
     echo "$CMD"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi # !(rc -ne 0)
 kill "$pids" 2>/dev/null; wait
 fi ;; # NUMCOND
@@ -3458,71 +3571,108 @@ esac
 N=$((N+1))
 
 
+# Test the ignoreeof option in forward (left to right) direction
 NAME=IGNOREEOF
 case "$TESTS" in
 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
 TEST="$NAME: ignoreeof on file"
-if ! eval $NUMCOND; then :; else
+# Let Socat read from an empty file, this would terminate immediately due to
+# EOF. Wait for more than one second, then append data to the file; when Socat
+# transfers this data the test succeeded.
+if ! eval $NUMCOND; then :;
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "STDIO FILE" \
+		  "STDOUT FILE" \
+		  "ignoreeof" \
+		  "" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
 ti="$td/test$N.file"
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -"
+# Note: the bug in 1.8.0.0 and 1.8.0.1 let Socat terminate in unidirectional
+# mode after 1s, in bidirectional mode with traffic in reverse direction
+# (var wasaction) immediately
+CMD="$TRACE $SOCAT $opts -u FILE:\"$ti\",ignoreeof -"
 printf "test $F_n $TEST... " $N
 touch "$ti"
 $CMD >"$tf" 2>"$te" &
 bg=$!
-sleep 0.1
+# Up to 1.8.0.1 this sleep was 0.1 and thus the test said OK despite the bug
+sleep 1.1
 echo "$da" >>"$ti"
 sleep 1
 kill $bg 2>/dev/null; wait
 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: diff:\n"
-    cat "$tdiff"
-    listFAIL="$listFAIL $N"
-    numFAIL=$((numFAIL+1))
+    $PRINTF "$FAILED (diff)\n"
+    echo "$CMD"
+    cat "$te" >&2
+    echo "// diff:" >&2
+    cat "$tdiff" >&2
+    failed
 else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+    $PRINTF "$OK\n"
+    if [ -n "$VERBOSE" ]; then echo "$CMD"; fi
+    if [ -n "$DEBUG" ]; then cat "$te" >&2; fi
+    ok
 fi
 fi ;; # NUMCOND
 esac
 N=$((N+1))
 
+# Test the ignoreeof option in reverse (right to left) direction
 NAME=IGNOREEOF_REV
 case "$TESTS" in
 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
 TEST="$NAME: ignoreeof on file right-to-left"
-if ! eval $NUMCOND; then :; else
+if ! eval $NUMCOND; then :;
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "STDIO FILE" \
+		  "STDOUT FILE" \
+		  "ignoreeof" \
+		  "" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+# Let Socat read from an empty file, this would terminate immediately due to
+# EOF. Wait for more than one second, then append data to the file; when Socat
+# transfers this data the test succeeded.
 ti="$td/test$N.file"
 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="$SOCAT $opts -U - FILE:\"$ti\",ignoreeof"
 printf "test $F_n $TEST... " $N
 touch "$ti"
 $CMD >"$tf" 2>"$te" &
 bg=$!
-relsleep 1
+sleep 1.1
 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"
-    listFAIL="$listFAIL $N"
-    numFAIL=$((numFAIL+1))
+    $PRINTF "$FAILED (diff)\n"
+    echo "$CMD"
+    cat "$te" >&2
+    echo "// diff:" >&2
+    cat "$tdiff" >&2
+    failed
 else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+    $PRINTF "$OK\n"
+    if [ -n "$VERBOSE" ]; then echo "$CMD"; fi
+    if [ -n "$DEBUG" ]; then cat "$te" >&2; fi
+    ok
 fi
-wait
 fi ;; # NUMCOND
 esac
 N=$((N+1))
@@ -3542,14 +3692,13 @@ $CMD >"$tf" 2>"$te"
 if [ -s "$te" ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
-    cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    cat "$te" >&2
+    failed
 else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+    $PRINTF "$OK\n"
+    if [ -n "$VERBOSE" ]; then echo "$CMD"; fi
+    if [ -n "$DEBUG" ]; then cat "$te" >&2; fi
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3563,8 +3712,7 @@ TEST="$NAME: generation of pty for other processes"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tt="$td/pty$N"
 tf="$td/test$N.stdout"
@@ -3590,13 +3738,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
@@ -3625,13 +3771,11 @@ if ! [ $rc0 = 0 ] ||
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3657,13 +3801,11 @@ if ! echo "$da" |$CMD >$tf 2>"$te" ||
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3674,7 +3816,7 @@ NAME=RIGHTTOLEFT
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: unidirectional throughput from stdin to stdout, right to left"
-testecho "$N" "$TEST" "stdout" "stdin" "$opts -U"
+testecho "$N" "$NAME" "$TEST" "stdout" "stdin" "$opts -U"
 esac
 N=$((N+1))
 
@@ -3686,12 +3828,10 @@ case "$TESTS" in
 if ! eval $NUMCOND; then :
 elif ! F=$(testfeats STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 TEST="$NAME: child process default properties"
 tf="$td/test$N.stdout"
@@ -3711,14 +3851,12 @@ then
     $PRINTF "$FAILED:\n"
     echo "$CMD"
     cat "$te" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3747,12 +3885,10 @@ then
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3781,12 +3917,10 @@ then
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -3800,16 +3934,13 @@ TEST="$NAME: openssl connect"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -3835,13 +3966,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
@@ -3856,12 +3985,10 @@ TEST="$NAME: openssl listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -3883,13 +4010,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -3904,12 +4029,10 @@ TEST="$NAME: openssl listen"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -3931,13 +4054,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -3946,8 +4067,6 @@ esac
 N=$((N+1))
 
 
-newport $RUNS 	# in case it has not yet been invoked
-
 while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do
 if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi
 
@@ -3970,12 +4089,10 @@ TEST="$NAME: $TESTKEYW half close"
 if ! eval $NUMCOND; then :;
 elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs$RUNS >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available on host${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -3998,8 +4115,7 @@ if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then
     echo "$CMD"
     cat "${te}"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
@@ -4007,8 +4123,7 @@ else
 	echo "  $CMD"
     fi
    if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 wait
 fi ;; # NUMCOND, feats
@@ -4038,12 +4153,10 @@ TEST="$NAME: OpenSSL server authentication (hostname)"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -4066,13 +4179,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD1"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4087,12 +4198,10 @@ TEST="$NAME: openssl client authentication"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -4115,13 +4224,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4136,16 +4243,13 @@ TEST="$NAME: OpenSSL+FIPS client and server authentication"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testoptions fips >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 OPENSSL_FIPS=1 gentestcert testsrvfips
 OPENSSL_FIPS=1 gentestcert testclifips
@@ -4168,13 +4272,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4190,16 +4292,13 @@ TEST="$NAME: OpenSSL compression"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testoptions openssl-compress >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     gentestcert testsrv
     printf "test $F_n $TEST... " $N
@@ -4231,63 +4330,73 @@ else
         cat "${te}1"
         cat "${te}2"
         cat "$tdiff"
-        numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+        failed
     else
         $PRINTF "$OK\n"
         if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-        numOK=$((numOK+1))
-	listOK="$listOK $N"
+        ok
     fi
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
 
 
+# Test the SOCKS address with IPv4
 NAME=SOCKS4CONNECT_TCP4
 case "$TESTS" in
 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
 TEST="$NAME: socks4 connect over TCP/IPv4"
 if ! eval $NUMCOND; then :;
-elif ! testfeats socks4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "socks4echo.sh" \
+		  "SOCKS4 IP4 TCP LISTEN STDIO" \
+		  "TCP4-LISTEN EXEC STDIN SOCKS4" \
+		  "so-reuseaddr" \
+		  "tcp4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
 else
-tf="$td/test$N.stdout"
-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
-newport tcp4 	# provide free port number in $PORT
-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: $TRACE $SOCAT:\n"
-    echo "$CMD2 &"
-    echo "$CMD"
-    cat "${te}1"
-    cat "${te}2"
-    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
-fi
-kill $pid 2>/dev/null
-wait
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp4 	# provide free port number in $PORT
+    CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\""
+    CMD1="$TRACE $SOCAT $opts STDIO SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid0=$!	# background process id
+    waittcp4port $PORT 1
+    echo "$da" |$CMD1 >${tf}1 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null
+    wait
+    if [ "$rc1" -ne 0 ]; then
+	$PRINTF "$FAILED (rc1=$rc1)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    fi
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4299,12 +4408,10 @@ TEST="$NAME: socks4 connect over TCP/IPv6"
 if ! eval $NUMCOND; then :;
 elif ! testfeats socks4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -4327,16 +4434,14 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
     cat "${te}1" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4352,12 +4457,10 @@ TEST="$NAME: socks4a connect over TCP/IPv4"
 if ! eval $NUMCOND; then :;
 elif ! testfeats socks4a >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -4379,13 +4482,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4400,12 +4501,10 @@ TEST="$NAME: socks4a connect over TCP/IPv6"
 if ! eval $NUMCOND; then :;
 elif ! testfeats socks4a >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -4427,13 +4526,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4449,44 +4546,52 @@ TEST="$NAME: proxy connect over TCP/IPv4"
 if ! eval $NUMCOND; then :;
 elif ! testfeats proxy >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-ts="$td/test$N.sh"
-tf="$td/test$N.stdout"
-te="$td/test$N.stderr"
-tdiff="$td/test$N.diff"
-da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-newport tcp4 	# provide free port number in $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:\"/usr/bin/env 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: $TRACE $SOCAT:\n"
-    echo "$CMD2 &"
-    echo "$CMD"
-    cat "${te}1"
-    cat "${te}2"
-    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
-fi
-kill $pid 2>/dev/null
-wait
+    ts="$td/test$N.sh"
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp4 	# provide free port number in $PORT
+    #CMD0="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
+    CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
+    CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid=$!	# background process id
+    waittcp4port $PORT 1
+    echo "$da" |$CMD1 >"$tf" 2>"${te}1"
+    rc1=$?
+    if [ "$rc1" -ne 0 ]; then
+	$PRINTF "$FAILED (rc1=$rc1)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	fail
+    elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	fail
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    fi
+    kill $pid 2>/dev/null
+    wait
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4498,44 +4603,52 @@ TEST="$NAME: proxy connect over TCP/IPv6"
 if ! eval $NUMCOND; then :;
 elif ! testfeats proxy >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-ts="$td/test$N.sh"
-tf="$td/test$N.stdout"
-te="$td/test$N.stderr"
-tdiff="$td/test$N.diff"
-da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-newport tcp6 	# provide free port number in $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:\"/usr/bin/env 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: $TRACE $SOCAT:\n"
-    echo "$CMD2 &"
-    echo "$CMD"
-    cat "${te}1"
-    cat "${te}2"
-    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
-fi
-kill $pid 2>/dev/null
-wait
+    ts="$td/test$N.sh"
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp6 	# provide free port number in $PORT
+    #CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
+    CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
+    CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid=$!	# background process id
+    waittcp6port $PORT 1
+    echo "$da" |$CMD1 >"$tf" 2>"${te}1"
+    rc1=$?
+    if [ "$rc1" -ne 0 ]; then
+	$PRINTF "$FAILED (rc1=$rc1)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff: " >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    fi
+    kill $pid 2>/dev/null
+    wait
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4566,18 +4679,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -4588,7 +4698,7 @@ NAME=EXECCATNOFORK
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: simple echo via exec of cat with nofork"
-testecho "$N" "$TEST" "" "EXEC:$CAT,nofork" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,nofork" "$opts"
 esac
 N=$((N+1))
 
@@ -4597,7 +4707,7 @@ NAME=SYSTEMCATNOFORK
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: simple echo via system() of cat with nofork"
-testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts"
 esac
 N=$((N+1))
 
@@ -4606,7 +4716,7 @@ NAME=NOFORKSETSID
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: simple echo via exec() of cat with nofork and setsid"
-testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts"
 esac
 N=$((N+1))
 
@@ -4622,12 +4732,10 @@ N=$((N+1))
 #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf"
 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
 #   $ECHO "... test $N succeeded"
-#   numOK=$((numOK+1))
-#   listOK="$listOK $N"
+#   ok
 #else
 #   $ECHO "*** test $N $FAILED"
-#    numFAIL=$((numFAIL+1))
-#    listFAIL="$listFAIL $N"
+#    failed
 #fi
 #fi ;; # NUMCOND
 #N=$((N+1))
@@ -4642,12 +4750,10 @@ N=$((N+1))
 #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf"
 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
 #   $ECHO "... test $N succeeded"
-#   numOK=$((numOK+1))
-#   listOK="$listOK $N"
+#   ok
 #else
 #   $ECHO "*** test $N $FAILED"
-#   numFAIL=$((numFAIL+1))
-#    listFAIL="$listFAIL $N"
+#   failed
 #fi
 #fi ;; # NUMCOND
 
@@ -4678,13 +4784,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4724,13 +4828,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "$te" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 wait
 MICROS=$SAVEMICS
@@ -4746,8 +4848,7 @@ TEST="$NAME: proxy connect accepts status with multiple spaces"
 if ! eval $NUMCOND; then :;
 elif ! testfeats proxy >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.sh"
 tf="$td/test$N.stdout"
@@ -4771,16 +4872,14 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1" >&2
     echo "diff:"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$debug" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$debug" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -4804,19 +4903,16 @@ CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk"
 $CMD <"$ff"  2>"$te"
 if [ "$?" -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     if [ "$UNAME" = "Linux" ]; then
 	$PRINTF "$FAILED\n"
 	echo "$CMD"
 	cat "$te"
-	numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+	failed
     else
 	$PRINTF "${YELLOW}failed (don't care)${NORMAL}\n"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
     fi
 fi
 fi ;; # NUMCOND
@@ -4828,7 +4924,7 @@ NAME=SINGLEEXECOUTSOCKETPAIR
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: inheritance of stdout to single exec with socketpair"
-testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1
+testecho "$N" "$NAME" "$TEST" "-!!exec:cat" "" "$opts" 1
 esac
 N=$((N+1))
 
@@ -4836,7 +4932,7 @@ NAME=SINGLEEXECOUTPIPE
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: inheritance of stdout to single exec with pipe"
-testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1
+testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1
 esac
 N=$((N+1))
 
@@ -4847,10 +4943,9 @@ TEST="$NAME: inheritance of stdout to single exec with pty"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1
+testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4859,7 +4954,7 @@ NAME=SINGLEEXECINSOCKETPAIR
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: inheritance of stdin to single exec with socketpair"
-testecho "$N" "$TEST" "exec:cat!!-" "" "$opts"
+testecho "$N" "$NAME" "$TEST" "exec:cat!!-" "" "$opts"
 esac
 N=$((N+1))
 
@@ -4867,7 +4962,7 @@ NAME=SINGLEEXECINPIPE
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: inheritance of stdin to single exec with pipe"
-testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts"
+testecho "$N" "$NAME" "$TEST" "exec:cat,pipes!!-" "" "$opts"
 esac
 N=$((N+1))
 
@@ -4878,10 +4973,9 @@ TEST="$NAME: inheritance of stdin to single exec with pty, with delay"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY
+testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4893,11 +4987,10 @@ TEST="$NAME: inheritance of stdin to single exec with pty"
 if ! eval $NUMCOND; then :;
 elif ! testfeats pty >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # T value needed (only) by AIX
-testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1
+testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -4911,8 +5004,7 @@ TEST="$NAME: readline with password and sigint"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats readline pty); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 SAVETERM="$TERM"; TERM=	# 'cause console might print controls even in raw
 SAVEMICS=$MICROS
@@ -4925,8 +5017,9 @@ te="$td/test$N.stderr"
 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="$TRACE $SOCAT -lpwrapper $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig"
+# The feature that we really want to test is in the readline.sh script
+READLINE_LOG=; if grep -e -lf ./readline.sh >/dev/null; then READLINE_LOG="-lf $td/test$N.rl-log"; fi
+CMD="$TRACE $SOCAT -lpwrapper $opts -t1 OPEN:$tpi,nonblock!!OPEN:$tpo EXEC:\"./readline.sh -nh $READLINE_LOG ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig"
 #echo "$CMD" >"$ts"
 #chmod a+x "$ts"
 printf "test $F_n $TEST... " $N
@@ -4984,14 +5077,12 @@ if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr"
     cat "$te" 2>&1
     echo diff:  2>&1
     cat "$tdiff" 2>&1
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 wait
 MICROS=$SAVEMICS
@@ -5003,7 +5094,7 @@ N=$((N+1))
 
 NAME=GENDERCHANGER
 case "$TESTS" in
-*%$N%*|*%functions%*|*%listen%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%listen%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: TCP4 \"gender changer\""
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.stdout"
@@ -5046,8 +5137,7 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}4" >&2
     echo diff: >&2
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
@@ -5058,8 +5148,7 @@ else
     if [ "$DEBUG" ];   then cat "${te}3" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD4"; fi
     if [ "$DEBUG" ];   then cat "${te}4" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -5068,13 +5157,12 @@ N=$((N+1))
 
 NAME=OUTBOUNDIN
 case "$TESTS" in
-*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats openssl proxy); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5134,13 +5222,11 @@ if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then
     echo "$CMD4 &"
     cat "${te}4"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
 wait
@@ -5160,13 +5246,12 @@ N=$((N+1))
 #!
 NAME=INTRANETRIPPER
 case "$TESTS" in
-*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: gender changer via SSL through HTTP proxy, daemons"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats openssl proxy); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5182,11 +5267,12 @@ newport tcp4; PORT3=$PORT
 newport tcp4; PORT4=$PORT
 newport tcp4; PORT5=$PORT
 # this is the server in the protected network that we want to reach
-CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 10) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO"
+CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 100) TCP4-L:$PORT1,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="$TRACE $SOCAT $opts -lpproxy -t$(reltime 10) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
+export SOCAT_OPTS="$OPTS" 	# for proxy.sh
+CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 100) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
 # this is our proxy connect wrapper in the protected network
 CMD3="$TRACE $SOCAT $opts -lpwrapper -t$(reltime 30) TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
 # this is our double client in the protected network using SSL
@@ -5212,21 +5298,23 @@ waittcp4port $PORT3 1 50 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null
 # now we start the external daemon
 eval "$CMD5 2>\"${te}5\" &"
 pid5=$!
-waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null
+waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null
 # and this is the outside client:
-echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" &
+{ echo "$da1"; relsleep 100; } |$CMD6 >${tf}_1 2>"${te}6_1" &
 pid6_1=$!
-echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" &
+relsleep 20
+{ echo "$da2"; relsleep 100; } |$CMD6 >${tf}_2 2>"${te}6_2" &
 pid6_2=$!
-echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" &
+relsleep 20
+{ echo "$da3"; relsleep 100; } |$CMD6 >${tf}_3 2>"${te}6_3" &
 pid6_3=$!
 wait $pid6_1 $pid6_2 $pid6_3
 kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null
-# (On BSDs a child of pid5 loves to hang)
+# (On BSDs a child of pid5 likes to hang)
 #
-(echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1"
-(echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2"
-(echo "$da3"; relsleep 2) |diff - "${tf}_3" >"${tdiff}3"
+echo "$da1" |diff - "${tf}_1" >"${tdiff}1"
+echo "$da2" |diff - "${tf}_2" >"${tdiff}2"
+echo "$da3" |diff - "${tf}_3" >"${tdiff}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
@@ -5250,19 +5338,16 @@ if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then
     echo "$CMD6 &"
     cat "${te}6_3"
     cat "${tdiff}3"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
   else
     $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
   fi
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
 wait
@@ -5306,8 +5391,7 @@ testserversec () {
 	$PRINTF "$NO_RESULT (ph.1 server not working):\n"
 	echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
 	cat "${te}1"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
 	wait; return
     fi
     # now use client
@@ -5321,8 +5405,7 @@ testserversec () {
 	cat "${te}1"
 	echo "$TRACE $SOCAT $opts - \"$arg2\""
 	cat "${te}2"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
 	wait; return
     elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then
 	:	# function without security is ok, go on
@@ -5333,16 +5416,14 @@ testserversec () {
 	echo "$TRACE $SOCAT $opts - $arg2"
 	cat "${te}2"
 	cat "$tdiff1"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
 	wait; return
     fi
 
     # then: with security
     if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then
 	$PRINTF "$NO_RESULT (ph.1 port remains in use)\n"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
 	wait; return
     fi
     wait
@@ -5364,8 +5445,7 @@ testserversec () {
 	wait
 	echo "$CMD3"
 	cat "${te}3"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
 	return
     fi
     # now use client
@@ -5391,8 +5471,7 @@ testserversec () {
 	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
-	    numFAIL=$((numFAIL+1))
-	    listFAIL="$listFAIL $N"
+	    failed
     elif [ "X$expect" != 'X*' -a X$result != X$expect ]; then
 	case X$result in
 	X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n"
@@ -5400,8 +5479,7 @@ testserversec () {
 	    cat "${te}3"
 	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
-	    numCANT=$((numCANT+1))
-	    listCANT="$listCANT $N"
+	    cant
 	    ;;
 	X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n"
 	    echo "$TRACE $SOCAT $opts $arg echo"
@@ -5409,8 +5487,7 @@ testserversec () {
 	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
-	    numCANT=$((numCANT+1))
-	    listCANT="$listCANT $N"
+	    cant
 	    ;;
 	X1) $PRINTF "$FAILED: SECURITY BROKEN\n"
 	    echo "$TRACE $SOCAT $opts $arg echo"
@@ -5418,8 +5495,7 @@ testserversec () {
 	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
-	    numFAIL=$((numFAIL+1))
-	    listFAIL="$listFAIL $N"
+	    failed
 	    ;;
 	X2) $PRINTF "$FAILED: diff:\n"
 	    echo "$TRACE $SOCAT $opts $arg echo"
@@ -5427,8 +5503,7 @@ testserversec () {
 	    echo "$TRACE $SOCAT $opts - $arg2"
 	    cat "${te}4"
 	    cat "$tdiff2"
-	    numFAIL=$((numFAIL+1))
-	    listFAIL="$listFAIL $N"
+	    failed
 	    ;;
 	esac
     else
@@ -5437,8 +5512,7 @@ testserversec () {
 	[ "$debug" ] && cat ${te}3
 	[ "$VERBOSE" ] && echo "  $TRACE $SOCAT $opts - $arg2"
 	[ "$debug" ] && cat ${te}4
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
     wait
 #set +vx
@@ -5447,14 +5521,13 @@ testserversec () {
 
 NAME=TCP4RANGEBITS
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with RANGE option"
 if ! eval $NUMCOND; then :;
 elif [ -z "$SECONDADDR" ]; then
     # we need access to a second addresses
     $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
@@ -5464,14 +5537,13 @@ N=$((N+1))
 
 NAME=TCP4RANGEMASK
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with RANGE option"
 if ! eval $NUMCOND; then :;
 elif [ -z "$SECONDADDR" ]; then
     # we need access to a second addresses
     $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
@@ -5482,7 +5554,7 @@ N=$((N+1))
 # like TCP4RANGEMASK, but the "bad" address is within the same class A network
 NAME=TCP4RANGEMASKHAIRY
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with RANGE option"
 if ! eval $NUMCOND; then :; else
 newport tcp4 	# provide free port number in $PORT
@@ -5494,7 +5566,7 @@ N=$((N+1))
 
 NAME=TCP4SOURCEPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with SOURCEPORT option"
 if ! eval $NUMCOND; then :; else
 newport tcp4 	# provide free port number in $PORT
@@ -5505,7 +5577,7 @@ N=$((N+1))
 
 NAME=TCP4LOWPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with LOWPORT option"
 if ! eval $NUMCOND; then :; else
 newport tcp4 	# provide free port number in $PORT
@@ -5516,13 +5588,12 @@ N=$((N+1))
 
 NAME=TCP4WRAPPERS_ADDR
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -5536,13 +5607,12 @@ N=$((N+1))
 
 NAME=TCP4WRAPPERS_NAME
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP4-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -5557,13 +5627,12 @@ N=$((N+1))
 
 NAME=TCP6RANGE
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP6-L with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "range=[::2]/128" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
@@ -5573,13 +5642,12 @@ N=$((N+1))
 
 NAME=TCP6SOURCEPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP6-L with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
@@ -5589,13 +5657,12 @@ N=$((N+1))
 
 NAME=TCP6LOWPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP6-L with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
@@ -5605,13 +5672,12 @@ N=$((N+1))
 
 NAME=TCP6TCPWRAP
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of TCP6-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -5665,8 +5731,7 @@ TEST="$NAME: security of UDP4-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -5686,8 +5751,7 @@ TEST="$NAME: security of UDP6-L with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 #testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0
@@ -5703,8 +5767,7 @@ TEST="$NAME: security of UDP6-L with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP6:[::1]:$PORT" 6 udp $PORT 0
@@ -5719,8 +5782,7 @@ TEST="$NAME: security of UDP6-L with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0
@@ -5735,8 +5797,7 @@ TEST="$NAME: security of UDP6-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -5750,13 +5811,12 @@ N=$((N+1))
 
 NAME=OPENSSLTCP4_RANGE
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 newport tcp4 	# provide free port number in $PORT
@@ -5767,13 +5827,12 @@ N=$((N+1))
 
 NAME=OPENSSLTCP4_SOURCEPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 newport tcp4 	# provide free port number in $PORT
@@ -5784,13 +5843,12 @@ N=$((N+1))
 
 NAME=OPENSSLTCP4_LOWPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 newport tcp4 	# provide free port number in $PORT
@@ -5801,13 +5859,12 @@ N=$((N+1))
 
 NAME=OPENSSLTCP4_TCPWRAP
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 tcp libwrap openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 ha="$td/hosts.allow"
@@ -5822,13 +5879,12 @@ N=$((N+1))
 
 NAME=OPENSSLCERTSERVER
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L with client certificate"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5840,13 +5896,12 @@ N=$((N+1))
 
 NAME=OPENSSLCERTCLIENT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL with server certificate"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5859,17 +5914,15 @@ N=$((N+1))
 
 NAME=OPENSSLTCP6_RANGE
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert6 testsrv6
 newport tcp6 	# provide free port number in $PORT
@@ -5880,17 +5933,15 @@ N=$((N+1))
 
 NAME=OPENSSLTCP6_SOURCEPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert6 testsrv6
 newport tcp6 	# provide free port number in $PORT
@@ -5901,17 +5952,15 @@ N=$((N+1))
 
 NAME=OPENSSLTCP6_LOWPORT
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert6 testsrv6
 newport tcp6 	# provide free port number in $PORT
@@ -5922,13 +5971,12 @@ N=$((N+1))
 
 NAME=OPENSSLTCP6_TCPWRAP
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert6 testsrv6
 ha="$td/hosts.allow"
@@ -5945,19 +5993,17 @@ N=$((N+1))
 # test security with the openssl-commonname option on client side
 NAME=OPENSSL_CN_CLIENT_SECURITY
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of client openssl-commonname option"
 # connect using non matching server name/address with commonname
 # options, this should succeed. Then without this option, should fail
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5978,12 +6024,10 @@ TEST="$NAME: security of server openssl-commonname option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -5996,21 +6040,18 @@ N=$((N+1))
 
 NAME=OPENSSL_FIPS_SECURITY
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: OpenSSL restrictions by FIPS"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testoptions fips >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 gentestcert testcli
@@ -6026,7 +6067,7 @@ NAME=UNIEXECEOF
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: give exec'd write-only process a chance to flush (-u)"
-testod "$N" "$TEST" "" EXEC:"$OD_C" "$opts -u"
+testod "$N" "$NAME" "$TEST" "" EXEC:"$OD_C" "$opts -u"
 esac
 N=$((N+1))
 
@@ -6035,7 +6076,7 @@ NAME=REVEXECEOF
 case "$TESTS" in
 *%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: give exec'd write-only process a chance to flush (-U)"
-testod "$N" "$TEST" EXEC:"$OD_C" "-" "$opts -U"
+testod "$N" "$NAME" "$TEST" EXEC:"$OD_C" "-" "$opts -U"
 esac
 N=$((N+1))
 
@@ -6050,13 +6091,11 @@ printf "test $F_n $TEST... " $N
 type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}')
 if [ "$type" = "dir" ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi ;; # NUMCOND
 esac
@@ -6085,16 +6124,14 @@ if [ "$type" = "socket" ]; then
 	echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\""
 	echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'"
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" >&2
     cat "$te1"
     echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" >&2
     cat "$te2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 kill $spid 2>/dev/null
 wait
@@ -6143,8 +6180,7 @@ if echo "$da" |diff - "$tf"> "$tdiff"; then
 	echo "  $TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link=\"$tp\" UNIX-LISTEN:\"$ts\"" >&2
 	echo "  $TRACE $SOCAT -lpsocat3 $opts - file:\"$tp\",$PTYOPTS2" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "${YELLOW}FAILED${NORMAL}\n"
     cat "$te1"
@@ -6152,8 +6188,7 @@ else
     cat "$te3"
     cat "$te4"
     cat "$tdiff"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 fi
 set +vx
 }
@@ -6166,12 +6201,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
 if ! eval $NUMCOND; then :; else
 if ! feat=$(testfeats pty); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
     $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
    testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
 fi
@@ -6187,12 +6220,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats pty); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
     $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
    testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
 fi ;; # NUMCOND, feats
@@ -6208,12 +6239,10 @@ TEST="$NAME: test the connect-timeout option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions connect-timeout); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # We need a hanging connection attempt, guess an address for this
 case "$UNAME" in
@@ -6235,8 +6264,7 @@ if ! kill $pid1 2>"$tk1"; then
     $PRINTF "${YELLOW}does not hang${NORMAL}\n"
     echo "$CMD" >&2
     cat "$te1" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # Second, set connect-timeout and see if socat exits before kill
 CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=$(reltime 1)"
@@ -6247,15 +6275,13 @@ if kill $pid2 2>"$tk2"; then
     $PRINTF "$FAILED (\n"
     echo "$CMD" >&2
     cat "$te2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
 	echo "$CMD" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi
 wait
@@ -6296,8 +6322,7 @@ if [ $rc2 -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED (diff)\n"
     echo "$CMD1 &"
@@ -6306,13 +6331,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi ;;
 esac
 fi # NUMCOND
@@ -6326,8 +6349,7 @@ TEST="$NAME: openssl listen with DSA certificate"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 SRVCERT=testsrvdsa
 gentestdsacert $SRVCERT
@@ -6350,13 +6372,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -6391,8 +6411,7 @@ TEST="$NAME: exit status when dying on SIG$signam"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats pty); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 SIG="$(signum $signam)"
 te="$td/test$N.stderr"
@@ -6418,14 +6437,12 @@ sleep 1; kill -INT $(cat $tp)
 wait
 if [ "$stat" -eq $((128+$SIG)) ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 wait
 fi ;; # NUMCOND, feats
@@ -6442,8 +6459,7 @@ TEST="$NAME: restrict reading from file with bytes option"
 if ! eval $NUMCOND; then :;
 elif false; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tr="$td/test$N.ref"
 ti="$td/test$N.in"
@@ -6467,13 +6483,11 @@ if ! diff "$tr" "$to" >"$tdiff" 2>&1; then
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -6487,20 +6501,16 @@ TEST="$NAME: UDP socket rebinds after first connection"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO IP4 UDP PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO UDP4-CONNECT UDP4-LISTEN PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions bind so-reuseaddr fork) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -6525,8 +6535,7 @@ if [ $? -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$NO_RESULT (first conn failed); diff:\n"
@@ -6535,8 +6544,7 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     echo "$CMD1"
     cat "${te}1" >&2
     cat "$tdiff"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 relsleep 2		# UDP-LISTEN sleeps 1s
 echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2"
@@ -6547,8 +6555,7 @@ if [ $rc -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then
     $PRINTF "$FAILED: diff\n"
     echo "$CMD0 &"
@@ -6557,16 +6564,14 @@ elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then
     cat "${te}1" >&2
     echo "diff:"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # !( $? -ne 0)
 fi # !(rc -ne 0)
 wait
@@ -6593,11 +6598,10 @@ TEST="$NAME: $PROTOV listen handles 2 concurrent connections"
 if ! eval $NUMCOND; then :;
 #elif ! feat=$(testfeats $PROTOV); then
 #    $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
+#    cant
 elif ! runs$protov >/dev/null; then
      $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N
-     numCANT=$((numCANT+1))
-     listCANT="$listCANT $N"
+     cant
 else
 ts="$td/test$N.sock"
 tref="$td/test$N.ref"
@@ -6613,7 +6617,7 @@ case "$MAJADDR" in
 	tca="$ts"
 	waitproto="file"
 	waitfor="$ts" ;;
-esac	
+esac
 case "$MINADDR" in
     "PORT")
 	newport $protov 	# provide free port number in $PORT
@@ -6621,7 +6625,7 @@ case "$MINADDR" in
 	tca="$MAJADDR:$PORT"
 	waitproto="${protov}port"
 	waitfor="$PORT" ;;
-esac	
+esac
 #set -xv
 echo -e "$da1a\n$da2\n$da1b" >"$tref"
 # establish a listening and forking listen socket in background
@@ -6649,8 +6653,7 @@ if ! diff -u "$tref" "$tf" >"$tdiff"; then
     echo "$CMD1"
     cat "${te}2" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -6659,8 +6662,7 @@ else
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # !(rc -ne 0)
 wait
 fi ;; # NUMCOND, feats
@@ -6702,18 +6704,15 @@ if [ $? -ne 0 ]; then
     echo "$SRV &"
     echo "$CLI"
     cat "${te}s" "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$FAILED; diff:\n"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # !(rc -ne 0)
 wait
 fi ;; # NUMCOND
@@ -6752,8 +6751,7 @@ if [ $rc -ne 0 ]; then
     cat "${te}s"
     echo "$CLI"
     cat "${te}1" "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$FAILED:\n"
@@ -6762,12 +6760,10 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     echo "$CLI"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # !(rc -ne 0)
 fi ;; # NUMCOND
 esac
@@ -6782,7 +6778,7 @@ TEST="$NAME: simple echo via exec of cat with pipes,stderr"
 # this test is known to fail when logging is enabled with OPTS/opts env var.
 SAVE_opts="$opts"
 opts="$(echo "$opts" |sed 's/-dd*//g')"
-testecho "$N" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts"
 opts="$SAVE_opts"
 esac
 N=$((N+1))
@@ -6799,7 +6795,7 @@ case "$opts" in
 *-d*) opts="$opts -d" ;;
 *) opts="-d -d" ;;
 esac
-testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts"
+testecho "$N" "$NAME" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts"
 opts="$SAVE_opts"
 esac
 N=$((N+1))
@@ -6810,7 +6806,7 @@ NAME=SIMPLEPARSE
 case "$TESTS" in
 *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*)
 TEST="$NAME: invoke socat from socat"
-testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t"
+testecho "$N" "$NAME" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t"
 esac
 N=$((N+1))
 
@@ -6835,20 +6831,17 @@ if [ "$rc" -ne 0 ]; then
     $PRINTF "$FAILED:\n"
     echo "$TRACE $SOCAT" -u "exec:echo $da" -
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ -s "$tdiff" ]; then
     $PRINTF "$FAILED:\n"
     echo diff:
     cat "$tdiff"
     if [ -n "$debug" ]; then cat $te; fi
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -6858,7 +6851,7 @@ NAME=NESTEDSOCATEXEC
 case "$TESTS" in
 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: does lexical analysis work sensibly (exec)"
-testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1
+testecho "$N" "$NAME" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1
 esac
 N=$((N+1))
 
@@ -6866,7 +6859,7 @@ NAME=NESTEDSOCATSYSTEM
 case "$TESTS" in
 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
 TEST="$NAME: does lexical analysis work sensibly (system)"
-testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1
+testecho "$N" "$NAME" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1
 esac
 N=$((N+1))
 
@@ -6878,12 +6871,10 @@ TEST="$NAME: TCP4 mapped into TCP6 address space"
 if ! eval $NUMCOND; then :;
 elif true; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature removed${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -6904,18 +6895,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null; wait
 fi ;; # NUMCOND, feats
@@ -6955,8 +6943,7 @@ if [ "$rc2" -ne 0 ]; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -6964,13 +6951,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # NUMCOND
  ;;
@@ -6985,8 +6970,7 @@ TEST="$NAME: UDP/IPv6 datagram"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7009,18 +6993,15 @@ if [ $? -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -7034,8 +7015,7 @@ TEST="$NAME: raw IPv4 datagram"
 if ! eval $NUMCOND; then :;
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7061,18 +7041,15 @@ if [ $rc2 -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # root, NUMCOND
 esac
@@ -7087,12 +7064,10 @@ TEST="$NAME: raw IPv6 datagram by self addressing"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7114,18 +7089,15 @@ if [ $? -ne 0 ]; then
 #   cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # root, NUMCOND
 esac
@@ -7159,8 +7131,7 @@ if [ $rc2 -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD1 &"
@@ -7169,16 +7140,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -7215,8 +7184,7 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -7224,13 +7192,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # NUMCOND
  ;;
@@ -7245,8 +7211,7 @@ TEST="$NAME: UDP/IPv6 receive"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7272,18 +7237,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -7297,8 +7259,7 @@ TEST="$NAME: raw IPv4 receive"
 if ! eval $NUMCOND; then :;
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7324,18 +7285,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, root
 esac
@@ -7349,12 +7307,10 @@ TEST="$NAME: raw IPv6 receive"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -7379,18 +7335,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, root
 esac
@@ -7424,18 +7377,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # NUMCOND
  ;;
@@ -7450,8 +7400,7 @@ TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
@@ -7466,8 +7415,7 @@ TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
@@ -7494,8 +7442,7 @@ TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 udp libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -7516,8 +7463,7 @@ TEST="$NAME: security of UDP4-RECV with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4; PORT1=$PORT
 newport udp4; PORT2=$PORT
@@ -7536,8 +7482,7 @@ TEST="$NAME: security of UDP4-RECV with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4; PORT1=$PORT
 newport udp4; PORT2=$PORT
@@ -7555,8 +7500,7 @@ TEST="$NAME: security of UDP4-RECV with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4; PORT1=$PORT
 newport udp4; PORT2=$PORT
@@ -7574,8 +7518,7 @@ TEST="$NAME: security of UDP4-RECV with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4; PORT1=$PORT
 newport udp4; PORT2=$PORT
@@ -7598,8 +7541,7 @@ TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
@@ -7614,8 +7556,7 @@ TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
@@ -7630,8 +7571,7 @@ TEST="$NAME: security of UDP6-RECVFROM with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 #testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
@@ -7647,8 +7587,7 @@ TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -7668,8 +7607,7 @@ TEST="$NAME: security of UDP6-RECV with SOURCEPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6; PORT1=$PORT
 newport udp6; PORT2=$PORT
@@ -7688,8 +7626,7 @@ TEST="$NAME: security of UDP6-RECV with LOWPORT option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6; PORT1=$PORT
 newport udp6; PORT2=$PORT
@@ -7707,8 +7644,7 @@ TEST="$NAME: security of UDP6-RECV with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6; PORT1=$PORT
 newport udp6; PORT2=$PORT
@@ -7726,8 +7662,7 @@ TEST="$NAME: security of UDP6-RECV with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -7750,12 +7685,10 @@ TEST="$NAME: security of IP4-RECVFROM with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp4 	# provide free port number in $PORT
 #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0
@@ -7772,12 +7705,10 @@ TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -7800,12 +7731,10 @@ TEST="$NAME: security of IP4-RECV with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
 IPPROTO2=$((IPPROTO+1))
@@ -7826,12 +7755,10 @@ TEST="$NAME: security of IP4-RECV with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
 IPPROTO2=$((IPPROTO+1))
@@ -7855,12 +7782,10 @@ TEST="$NAME: security of IP6-RECVFROM with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport udp6 	# provide free port number in $PORT
 #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0
@@ -7877,12 +7802,10 @@ TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ha="$td/hosts.allow"
 hd="$td/hosts.deny"
@@ -7904,12 +7827,10 @@ TEST="$NAME: security of IP6-RECV with RANGE option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
 IPPROTO2=$((IPPROTO+1))
@@ -7928,12 +7849,10 @@ TEST="$NAME: security of IP6-RECV with TCPWRAP option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
 IPPROTO2=$((IPPROTO+1))
@@ -7961,8 +7880,7 @@ TEST="$NAME: option O_NOATIME on file"
 if ! eval $NUMCOND; then :;
 elif ! testoptions o-noatime >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.file"
 te="$td/test$N.stderr"
@@ -7982,8 +7900,7 @@ if [ $? -ne 0 ]; then # command failed
     $PRINTF "${FAILED}:\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
 # check which file has a later atime stamp
 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
@@ -7991,13 +7908,11 @@ then
    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD"
    cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi # wrong time stamps
 fi # command ok
 fi ;; # NUMCOND, feats
@@ -8015,8 +7930,7 @@ TEST="$NAME: option O_NOATIME on file descriptor"
 if ! eval $NUMCOND; then :;
 elif ! testoptions o-noatime >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.file"
 te="$td/test$N.stderr"
@@ -8038,8 +7952,7 @@ if [ $rc -ne 0 ]; then # command failed
     $PRINTF "${FAILED} (rc=$rc):\n"
     echo "$CMD"
     cat "$te" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
 # check which file has a later atime stamp
 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
@@ -8047,14 +7960,12 @@ then
     $PRINTF "$FAILED (bad order):\n"
     echo "$CMD" >&2
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # wrong time stamps
 fi # command ok
 fi ;; # NUMCOND, feats
@@ -8072,8 +7983,7 @@ TEST="$NAME: extended file system options using fs noatime option"
 if ! eval $NUMCOND; then :;
 elif ! testoptions fs-noatime >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}fs-noatime not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.socket"
 tf="$td/test$N.file"
@@ -8088,8 +7998,7 @@ CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime"
 $CMD0 2>"${te}0"
 if [ $? -ne 0 ]; then
     $PRINTF "${YELLOW} cannot test${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # generate a file with noatime, len >= 1
 $CMD 2>"$te"
@@ -8097,8 +8006,7 @@ if [ $? -ne 0 ]; then # command failed
     $PRINTF "${YELLOW}impotent file system?${NORMAL}\n"
     echo "$CMD"
     cat "$te"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 sleep 1
 # generate a reference file
@@ -8113,13 +8021,11 @@ then
    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
    echo "$CMD"
    cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # not impotent
 fi # can test
@@ -8135,8 +8041,7 @@ TEST="$NAME: option cool-write"
 if ! eval $NUMCOND; then :;
 elif ! testoptions cool-write >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 #set -vx
 ti="$td/test$N.pipe"
@@ -8158,13 +8063,11 @@ if [ $rc -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD &"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8186,8 +8089,7 @@ TEST="$NAME: option cool-write on bidirectional stdio"
 if ! eval $NUMCOND; then :;
 elif ! testoptions cool-write >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 #set -vx
 ti="$td/test$N.pipe"
@@ -8211,13 +8113,11 @@ if [ $rc -ne 0 ]; then
     cat "${te}1"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8264,8 +8164,7 @@ if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then
     cat "${te}2a" >&2
     echo "$CMD2"
     cat "${te}2b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD0 &"
@@ -8277,8 +8176,7 @@ elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then
     echo "$CMD2"
     cat "${te}2b" >&2
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -8289,8 +8187,7 @@ else
     if [ "$DEBUG" ];   then cat "${te}2a" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -8325,19 +8222,16 @@ if [ $? -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1a" "${te}1b" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
    cat "${te}1a" "${te}1b" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -8371,14 +8265,12 @@ PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //')
 rc=$(cat "$td/test$N.rc0")
 if [ "$rc" = 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -8422,8 +8314,7 @@ if [ $rc1 != 0 -o $rc2 != 0 ]; then
     cat "${te}1" >&2
     echo "$CMD1"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - "${tf}" >"$tdiff"; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -8432,8 +8323,7 @@ elif echo "$da" |diff - "${tf}" >"$tdiff"; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD0 &"
@@ -8444,8 +8334,7 @@ else
     cat "${te}2" >&2
     echo "// diff:" >&2
     cat "${tdiff}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -8462,8 +8351,7 @@ TEST="$NAME: UDP6-LISTEN with bind"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8485,18 +8373,15 @@ if [ $rc2 -ne 0 ]; then
    echo "$CMD1 &"
    echo "$CMD2"
    cat "${te}1" "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8512,8 +8397,7 @@ TEST="$NAME: use of multiple tcpwrapper enabling options"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8537,18 +8421,15 @@ if [ $rc2 -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8564,8 +8445,7 @@ TEST="$NAME: specification of TCP6 address in hosts.allow"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8591,18 +8471,15 @@ if [ $rc2 -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8616,8 +8493,7 @@ TEST="$NAME: UDP/IPv4 broadcast"
 if ! eval $NUMCOND; then :;
 elif [ -z "$BCADDR" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8644,13 +8520,11 @@ if [ "$rc2" -ne 0 ]; then
     echo "$CMD2"
     cat "${te}1"
     cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$tut" ]; then
@@ -8658,8 +8532,7 @@ else
 	echo "$CMD2"
     fi
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8676,12 +8549,10 @@ TEST="$NAME: raw IPv4 broadcast"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ -z "$BCADDR" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
 else
@@ -8714,8 +8585,7 @@ if [ "$rc2" -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD1 &"
@@ -8724,16 +8594,14 @@ elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD2"; fi
 	if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8763,16 +8631,13 @@ TEST="$NAME: UDP/IPv4 multicast, send only"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 udp) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs UDP4-RECV UDP4-SENDTO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions ip-add-membership bind) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8797,8 +8662,7 @@ if [ "$rc2" -ne 0 ]; then
    cat "${te}1" >&2
    echo "$CMD2"
    cat "${te}2" >&2
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    echo "$CMD1 &"
@@ -8806,16 +8670,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    echo "$CMD2"
    cat "${te}2" >&2
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8828,12 +8690,10 @@ TEST="$NAME: IPv4 multicast"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8860,18 +8720,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8888,24 +8745,19 @@ TEST="$NAME: UDP/IPv6 multicast"
 if ! eval $NUMCOND; then :;
 elif ! f=$(testfeats ip6 udp); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions ipv6-join-group) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 does not work on $HOSTNAME${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::1]:12002 >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 multicasting does not work${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -8931,14 +8783,11 @@ if [ "$rc2" -ne 0 ]; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 #    if ! [ "$UNAME" = Linux ] || ! [[ $(uname -r) =~ ^2\.* ]] || ! [[ ^3\.* ]] || ! [[ ^4\.[0-4]\.* ]]; then
 #   $PRINTF "${YELLOW}works only on Linux up to about 4.4${NORMAL}\n" $N
-#   numCANT=$((numCANT+1))
-#   listCANT="$listCANT $N"
+#   cant
 #    else
    $PRINTF "$FAILED\n"
    echo "$CMD1 &"
@@ -8946,8 +8795,7 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    echo "$CMD2"
    cat "${te}2"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+   failed
 #    fi
 else
     $PRINTF "$OK\n"
@@ -8955,8 +8803,7 @@ else
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -8993,8 +8840,7 @@ if [ "$rc2" -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD1 &"
@@ -9003,16 +8849,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo diff: >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -9025,12 +8869,10 @@ TEST="$NAME: IPv4 multicast, with reply"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9056,13 +8898,11 @@ if [ "$rc2" -ne 0 ]; then
     echo "$CMD2"
     cat "${te}1"
     cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$tut" ]; then
@@ -9070,8 +8910,7 @@ else
 	echo "$CMD2"
     fi
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9089,12 +8928,10 @@ TEST="$NAME: reading data sent through tun interface"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 tun) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9119,21 +8956,18 @@ if [ $? -ne 0 ]; then
     echo "$CMD &"
     echo "$CMD1"
     cat "${te}" "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD &"
     echo "$CMD1"
     cat "$tdiff"
     cat "${te}" "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9151,12 +8985,10 @@ TEST="$NAME: pass data through tun interface using INTERFACE"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats ip4 tun interface) || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9183,8 +9015,7 @@ if [ "$rc1" -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD0 &"
@@ -9193,16 +9024,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1" >&2
     echo "// diff:"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9216,8 +9045,7 @@ TEST="$NAME: abstract UNIX stream socket, listen and connect"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats abstract-unixsocket); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.socket"
 tf="$td/test$N.stdout"
@@ -9242,8 +9070,7 @@ if [ $? -ne 0 ]; then
     cat "${te}s"
     echo "$CMD"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     kill "$pids" 2>/dev/null
     $PRINTF "$FAILED:\n"
@@ -9252,13 +9079,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
     echo "$CMD"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi # !(rc -ne 0)
 wait
 fi ;; # NUMCOND, feats
@@ -9273,8 +9098,7 @@ TEST="$NAME: abstract UNIX datagram"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats abstract-unixsocket); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9299,8 +9123,7 @@ if [ $rc2 -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD1 &"
@@ -9308,16 +9131,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD2"
     cat "${te}2" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9331,8 +9152,7 @@ TEST="$NAME: abstract UNIX datagram receive"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats abstract-unixsocket); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.socket"
 tf="$td/test$N.stdout"
@@ -9358,8 +9178,7 @@ if [ "$rc2" -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD1 &"
@@ -9367,16 +9186,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD2"
     cat "${te}2" >&2
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9395,8 +9212,7 @@ TEST="$NAME: abstract bind"
 if ! eval $NUMCOND; then :; 
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9412,21 +9228,18 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1"
     echo "rc=$rc1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff -q - $tf; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD1" >&2
     cat "${te}1" >&2
     echo "$da" |diff - "$tf" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -9453,8 +9266,7 @@ TEST="$NAME: socat handles data buffered by openssl"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats openssl) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.out"
 te="$td/test$N.err"
@@ -9479,13 +9291,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD2"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 wait
 fi # NUMCOND, featsesac
@@ -9495,7 +9305,7 @@ N=$((N+1))
 
 
 # test: there is a bug with the readbytes option: when the socket delivered
-# exacly that many bytes as specified with readbytes and the stays idle (no
+# exactly that many bytes as specified with readbytes and the stays idle (no
 # more data, no EOF), socat waits for more data instead of generating EOF on
 # this in put stream.
 NAME=READBYTES_EOF
@@ -9509,8 +9319,7 @@ TEST="$NAME: trigger EOF after that many bytes, even when socket idle"
 if ! eval $NUMCOND; then :;
 elif false; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tr="$td/test$N.ref"
 ti="$td/test$N.in"
@@ -9524,13 +9333,11 @@ printf "test $F_n $TEST... " $N
 if test -s "$to"; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -9542,7 +9349,7 @@ N=$((N+1))
 NAME=EXECPTYKILL
 case "$TESTS" in
 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*)
-TEST="$NAME: exec:...,pty explicitely kills sub process"
+TEST="$NAME: exec:...,pty explicitly kills sub process"
 # we want to check if the exec'd sub process is killed in time
 # for this we have a shell script that generates a file after two seconds;
 # it should be killed after one second, so if the file was generated the test
@@ -9574,18 +9381,15 @@ if [ $? -ne 0 ]; then
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ -f "$tda" ]; then
     $PRINTF "$FAILED\n"
     cat "${te}1" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -9625,18 +9429,15 @@ if [ $? -ne 0 ]; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid1 2>/dev/null
 wait
@@ -9670,15 +9471,13 @@ TEST="$NAME: more than FOPEN_MAX FDs in use"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 REDIR=
 #set -vx
 if [ -z "$FOPEN_MAX" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     if [ $FOPEN_MAX -lt 270 ]; then
 	OPEN_FILES=$FOPEN_MAX	# more than the highest FOPEN_MAX
@@ -9691,9 +9490,9 @@ i=3; while [ "$i" -lt "$OPEN_FILES" ]; do
     i=$((i+1))
 done
 #echo "$REDIR"
-#testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 
+#testecho "$N" "$NAME" "$TEST" "" "pipe" "$opts -T 3" "" 1 
 #set -vx
-eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR
+eval testecho "\"$N\"" "\"$NAME\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR
 #set +vx
 fi # could determine FOPEN_MAX
 fi ;; # NUMCOND
@@ -9732,24 +9531,20 @@ l="$(childprocess $pid1)"
 kill $pid1 2>/dev/null; wait
 if [ $rc2 -ne 0 ]; then
     $PRINTF "$NO_RESULT (client failed)\n"	# already handled in test UDP4STREAM
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$NO_RESULT (diff failed)\n"	# already handled in test UDP4STREAM
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif $(isdefunct "$l"); then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
     echo "$CMD2"
     cat "${te}1" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -9792,16 +9587,14 @@ if [ $rc2 -ne 0 ]; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$NO_RESULT\n"	# already handled in test UDP4DGRAM
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif $(isdefunct "$l"); then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &"
@@ -9809,16 +9602,14 @@ elif $(isdefunct "$l"); then
     echo "$CMD2"
     cat "${te}2" >&2
     cat "${te}1" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -9838,8 +9629,7 @@ TEST="$NAME: raw IPv4 receive with bind"
 if ! eval $NUMCOND; then :;
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -9865,18 +9655,15 @@ if [ "$rc2" -ne 0 ]; then
    echo "$CMD2"
    cat "${te}1"
    cat "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, root
 esac
@@ -9915,8 +9702,7 @@ rc2b=$?
 kill $pid1 2>/dev/null; wait
 if [ $rc2b -ne 0 ]; then
     $PRINTF "$NO_RESULT\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD1 &" >&2
@@ -9924,13 +9710,11 @@ elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then
     echo "$CMD2" >&2
     cat "${te}2b" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -9957,20 +9741,17 @@ echo "$da" |diff - "$tf" >"$tdiff"
 if [ "$rc" -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ -s "$tdiff" ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo diff:
     cat "$tdiff"
     if [ -n "$debug" ]; then cat $te; fi
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10012,24 +9793,20 @@ fi
 kill $pid1 2>/dev/null; wait
 if [ $rc1 -ne 0 ]; then
     $PRINTF "$NO_RESULT\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $nsocks -eq 0 ]; then
     $PRINTF "$NO_RESULT\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $nsocks -ne 1 ]; then
     $PRINTF "$FAILED ($nsocks listening sockets)\n"
     echo "$CMD0 &"
     echo "$CMD1"
     cat "${te}0" "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10060,19 +9837,16 @@ if [ $rc0 != 0 ]; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - "$tf" >/dev/null; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     echo "$CMD1"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi ;; # NUMCOND
 esac
@@ -10098,18 +9872,15 @@ if [ $? -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10138,13 +9909,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED: diff:\n"
     cat "$tdiff"
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat $te; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10169,20 +9938,16 @@ if ! eval $NUMCOND; then :;
 #elif [[ "$PF" == "#*" ]]; then :
 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats ${KEYW%[46]} IP${KEYW##*[A-Z]}); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs${proto} >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available on host${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testoptions $SCM_RECV >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -10238,8 +10003,7 @@ if [ "$rc1" -ne 0 ]; then
     echo "$CMD1"
     grep " $LEVELS " "${te}0"
     grep " $LEVELS " "${te}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then
     $PRINTF "$FAILED\n"
     echo "variable $SCM_TYPE: $SCM_NAME not set"
@@ -10247,8 +10011,7 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then
     echo "$CMD1"
     grep " $LEVELS " "${te}0"
     grep " $LEVELS " "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/null; then
     $PRINTF "$FAILED\n"
     badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')"
@@ -10257,21 +10020,18 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/
     echo "$CMD1"
     grep " $LEVELS " "${te}0"
     grep " $LEVELS " "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then grep " $LEVELS " "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi
     if [ "$DEBUG" ];   then grep " $LEVELS " "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 else # option is not supported
     $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 fi # option is not supported
 fi # NUMCOND, root, feats
  ;;
@@ -10330,12 +10090,10 @@ TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats $FEAT); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs${protov} >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -10373,8 +10131,7 @@ if [ $rc1 != 0 ]; then
     cat "${te}0"
     echo "$CMD1"
     cat "${te}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
     "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
     \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
@@ -10387,8 +10144,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g"
 	echo "$CMD1"
 	cat "${te}1"
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -10397,8 +10153,7 @@ else
     cat "${te}1"
     echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
     diff - "${tf}"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND, feats
  ;;
@@ -10437,12 +10192,10 @@ TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME"
 if ! eval $NUMCOND; then :;
 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$PF" = "IP6" ] && ( ! feat=$(testfeats ip6) || ! runsip6 ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -10494,8 +10247,7 @@ if [ "$rc1" -ne 0 ]; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 #elif ! $GREP_E "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then
 #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then
 elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then
@@ -10505,21 +10257,18 @@ elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 else # option is not supported
     $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 fi # option is not supported
 fi ;; # NUMCOND, feats
 esac
@@ -10587,8 +10336,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10596,13 +10344,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi # NUMCOND
  ;;
@@ -10618,8 +10364,7 @@ TEST="$NAME: socket connect with TCP/IPv6"
 if ! eval $NUMCOND; then :;
 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # start a TCP6-LISTEN process that echoes data, and send test data using
 # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned.
@@ -10648,8 +10393,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10657,13 +10401,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10698,8 +10440,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10707,13 +10448,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10754,8 +10493,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10763,13 +10501,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10808,8 +10544,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10817,13 +10552,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10863,8 +10596,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10872,13 +10604,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10920,8 +10650,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10929,13 +10658,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10976,8 +10703,7 @@ if [ "$rc1" -ne 0 ]; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
@@ -10985,13 +10711,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    cat "${te}0"
    echo "$CMD1"
    cat "${te}1"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat $te; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND
 esac
@@ -10999,14 +10723,13 @@ N=$((N+1))
 
 NAME=SOCKETRANGEMASK
 case "$TESTS" in
-*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: security of generic socket-listen with RANGE option"
 if ! eval $NUMCOND; then :;
 elif [ -z "$SECONDADDR" ]; then
     # we need access to more loopback addresses
     $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4; ts1p=$(printf "%04x" $PORT);
 testserversec "$N" "$TEST" "$opts" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,$REUSEADDR,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0
@@ -11030,8 +10753,7 @@ if ! eval $NUMCOND; then :;
 elif [ -z "$TIOCEXCL" ]; then
     # we use the numeric value of TIOCEXL which is system dependent
     $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tp="$td/test$N.pty"
 tf="$td/test$N.stdout"
@@ -11056,21 +10778,18 @@ if ! echo "$da" |diff - "$tf" >/dev/null; then
     echo "$CMD0 &"
     echo "$CMD1"
     echo "$da" |diff - "$tf"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc2 -eq 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
     echo "$CMD1"
     echo "$CMD2"
     cat "${te}0" "${te}1" "${te}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND, TIOCEXCL
 ;;
@@ -11095,8 +10814,7 @@ if ! eval $NUMCOND; then :;
 elif [ -z "$TCP_MAXSEG" ]; then
     # we use the numeric value of TCP_MAXSEG which might be system dependent
     $PRINTF "test $F_n $TEST... ${YELLOW}value of TCPMAXSEG not known${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -11123,29 +10841,25 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
     echo "$CMD1"
     cat ${te}1
     cat "$tdiff"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc1 -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
     cat ${te}0
     echo "$CMD1"
     cat ${te}1
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ $rc2 -eq 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
     cat ${te}0
     echo "$CMD2"
     cat ${te}2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -11174,8 +10888,7 @@ if ! eval $NUMCOND; then :;
 elif [ -z "$SO_REUSEADDR" ]; then
     # we use the numeric value of SO_REUSEADDR which might be system dependent
     $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -11206,8 +10919,7 @@ if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then
     echo "$CMD1"
     cat ${te}1
     cat "${tdiff}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc3 -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
@@ -11218,8 +10930,7 @@ elif [ $rc3 -ne 0 ]; then
     cat ${te}2
     echo "$CMD3"
     cat ${te}3
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
@@ -11231,13 +10942,11 @@ elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then
     echo "$CMD3"
     cat ${te}3
     cat "${tdiff}3"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND, SO_REUSEADDR
  ;;
@@ -11252,15 +10961,12 @@ TEST="$NAME: echo via connection to SCTP V4 socket"
 if ! eval $NUMCOND; then :;
 elif ! testfeats sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
-    listCANT="$listCANT $N"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
     # RHEL5 based systems became unusable when an sctp socket was created but
     # module sctp not loaded
     $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -11282,18 +10988,15 @@ if [ $? -ne 0 ]; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid1 2>/dev/null
 wait
@@ -11309,12 +11012,10 @@ TEST="$NAME: echo via connection to SCTP V6 socket"
 if ! eval $NUMCOND; then :;
 elif ! testfeats sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
     $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -11336,18 +11037,15 @@ if [ $? -ne 0 ]; then
    cat "${te}1"
    echo "$CMD2"
    cat "${te}2"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
    $PRINTF "$FAILED: diff:\n"
    cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+   failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 fi # NUMCOND, feats
@@ -11380,28 +11078,23 @@ TEST="$NAME: OpenSSL connections survive renogotiation"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then
+    cant
+elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then
     # openssl s_client apparently provides renegotiation only up to version 1.2
     $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-init_openssl_s_client
 newport tcp4
 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
 #CMD1="openssl s_client -port $PORT -verify 0" 	# not with openssl 1.1.0g
@@ -11419,16 +11112,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif grep -i "Connection refused" "${te}1" >/dev/null; then
     $PRINTF "$CANT (conn failed)\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD0 &"
@@ -11437,8 +11128,7 @@ else
     cat "${te}1" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11460,21 +11150,17 @@ TEST="$NAME: OpenSSL connections do not block after renogotiation"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then
+    cant
+elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then
     # openssl s_client apparently provides renegotiation only up to version 1.2
     $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -11499,16 +11185,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif grep -i "Connection refused" "${te}1" >/dev/null; then
     $PRINTF "$CANT (conn failed)\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$FAILED (diff)\n"
     echo "$CMD0 &"
@@ -11517,8 +11201,7 @@ else
     cat "${te}1" >&2
     echo "// diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11549,14 +11232,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0"
 rc0=$?
 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11584,14 +11265,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0"
 rc0=$?
 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11620,14 +11299,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0"
 rc0=$?
 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11667,16 +11344,14 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif grep -q ' W ' "${te}1"; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif  ! echo "$da" |diff - ${tf}1 >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -11684,12 +11359,10 @@ elif  ! echo "$da" |diff - ${tf}1 >"$tdiff"; then
     cat "${te}0"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -11715,14 +11388,12 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ $rc0 -ne 0 -a -f "$tf" ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11747,14 +11418,12 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ $rc0 -ne 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11794,26 +11463,21 @@ if [ $rc1 -ne 0 ]; then
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 elif [ ! -e "$tw" ]; then 
 	$PRINTF "$NO_RESULT (no wc -c output)\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
 elif [ "$bytes" -eq $(cat "$tw") ]; then
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
 else
 	$PRINTF "$FAILED (incomplete)\n"
 	echo "transferred only $(cat $tw) of $bytes bytes" >&2
@@ -11821,9 +11485,7 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 fi
 fi # NUMCOND
  ;;
@@ -11838,12 +11500,10 @@ TEST="$NAME: OpenSSL server with cipher aNULL "
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -11864,13 +11524,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     #cat "${te}1"
     #cat "${te}2"
     #cat "$tdiff"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -11886,10 +11544,10 @@ PROTO=$KEYW
 proto="$(tolower "$PROTO")"
 feat="$(tolower "$FEAT")"
 # test the max-children option on really connection oriented sockets
-NAME=${KEYW}MAXCHILDREN
+NAME=${KEYW}_L_MAXCHILDREN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*)
-TEST="$NAME: max-children option"
+TEST="$NAME: max-children option with $PROTO-LISTEN"
 # start a listen process with max-children=1; connect with a client, let it
 # sleep some time before sending data; connect with second client that sends
 # data immediately. If max-children is working correctly the first data should
@@ -11897,12 +11555,10 @@ TEST="$NAME: max-children option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats "$FEAT" >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs$RUNS >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 case "X$IPPORT" in
     "XPORT")
@@ -11934,8 +11590,7 @@ relsleep 2
 kill $pid1 $pid2 $pid0 2>/dev/null; wait
 if echo -e "$da 1\n$da 2" |diff - $tf >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -11945,8 +11600,7 @@ else
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -11973,10 +11627,10 @@ RUNS=$(tolower $KEYW)
 PROTO=$KEYW
 proto="$(tolower "$PROTO")"
 # test the max-children option on pseudo connected sockets
-NAME=${KEYW}MAXCHILDREN
+NAME=${KEYW}_L_MAXCHILDREN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
-TEST="$NAME: max-children option"
+TEST="$NAME: max-children option with $PROTO-LISTEN"
 # start a listen process with max-children=1; connect with a client, let it
 # send data and then sleep; connect with second client that wants to send
 # data immediately, but keep first client active until server terminates.
@@ -11985,12 +11639,10 @@ TEST="$NAME: max-children option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats "$FEAT" >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs$RUNS >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 case "X$IPPORT" in
     "XPORT")
@@ -12024,8 +11676,7 @@ cpids="$(childpids $pid0)"
 kill $pid1 $pid2 $pid0 $cpids 2>/dev/null; wait
 if echo -e "$da 1" |diff - $tf >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -12035,8 +11686,7 @@ else
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12066,8 +11716,7 @@ TEST="$NAME: test for buffer overflow in readline prompt handling"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testfeats readline pty); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -12085,14 +11734,12 @@ if [ $rc -ne 0 ]; then
     $PRINTF "${YELLOW}framework failed${NORMAL}\n"
 elif [ $rc0 -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     grep -v ^rc= "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12122,7 +11769,8 @@ te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 RLIMIT_NOFILE="$(ulimit -n)"
-if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
+#if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
+if ! re_match "$RLIMIT_NOFILE" '^[0-9][0-9]*$'; then
     $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}"
 else
 if [ $RLIMIT_NOFILE -gt 1024 ]; then
@@ -12154,8 +11802,7 @@ if [ $rc2 -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -12164,8 +11811,7 @@ elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -12174,8 +11820,7 @@ else
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # ulimit -n
 fi # NUMCOND
@@ -12185,7 +11830,9 @@ N=$((N+1))
 
 
 if false; then	# this overflow is not reliably reproducable
-# socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command line paramters when copying them into the HTTP request buffer. This could lead to a buffer overflow.
+# Socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command
+# line parameters when copying them into the HTTP request buffer. This could
+# lead to a buffer overflow.
 NAME=PROXY_ADDR_OVFL
 case "$TESTS" in
 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*)
@@ -12215,19 +11862,16 @@ rc1=$?
 if [ $rc1 -lt 128 ]; then
     if [ "$EF" ]; then
 	$PRINTF "$OK\n"
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     else
 	$PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n"
-	numCANT=$((num+1))
-	listCANT="$listCANT $N"
+	cant
     fi
 else
     $PRINTF "$FAILED\n"
     echo "$CMD1"
     cat "${te}"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12268,26 +11912,21 @@ if [ -z "$KEEPALIVE" ]; then
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 elif [ "$KEEPALIVE" = "1" ]; then
     $PRINTF "$OK\n";
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED (KEEPALIVE=$KEEPALIVE)\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12307,8 +11946,7 @@ TEST="$NAME: test OPENSSL-CONNECT with bind option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf0="$td/test$N.0.stdout"
@@ -12333,8 +11971,7 @@ if [ "$rc1" -ne 0 ]; then
     echo "$CMD1"
     cat "$te0"
     cat "$te1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - $tf1 >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -12342,12 +11979,10 @@ elif ! echo "$da" |diff - $tf1 >"$tdiff"; then
     cat "${te}0"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -12359,14 +11994,13 @@ N=$((N+1))
 # had a bug that converted a bit mask of 0 internally to 0xffffffff
 NAME=TCP4RANGE_0BITS
 case "$TESTS" in
-*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: correct evaluation of range mask 0"
 if ! eval $NUMCOND; then :;
 elif [ -z "$SECONDADDR" ]; then
     # we need access to a second address
     $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -12386,24 +12020,20 @@ sleep 1
 kill $pid0 2>/dev/null; wait
 if [ $rc1 != 0 ]; then
     $PRINTF "${YELLOW}invocation failed${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! [ -f "$tf" ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "${YELLOW}diff failed${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 
 fi ;; # $SECONDADDR, NUMCOND
@@ -12429,8 +12059,7 @@ FEAT=$(echo "$ssldist" |tr a-z A-Z)
 if ! eval $NUMCOND; then :;
 elif ! testfeats $FEAT >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -12469,8 +12098,7 @@ if [ $rc1 != 0 ]; then
     cat "${te}0"
     echo "$CMD1"
     cat "${te}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")";
     [ "$effval" = "$VALUE" ]; then
     $PRINTF "$OK\n"
@@ -12480,8 +12108,7 @@ elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]
 	echo "$CMD1"
 	cat "${te}1"
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "expected \"$VALUE\", got \"$effval\"" >&2
@@ -12489,8 +12116,7 @@ else
     cat "${te}0"
     echo "$CMD1"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND, feats
  ;;
@@ -12552,18 +12178,15 @@ if [ "$ERRNOENT" ]; then
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 elif [ "$perms" != "600" ]; then
     $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n"
     echo "$CMD0 &"
     cat "$te0"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    let numOK=numOK+1
-    listOK="$listOK $N"
+    ok
 fi
                                set +xv
 fi # NUMCOND
@@ -12628,18 +12251,15 @@ if [ "$ERRNOENT" ]; then
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 elif [ "$perms" != "511" ]; then
     $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n"
     echo "$CMD0 &"
     cat "$te0"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    let numOK=numOK+1
-    listOK="$listOK $N"
+    ok
 fi
                                       set +vx
 fi # NUMCOND
@@ -12679,8 +12299,7 @@ TEST="$NAME: $ADDR applies option user"
 if ! eval $NUMCOND; then :;
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tlog="$td/test$N.log"
 te0="$td/test$N.0.stderr"
@@ -12704,20 +12323,17 @@ if [ "$ERRNOENT" ]; then
     echo "$CMD0 &"
     cat "$te0" >&2
     cat "$tlog" >&2
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 elif [ "$user" != "$SUBSTUSER" ]; then
-    $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n"
+    $PRINTF "${FAILED}(user \"$user\", expected \"$SUBSTUSER\")\n"
     echo "$CMD0 &"
     cat "$te0" >&2
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
 fi
                                       set +vx
 fi # NUMCOND
@@ -12777,19 +12393,16 @@ if [ $rc1 != 0 ]; then
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! [ $crit $tsock ]; then
     $PRINTF "$OK\n"
-    let numOK=numOK+1
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12846,19 +12459,16 @@ if [ $rc1 != 0 ]; then
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! [ $crit $tsock ]; then
     $PRINTF "$OK\n"
-    let numOK=numOK+1
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "$te0"
     cat "$tlog"
-    let numFAIL=numFAIL+1
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -12880,14 +12490,13 @@ case "$TESTS" in
 TEST="$NAME: SYSTEM address does not shutdown its parents addresses"
 # start an OpenSSL echo server using SYSTEM:cat
 # start an OpenSSL client that sends data
-# when the client recieves its data and terminates without error the test succeeded
+# when the client receives its data and terminates without error the test succeeded
 # in case of the bug the client issues an error like:
 # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -12911,8 +12520,7 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then
     $PRINTF "$FAILED\n"
     echo "diff:"
@@ -12921,12 +12529,10 @@ elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -12958,19 +12564,16 @@ if [ ! -f "$t0rc" ]; then
     echo "no return code of CMD0 stored" >&2
     echo "$CMD0 &"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "CMD0 exited with $(cat $t0rc), expected 1"
     echo "$CMD0 &"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -12998,12 +12601,10 @@ TEST="$NAME: test OpenSSL method $method"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -13016,8 +12617,7 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,veri
 printf "test $F_n $TEST... " $N
 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
     $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -13030,13 +12630,11 @@ fi
 echo "$da" |diff - "${tf}1" >"$tdiff" 2>/dev/null
 if [ $w0 -eq 0 ] && [ -f "${tf}1" ] && ! [ -s "$tdiff" ]; then
     $PRINTF "${YELLOW}WARN${NORMAL} (obsolete method succeeds)\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$OK (obsolete method fails)\n"
     cat "$tdiff"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
     if [ "$VERBOSE" ]; then
 	echo "  $CMD0"
@@ -13066,19 +12664,18 @@ TEST="$NAME: test OpenSSL method $method"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-if [[ "$method" =~ DTLS* ]]; then
+#if [[ "$method" =~ DTLS* ]]; then
+if re_match "$method" '^DTLS.*'; then
     newport udp4
 else
     newport tcp4
@@ -13088,12 +12685,12 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,ver
 printf "test $F_n $TEST... " $N
 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
     $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
-if [[ "$method" =~ DTLS* ]]; then
+#if [[ "$method" =~ DTLS* ]]; then
+if re_match "$method" '^DTLS.*'; then
     waitudp4port $PORT 1
 else
     waittcp4port $PORT 1
@@ -13103,8 +12700,7 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if echo "$da" |diff - "${tf}1" >"$tdiff"; then 
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
     if [ "$VERBOSE" ]; then
 	echo "  $CMD0"
 	echo "  echo \"$da\" |$CMD1"
@@ -13116,8 +12712,7 @@ else
     echo "$CMD1"
     cat "${te}1"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
     #esac
 fi
 fi # !DTLS1 hang
@@ -13139,17 +12734,14 @@ TEST="$NAME: security of OpenSSL server with openssl-min-proto-version"
 if ! eval $NUMCOND; then :;
 elif ! testaddrs openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions openssl-min-proto-version); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! [ "$OPENSSL_LATEST_PROTO_VERSION" -a "$OPENSSL_BEFORELAST_PROTO_VERSION" -a \
          "$OPENSSL_LATEST_PROTO_VERSION" != "$OPENSSL_BEFORELAST_PROTO_VERSION" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}cannot determine two available SSL/TLS versions${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     gentestcert testsrv
     newport tcp4
@@ -13177,15 +12769,13 @@ $CMD >/dev/null 2>"${te}"
 rc=$?
 if [ $rc -eq 1 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}"
     echo "command did not terminate with error!"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13214,12 +12804,10 @@ if [ $rc0 -eq 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -13248,12 +12836,10 @@ if [ $rc0 -eq 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -13275,8 +12861,7 @@ TEST="$NAME: test the so-reuseaddr option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testoptions so-reuseaddr); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4; tp="$PORT"
 tf="$td/test$N.stdout"
@@ -13304,8 +12889,7 @@ if ! echo "$da" |diff - "$tf"; then
     $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
     echo "$CMD0 &"
     echo "$CMD1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc3 -ne 0 ]; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
@@ -13313,8 +12897,7 @@ elif [ $rc3 -ne 0 ]; then
     echo "$CMD2 &"
     echo "$CMD3"
     cat "${te}2" "${te}3"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "${tf}3"; then
     $PRINTF "$FAILED: $TRACE $SOCAT:\n"
     echo "$CMD0 &"
@@ -13322,13 +12905,11 @@ elif ! echo "$da" |diff - "${tf}3"; then
     echo "$CMD2 &"
     echo "$CMD3"
     echo "$da" |diff - "${tf}3"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND, SO_REUSEADDR
  ;;
@@ -13349,8 +12930,7 @@ TEST="$NAME: test the so-reuseport option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testoptions so-reuseport); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4; tp="$PORT"
 tf="$td/test$N.stdout"
@@ -13381,8 +12961,7 @@ if ! echo "$da2" |diff - "${tf}2"; then
     cat "${te}1"
     echo "$CMD2"
     cat "${te}2"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc3 -ne 0 ]; then
     $PRINTF "$FAILED:\n"
     echo "$CMD0 &"
@@ -13393,8 +12972,7 @@ elif [ $rc3 -ne 0 ]; then
     cat "${te}2"
     echo "$CMD3"
     cat "${te}3"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da2" |diff - "${tf}2"; then
     $PRINTF "$FAILED:\n"
     echo "$CMD0 &"
@@ -13406,8 +12984,7 @@ elif ! echo "$da2" |diff - "${tf}2"; then
     echo "$CMD3"
     cat "${te}3"
     echo "$da2" |diff - "${tf}2"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da3" |diff - "${tf}3"; then
     $PRINTF "$FAILED:\n"
     echo "$CMD0 &"
@@ -13419,13 +12996,11 @@ elif ! echo "$da3" |diff - "${tf}3"; then
     echo "$CMD3"
     cat "${te}3"
     echo "$da3" |diff - "${tf}3"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND, SO_REUSEPORT
  ;;
@@ -13451,15 +13026,13 @@ eval "$CMD0" >"${tf}0" 2>"${te}0"
 rc1=$?
 if echo "$da" |diff - "${tf}0" >"$tdiff"; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13479,12 +13052,10 @@ TEST="$NAME: test OpenSSL ECDHE"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! openssl ciphers |grep -q '\<ECDHE\>'; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl: cipher ECDHE not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -13511,12 +13082,10 @@ if [ $rc1 -ne 0 ]; then
     echo "client and stderr:" >&2
     echo "$CMD1"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - "${tf}1" >"$tdiff"; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "server and stderr:" >&2
@@ -13525,8 +13094,7 @@ else
     echo "client and stderr:" >&2
     echo "$CMD0 &"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13544,7 +13112,18 @@ TEST="$NAME: is option ipv6-join-group used"
 # Terminate immediately, do not transfer data.
 # If socat exits with 0 the test succeeds.
 # Up to 1.7.3.1 it failed with "1 option(s) could not be used"
-if ! eval $NUMCOND; then :; else
+if ! eval $NUMCOND; then :;
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "IP6 UDP GOPEN" \
+		  "UDP6-RECV GOPEN" \
+		  "ipv6-join-group" \
+		  "udp6" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
@@ -13556,14 +13135,12 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ $rc0 -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13577,7 +13154,7 @@ NAME=DIAG_FDIN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
 TEST="$NAME: test use of fdin=3"
-# Use FD 3 explicitely with fdin and test if Socat passes data to executed
+# Use FD 3 explicitly with fdin and test if Socat passes data to executed
 # program
 if ! eval $NUMCOND; then :; else
 tf="$td/test$N.stdout"
@@ -13592,19 +13169,16 @@ if [ $rc0 -ne 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - ${tf}0 >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13624,13 +13198,11 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ "$rc0" = "1" ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi ;; # NUMCOND
 esac
@@ -13661,16 +13233,14 @@ $CMD1  2>"${te}1"
 rc0=$?
 if [ $rc0 -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
     echo "$CMD1"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13697,14 +13267,12 @@ printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0"
 if ! grep -q "ai_socktype not supported" ${te}0; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13735,16 +13303,14 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if [ $(grep "socket 2 (fd .*) is at EOF" ${te}0 |wc -l) -eq 1 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13780,19 +13346,16 @@ if [ $rc0 -eq 0 ]; then
     $PRINTF "$FAILED (rc=$rc0)\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif [ $rc0 -eq 1 ]; then
     if grep -q "buffer size option (-b) to big" "${te}0"; then
 	$PRINTF "$OK\n"
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     else
 	$PRINTF "$FAILED (rc=$rc0)\n"
 	echo "$CMD0"
 	cat "${te}0"
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     fi
 fi
 fi # NUMCOND
@@ -13819,14 +13382,12 @@ if grep -q -i -e "syntax error" -e "unexpected end" "${te}0"; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
     if [ "$debug" ]; then cat ${te} >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13848,8 +13409,7 @@ TEST="$NAME: Service name resolution works with SCTP"
 if ! eval $NUMCOND; then :;
 elif ! runssctp4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -13859,18 +13419,15 @@ printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0"
 if [ $? -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif grep -q "Connection refused" ${te}0; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -13888,8 +13445,7 @@ TEST="$NAME: echo via file with o-direct"
 if ! eval $NUMCOND; then :;
 elif ! testoptions o-direct >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}o-direct not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.file"
 to="$td/test$N.stdout"
@@ -13907,29 +13463,26 @@ if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then
 	    $PRINTF "${FAILED}\n"
 	    echo "$CMD" >&2
 	    cat "$te" >&2
-	    numFAIL=$((numFAIL+1))
-	    listFAIL="$listFAIL $N" ;;
-	*) $PRINTF "${YELLOW}inable file system${NORMAL}\n"
-	    numCANT=$((numCANT+1))
-	    listCANT="$listCANT $N" ;;
+	    failed ;;
+	*) $PRINTF "${YELLOW}unsupported file system${NORMAL}\n"
+	    if [ "$VERBOSE" ]; then echo "$CMD"; fi
+	    if [ "$DEBUG" ];   then cat "${te}" >&2; fi
+	    cant ;;
     esac
 elif [ $rc -ne 0 ]; then
     $PRINTF "${FAILED}:\n"
     echo "$CMD" >&2
     cat "$te" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$to" >$tdiff; then
     $PRINTF "${FAILED}\n"
     echo "$CMD" >&2
     cat "$te" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi # command ok
 fi ;; # NUMCOND, feats
 esac
@@ -13963,8 +13516,7 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if test -S $uns && ! test -S $unc; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -13972,8 +13524,7 @@ else
     ls -ld $uns $unc
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14007,8 +13558,7 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if test -S $uns && ! test -S $unc; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -14016,8 +13566,7 @@ else
     ls -ld $uns $unc
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14035,20 +13584,19 @@ TEST="$NAME: OpenSSL DTLS client"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 udp openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-dtls-client); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
+elif init_openssl_s_server; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_SERVER_DTLS" ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_server${NORMAL}\n" $N
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -14073,13 +13621,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "$te"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 fi ;; # NUMCOND, feats
 esac
@@ -14095,25 +13641,23 @@ TEST="$NAME: OpenSSL DTLS server"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-dtls-server); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
+    cant
+elif init_openssl_s_client; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_CLIENT_DTLS" ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_client${NORMAL}\n" $N
+    cant
+elif re_match "$(openssl version |awk '{print($2);}')" '^0\.9\.8[a-ce]'; then
     # also on NetBSD-4 with openssl-0.9.8e
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -14133,8 +13677,7 @@ rc=$?
 kill $pid1 2>/dev/null; wait
 if echo "$da" |diff - $tf >"$tdiff"; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD1 &"
@@ -14142,8 +13685,7 @@ else
     echo "$CMD"
     cat "$te"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14158,12 +13700,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (hostname)"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestaltcert testalt
 tf="$td/test$N.stdout"
@@ -14185,13 +13725,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD1" >&2
     cat "${te}1" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -14206,12 +13744,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv4 address)"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 openssl >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestaltcert testalt
 tf="$td/test$N.stdout"
@@ -14233,13 +13769,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD1" >&2
     cat "${te}1" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -14254,12 +13788,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv6 address)"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip6 openssl >/dev/null || ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestaltcert testalt
 tf="$td/test$N.stdout"
@@ -14281,13 +13813,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     echo "$CMD1" >&2
     cat "${te}1" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -14307,8 +13837,7 @@ TEST="$NAME: raw dump of transferred data"
 if ! eval $NUMCOND; then :;
 elif [ $($SOCAT -h |grep -e ' -[rR] ' |wc -l) -lt 2 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Options -r, -R not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -14338,12 +13867,10 @@ if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; t
     cat $tdiff1 >&2
     echo "Right-to-left:" >&2
     cat $tdiff2 >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -14363,16 +13890,13 @@ SNISERVER=badssl.com
 if ! eval $NUMCOND; then :;
 elif ! testaddrs openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions openssl-snihost); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ -z "$INTERNET" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -14384,14 +13908,12 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ $rc0 -eq 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0" >&2
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14412,16 +13934,13 @@ SNISERVER=badssl.com
 if ! eval $NUMCOND; then :;
 elif ! testaddrs openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions openssl-no-sni); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ -z "$INTERNET" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -14433,14 +13952,12 @@ $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
 if [ $rc0 -ne 0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0" >&2
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14456,12 +13973,10 @@ TEST="$NAME: test the accept-timeout option"
 if ! eval $NUMCOND; then :;
 elif ! feat=$(testaddrs tcp); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testoptions accept-timeout); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # Just start a process with accept-timeout 1s and check if it still runs 2s later
 # but before this, we test if the process waits at all
@@ -14481,8 +13996,7 @@ if ! kill $pid1 2>"$tk1"; then
     echo $CMD1 >&2
     cat "$te1" >&2
     cat "$tk1" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # Second, set accept-timeout and see if socat exits before kill
 CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=$(reltime 1) PIPE"
@@ -14494,12 +14008,10 @@ if kill $pid2 2>"$tk2"; then
     echo "$CMD2" >&2
     cat "$te2" >&2
     cat "$tk2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi
 wait
@@ -14519,8 +14031,7 @@ TEST="$NAME: test UDP-DATAGRAM ignoring peerport"
 if ! eval $NUMCOND; then :
 elif [ $(echo $E "$SOCAT_VERSION\n1.7.3.4" |sort -n |tail -n 1) = 1.7.3.4 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Only with Socat 1.7.4.0 or higher${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -14541,8 +14052,7 @@ sleep 0.1
 kill $pid0 2>/dev/null; wait
 if [ -f ${tf}0 ] && echo "$da" |diff - ${tf}0 >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
@@ -14550,8 +14060,7 @@ else
     echo "$CMD1" >&2
     cat "${te}1" >&2
     cat "${tdiff}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14567,16 +14076,13 @@ TEST="$NAME: proxy-authorization-file option"
 if ! eval $NUMCOND; then :;
 elif ! testfeats proxy >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testoptions proxy-authorization-file >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option proxy-authorization-file not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ta="$td/test$N.auth"
 tf="$td/test$N.stdout"
@@ -14602,8 +14108,7 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1" >&2
     cat "${te}1" >&2
     cat "${tf}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then
     $PRINTF "$FAILED:\n"
     echo "$CMD0 &" >&2
@@ -14612,13 +14117,11 @@ elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then
     cat "${te}1" >&2
     cat "${tf}0" >&2
     echo "Authorization string not in client request" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
    $PRINTF "$OK\n"
    if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
-   listOK="$listOK $N"
+   ok
 fi
 kill $pid 2>/dev/null
 wait
@@ -14637,8 +14140,7 @@ TEST="$NAME: test communication via VSOCK loopback socket"
 if ! eval $NUMCOND; then :;
 elif ! fea=$(testfeats VSOCK); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$fea not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -14656,36 +14158,30 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if [ $rc1 -ne 0 ] &&  [ "$UNAME" != Linux ]; then
     $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then
+    cant
+elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! re_match "$UNAME_R" '^[6-9]\..*' && ! re_match "$UNAME_R" '^5\.[6-]\..*' && ! re_match "$UNAME_R" '^5\.[1-9][0-9].*'; then
     $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif grep -q "No such device" "${te}1"; then
     $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $rc1 -ne 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14707,16 +14203,13 @@ TEST="$NAME: OpenSSL stream from client to server"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 tcp openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-listen openssl-connect); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 ti="$td/test$N.datain"
@@ -14742,12 +14235,10 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif diff $ti $to >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
@@ -14757,8 +14248,7 @@ else
     echo "diff:" >&2
     head -n 2 $tdiff >&2
     echo ... >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14779,16 +14269,13 @@ TEST="$NAME: OpenSSL stream from server to client"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 tcp openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-listen openssl-connect); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 ti="$td/test$N.datain"
@@ -14814,12 +14301,10 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif diff $ti $to >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
@@ -14829,8 +14314,7 @@ else
     echo "diff:" >&2
     head -n 2 $tdiff >&2
     echo ... >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14850,21 +14334,17 @@ TEST="$NAME: OpenSSL DTLS transfer from client to server"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 udp openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
+    cant
+elif re_match "$(openssl version |awk '{print($2);}')" '^0.9.8[a-ce]'; then
     # also on NetBSD-4 with openssl-0.9.8e
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 ti="$td/test$N.datain"
@@ -14890,12 +14370,10 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif diff $ti $to >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
@@ -14905,8 +14383,7 @@ else
     echo "diff:" >&2
     head -n 2 $tdiff >&2
     echo ... >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -14926,21 +14403,17 @@ TEST="$NAME: OpenSSL DTLS transfer from server to client"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testfeats ip4 udp openssl); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
+    cant
+elif re_match "$(openssl  version |awk '{print($2);}')" '^0.9.8[a-ce]'; then
     # also on NetBSD-4 with openssl-0.9.8e
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 ti="$td/test$N.datain"
@@ -14966,12 +14439,10 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif diff $ti $to >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
@@ -14981,8 +14452,7 @@ else
     echo "diff:" >&2
     head -n 2 $tdiff >&2
     echo ... >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15001,16 +14471,13 @@ TEST="$NAME: test diverse of socket,openssl params"
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! type openssl >/dev/null 2>&1; then
     $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 gentestcert testsrv
 tf="$td/test$N.stdout"
@@ -15031,19 +14498,17 @@ sleep 0.5
 kill $pid0 2>/dev/null; wait
 if [ $rc1 -ne 0 ]; then
     $PRINTF "$CANT\n"
-    numCANT=$((numCANT+1))
+    cant
 elif [ ! -e $trc0 ]; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15062,12 +14527,13 @@ TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 addr
 if ! eval $NUMCOND; then :;
 elif ! testfeats openssl >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
+elif ! runsip6 >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Cannot generate cert with IPv6 address${NORMAL}\n" $N
+    cant
 else
 gentestcert testsrv
 gentestaltcert testalt
@@ -15087,16 +14553,14 @@ rc1=$?
 kill $pid0 2>/dev/null; wait
 if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15127,14 +14591,12 @@ if [ $rc -ne 0 ]; then
     if [ "$VERBOSE" ]; then
 	echo "$CMD &" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD &" >&2
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15153,8 +14615,7 @@ TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -15170,14 +14631,12 @@ if [ $rc -eq 0 ]; then
     if [ "$VERBOSE" ]; then
 	echo "$CMD" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD" >&2
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15207,26 +14666,22 @@ if [ ! -f "$ts" ]; then
 	echo "$CMD" >&2
 	cat "${te}" >&2
     fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ ! -s "$ts" ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
 	echo "$CMD" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD &" >&2
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 # Socats access to different types of file system entries using various kinds
@@ -15294,8 +14749,7 @@ if [ $rc1 != 1 ]; then
     fi
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then
     $PRINTF "$FAILED ($nerr error message(s) instead of 1)\n"
     if [ "$pid0" ]; then
@@ -15304,16 +14758,14 @@ elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then
     fi
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
 	if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi
 	echo "$CMD1" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 set +vx
 fi # NUMCOND
@@ -15364,7 +14816,7 @@ orphaned    gopen
 # Up to 1.7.4.3 this terminated immediately on connection refused
 NAME=TCP_TIMEOUT_RETRY
 case "$TESTS" in
-*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
+*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%retry%*|*%$NAME%*)
 TEST="$NAME: TCP with options connect-timeout and retry"
 # In background run a delayed echo server
 # In foreground start TCP with connect-timeout and retry. On first attempt the
@@ -15389,24 +14841,21 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - "${tf}1" >$tdiff; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
 	echo "$CMD0 &" >&2
 	echo "$CMD1" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &" >&2
     cat "${te}0" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15436,19 +14885,16 @@ if [ $rc0 -eq 0 ]; then
     if [ "$VERBOSE" ]; then
 	echo "$CMD0" >&2
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0" >&2
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 # Up to 1.7.4.3 there was a bug with the lowport option:
@@ -15477,29 +14923,26 @@ rc1=$?
 LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head -n 1)
 #echo "LOWPORT=\"$LOWPORT\"" >&2
 #type socat >&2
-if  [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
+#if  [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
+if re_match "$LOWPORT" '^[0-9][0-9]*' ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then
     $PRINTF "$CANT (no SYCLS)\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 # Test if trailing garbage in integer type options gives error
@@ -15519,14 +14962,12 @@ printf "test $F_n $TEST... " $N
 $CMD0 </dev/null >/dev/null 2>"${te}0"
 if grep -q "missing numerical value" "${te}0"; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15552,14 +14993,12 @@ if grep -q "trailing garbage" "${te}0"; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
     if [ "$debug" ]; then cat ${te} >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -15589,16 +15028,14 @@ if [ "$target" = "$tf" ]; then
 	echo "ln -s \"$tf\" \"$tl\""
 	echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'"
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "touch \"$tf\"" >&2
     echo "ln -s \"$tf\" \"$tl\"" >&2
     echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" >&2
     cat "$te"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 kill $spid 2>/dev/null
 wait
@@ -15652,8 +15089,7 @@ for addr in exec system; do
 		cat "${te}0"
 		echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1"
 		cat "${te}1"
-		numFAIL=$((numFAIL+1))
-		listFAIL="$listFAIL $N"
+		failed
 	    elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
 		$PRINTF "$FAILED (diff)\n"
 		echo "$CMD0 &" >&2
@@ -15662,16 +15098,14 @@ for addr in exec system; do
 		cat "${te}1" >&2
 		echo "diff:" >&2
 		cat $tdiff >&2
-		numFAIL=$((numFAIL+1))
-		listFAIL="$listFAIL $N"
+		failed
 	    else
 		$PRINTF "$OK\n"
 		if [ "$VERBOSE" ]; then
 		    echo "$CMD0 &" >&2
 		    echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" >&2
 		fi
-		numOK=$((numOK+1))
-		listOK="$listOK $N"
+		ok
 	    fi
 	    MICROS=$SAVEMICS
 	fi # NUMCOND
@@ -15692,12 +15126,10 @@ TEST="$NAME: Dalan syntax error does not raise SIGSEGV"
 if ! eval $NUMCOND; then :
 elif ! a=$(testfeats GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -15711,21 +15143,18 @@ if [ $rc1 -eq 1 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif [ $rc1 -eq 139 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
-    # soemthing unexpected happened
+    # Something unexpected happened
     $PRINTF "$CANT\n"
     echo "$CMD"
     cat "${te}" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 fi
 fi # NUMCOND
  ;;
@@ -15745,27 +15174,23 @@ TEST="$NAME: filan -s displays TCP etc"
 if ! eval $NUMCOND; then :
 elif ! a=$(testfeats STDIO IP4 TCP LISTEN EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs STDIO TCP4 TCP4-LISTEN EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions so-reuseaddr nofork ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
-CMD1="$TRACE $SOCAT $opts -t $T4 - TCP4:localhost:$PORT"
+CMD0="$TRACE $SOCAT $opts -t $T4 TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
+CMD1="$TRACE $SOCAT $opts -t $T8 - TCP4:localhost:$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD0" >/dev/null 2>"${te}0" &
 pid0=$!
@@ -15780,8 +15205,7 @@ if [ $rc1 -eq 0 -a "$result" = tcp ]; then
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     if [ $rc1 -ne 0 ]; then
@@ -15793,13 +15217,11 @@ else
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -15818,20 +15240,16 @@ TEST="$NAME: Restoring of terminal settings"
 if ! eval $NUMCOND; then :
 elif ! $(type stty >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 te="$td/test$N.stderr"
 tx0="$td/test$N.stty0"
@@ -15846,21 +15264,18 @@ if diff $tx0 $tx1 >$tdiff 2>&1; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD &"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}" >&2
     cat "${te}.outer" >&2
     cat $tdiff >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -15875,12 +15290,10 @@ TEST="$NAME: Socat does not leak FDs to EXEC'd program"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testaddrs STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions stderr) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -15894,20 +15307,17 @@ if [ "$(cat  "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD" >&2
     cat "${te}" >&2
     cat "${tf}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak
@@ -15922,12 +15332,10 @@ TEST="$NAME: Socat does not leak sniffing FDs"
 if ! eval $NUMCOND; then :;
 elif ! a=$(testaddrs STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions stderr) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -15941,20 +15349,17 @@ if [ "$(cat  "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD" >&2
     cat "${te}" >&2
     cat "${tf}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -15975,20 +15380,16 @@ TEST="$NAME: ${KEYW}-RECVFROM with fork option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats $FEAT STDIO SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions fork ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runs$RUNS >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 case "X$IPPORT" in
     "XPORT")
@@ -16028,8 +15429,7 @@ if $ECHO "$da 2\n$da 1" |diff -u - $tf >$tdiff; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -16040,9 +15440,7 @@ else
     cat "${te}2" >&2
     echo "diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16065,16 +15463,13 @@ TEST="$NAME: Option -S can turn off logging of SIGTERM"
 if ! eval $NUMCOND; then :;
 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16091,16 +15486,13 @@ if ! grep "exiting on signal" ${te}0 >/dev/null; then
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$DEBUG" ];   then echo "kill -TERM <pid>" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "kill -TERM <pid>" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16118,16 +15510,13 @@ TEST="$NAME: Option -S can turn on logging of signal 31"
 if ! eval $NUMCOND; then :;
 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16144,16 +15533,13 @@ if grep "exiting on signal" ${te}0 >/dev/null; then
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$DEBUG" ];   then echo "kill -31 <pid>" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "kill -31 <pid>" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16169,24 +15555,19 @@ TEST="$NAME: PROXY-CONNECT with option http-version"
 if ! eval $NUMCOND; then :;
 elif ! $(type proxyecho.sh >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}proxyecho.sh not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats IP4 TCP LISTEN EXEC STDIO PROXY); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs TCP4-LISTEN EXEC STDIO PROXY-CONNECT); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions so-reuseaddr crlf pf proxyport http-version) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.sh"
 tf="$td/test$N.stdout"
@@ -16208,22 +15589,19 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}1" >&2
     echo "diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$debug" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$debug" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 kill $pid 2>/dev/null
 wait
 fi ;; # NUMCOND, feats
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -16235,23 +15613,20 @@ TEST="$NAME: test the so-rcvtimeo option with DTLS"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO OPENSSL); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO DTLS); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions verify so-rcvtimeo) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 # We need a hanging connection attempt, guess an address for this
-HANGIP=0.0.0.1
+#HANGIP=0.0.0.1 	# some OSes refuse to end to this address
+HANGIP=8.8.8.9 		# 2025 this hangs...
 te1="$td/test$N.stderr1"
 tk1="$td/test$N.kill1"
 te2="$td/test$N.stderr2"
@@ -16266,8 +15641,7 @@ if ! kill -0 $pid1 2>"$tk1"; then
     $PRINTF "${YELLOW}does not hang${NORMAL}\n"
     if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
     wait
 else
     # DTLS restarts read() a few times
@@ -16277,21 +15651,23 @@ CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=$(reltime 1)"
 $CMD2 >"$te1" 2>$te2 </dev/null &
 pid2=$!
 relsleep 8 	# in OpenSSL 1.1.1f DTLS takes two timeouts
-if kill $pid2 2>"$tk2"; then
-    $PRINTF "$FAILED\n"
+sleep 0.02 	# in OpenSSL 3.0.13 SSL_CTX_clear_mode() needs e.g. 0.02s
+kill $pid2 2>"$tk2"
+prc2=$?
+wait
+if [ $prc2 -eq 0 ]; then
+    $PRINTF "$FAILED (not timeout)\n"
     echo "$CMD2" >&2
     cat "$te2" >&2
     cat "$tk2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
     while kill $pid2 2>/dev/null; do :; done
     wait
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi
 wait
@@ -16313,20 +15689,16 @@ TEST="$NAME: sniff file names with variables"
 if ! eval $NUMCOND; then :;
 elif ! A=$(testfeats IP4 TCP LISTEN PIPE STDIO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE STDIO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16353,9 +15725,7 @@ if [ $rc1a != 0 -o $rc1b != 0 ]; then
     cat "${te}1a" >&2
     echo "$CMD1"
     cat "${te}1b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 &&
 	test $(ls $td/test$N.*.log |head -n 1 |wc -c) -ge 56; then
     # Are the names correct?
@@ -16368,8 +15738,7 @@ elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 &&
     if [ "$DEBUG" ];   then cat "${te}1a" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then
     $PRINTF "$FAILED (vars not resolved)\n"
     echo "$CMD0 &"
@@ -16378,9 +15747,7 @@ elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.
     cat "${te}1a" >&2
     echo "$CMD1"
     cat "${te}1b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 else
     $PRINTF "$FAILED (unknown)\n"
     echo "$CMD0 &"
@@ -16389,9 +15756,7 @@ else
     cat "${te}1a" >&2
     echo "$CMD1"
     cat "${te}1b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16409,20 +15774,16 @@ TEST="$NAME: Socat option --statistics"
 if ! eval $NUMCOND; then :;
 elif ! $(type  >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats STATS STDIO SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16437,21 +15798,17 @@ if [ $rc0 -ne 0 ]; then
     $PRINTF "$CANT\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(grep STATISTICS "${te}0" |wc -l) -eq 2 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16468,53 +15825,53 @@ TEST="$NAME: statistics on SIGUSR1"
 if ! eval $NUMCOND; then :;
 elif ! $(type tee >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! $(type pkill >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}pkill not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats STATS STDIO SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 CMD0="$TRACE $SOCAT $opts STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw"
-#set -vx
-printf "test $F_n $TEST... " $N
-{ echo "$da"; relsleep 10; } |eval "$CMD0" >"${tf}0" 2>"${te}0" &
-pid0=$!
-relsleep 2
 TTY=$(tty |sed 's|/dev/||')
-pkill -USR1 -t $TTY socat || { echo "pkill -t $TTY -USR1 socat"; }
+CMD1="pkill -USR1 -t $TTY socat"
+printf "test $F_n $TEST... " $N
+# On Fedora-41 pkill can be slow (eg.20ms)
+{ echo "$da"; relsleep 20; } |eval "$CMD0" >"${tf}0" 2>"${te}0" &
+pid0=$!
+#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1"
 relsleep 2
-pkill -t $TTY socat
+#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1"
+$CMD1 2>"${te}1"
+relsleep 2
+#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1"
 wait
+pkill -t $TTY socat >>"${te}1"
 if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then
     $PRINTF "$OK\n"
-    if [ "$VERBOSE" ]; then echo "$CMD0"; fi
+    if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+    if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+    ok
 else
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (no stats)\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    echo "$CMD1"
+    cat "${te}1" >&2
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16533,16 +15890,13 @@ TEST="$NAME: test the children-shutup option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions fork children-shutup) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 newport tcp4
 ts="$td/test$N.sock"
@@ -16560,23 +15914,20 @@ waitunixport $ts 1
 rc1=$?
 kill $pid0 2>/dev/null; wait
 relsleep 1 	# child process might need more time
-if grep -q " W connect" ${te}0; then
+if ! grep -q " E " ${te}0; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16596,28 +15947,22 @@ TEST="$NAME: INTERFACE ignores outgoing packets"
 if ! eval $NUMCOND; then :;
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! $(type ping >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! feat=$(testfeats TUN STDIO INTERFACE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - TUN STDIO INTERFACE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions iff-up tun-type tun-name ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16650,8 +15995,7 @@ if [ $? -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif test -s "${tf}1"; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -16660,8 +16004,7 @@ elif test -s "${tf}1"; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -16670,12 +16013,10 @@ else
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi ;; # NUMCOND, feats
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -16691,20 +16032,16 @@ TEST="$NAME: test if option reuseaddr's default is 1"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO PIPE TCP4 TCP4-LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions accept-timeout) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16731,8 +16068,7 @@ if [ $rc0b -eq 0 ]; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0a &"
@@ -16741,9 +16077,7 @@ else
     cat "${te}1" >&2
     echo "$CMD0b"
     cat "${te}0b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16762,20 +16096,16 @@ TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats PIPE IP6 TCP OPENSSL LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs PIPE OPENSSL-CONNECT OPENSSL-LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions verify cert key) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16806,8 +16136,7 @@ if [ $rc0b -eq 0 ]; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0a &"
@@ -16816,9 +16145,7 @@ else
     cat "${te}1" >&2
     echo "$CMD0b"
     cat "${te}0b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16837,20 +16164,16 @@ TEST="$NAME: test option reuseaddr without value"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO PIPE TCP4-CONNECT TCP4-LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions so-reuseaddr accept-timeout) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16877,8 +16200,7 @@ if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "$
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 #elif grep -q "accept: \(Connection\|Operation\) timed out" "${te}0b"; then
 elif grep -q "accept: .* timed out" "${te}0b"; then
     # FreeBSD, Solaris do not seem to need SO_REUSEADDR with TCP at all
@@ -16889,8 +16211,7 @@ elif grep -q "accept: .* timed out" "${te}0b"; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0a &"
@@ -16899,9 +16220,7 @@ else
     cat "${te}1" >&2
     echo "$CMD0b"
     cat "${te}0b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -16922,40 +16241,26 @@ TEST="$NAME: try all available TCP4 addresses"
 # that is closed on both addresses.
 # The test succeeded when the log shows that Socat tried to connect two times.
 if ! eval $NUMCOND; then :;
-elif ! $(type nslookup >/dev/null 2>&1); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
-#    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
-#    listCANT="$listCANT $N"
 elif ! F=$(testfeats IP4 TCP GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs TCP4-CONNECT GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ -z "$INTERNET" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
+elif [ -z "$HAVEDNS" ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-if type nslookup >/dev/null 2>&1; then
-    ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
-elif type host >/dev/null 2>&1; then
-    ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //')
-fi
 while true; do
     newport tcp4
     OPEN=
@@ -16979,15 +16284,12 @@ if [ $(grep " N opening connection to .*AF=2 " ${te} |wc -l) -eq 2 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17006,34 +16308,27 @@ TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses"
 # neither IPv4 nor IPv6
 # Check the log if Socat tried both addresses
 if ! eval $NUMCOND; then :;
-#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
-#    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
-#    listCANT="$listCANT $N"
 elif ! F=$(testfeats IP4 IP6 TCP); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs TCP-CONNECT GOPEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions ai-addrconfig) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip6 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif [ -z "$INTERNET" ]; then	# only needs Internet DNS
+    cant
+elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
+elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -17081,15 +16376,12 @@ if [ $(grep " N opening connection to .*AF=[0-9]" ${te} |wc -l) -eq 2 ]; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD"; fi
     if [ "$DEBUG" ];   then cat "${te}" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD"
     cat "${te}" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17109,32 +16401,25 @@ TEST="$NAME: option netns (net namespace $ns)"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! $(type ip >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats IP4 TCP LISTEN NAMESPACES); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO TCP-LISTEN TCP EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions netns) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -17166,9 +16451,7 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1"
     cat "${te}1" >&2
     echo "ip netns del $ns"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then
@@ -17182,8 +16465,7 @@ elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED (bad output)\n"
     echo "$CMD0 &"
@@ -17192,9 +16474,7 @@ else
     cat "${te}1" >&2
     diff:
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17216,32 +16496,25 @@ TEST="$NAME: option netns with EXEC (net namespace $ns)"
 if ! eval $NUMCOND; then :;
 elif [ "$UNAME" != Linux ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! $(type ip >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats IP4 ABSTRACT_UNIXSOCKET UDP LISTEN NAMESPACES STDIO); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs ABSTRACT-RECV ABSTRACT-SENDTO CREATE EXEC UDP4-RECV STDIO UDP4); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions netns) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -17274,9 +16547,7 @@ if [ $rc1 -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -17285,8 +16556,7 @@ elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED (bad output)\n"
     echo "$CMD0 &"
@@ -17297,9 +16567,7 @@ else
     cat "${te}2" >&2
     echo diff:
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17320,11 +16588,9 @@ if ! cond=$(checkconds \
 		  "" \
 		  "" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
-    testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts"
+    testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR" "$opts"
 fi
 esac
 N=$((N+1))
@@ -17342,11 +16608,9 @@ if ! cond=$(checkconds \
 		  "" \
 		  "" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
-    testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts"
+    testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts"
 fi
 esac
 N=$((N+1))
@@ -17364,11 +16628,9 @@ if ! cond=$(checkconds \
 		  "" \
 		  "" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
-    testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts"
+    testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts"
 fi
 esac
 N=$((N+1))
@@ -17386,26 +16648,22 @@ TEST="$NAME: Internal socketpair keeps packet boundaries"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions bind socktype ) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
-ts1p=$PORT; PORT=$((PORT+1))
-ts2p=$PORT; PORT=$((PORT+1))
+newport udp; ts1p=$PORT
+newport udp; ts2p=$PORT
 da="test$N $(date) $RANDOM"
 CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM"
 CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p"
@@ -17424,8 +16682,7 @@ if [ "$rc2" -ne 0 ]; then
     cat "${te}1" >&2
     echo "$CMD2"
     cat "${te}2" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     $PRINTF "$FAILED\n"
     echo "$CMD1 &"
@@ -17434,21 +16691,18 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
     cat "${te}2" >&2
     echo diff:
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
     if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -17463,20 +16717,16 @@ TEST="$NAME: ACCEPT-FD address"
 if ! eval $NUMCOND; then :;
 elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats IP4 TCP LISTEN); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -17498,8 +16748,7 @@ if echo "$da" |diff "${tf}1" - >$tdiff; then
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -17507,9 +16756,7 @@ else
     echo "$CMD1"
     cat "${te}1" >&2
     cat $tdiff >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17517,42 +16764,28 @@ esac
 N=$((N+1))
 
 
-
-# Test the POSIX MQ feature with continuous READ and priorization on Linux
-NAME=LINUX_POSIXMQ_READ_PRIO
+# Test the POSIX MQ feature with continuous READ and prioritization on Linux
+NAME=POSIXMQ_READ_PRIO
 case "$TESTS" in
 *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*)
-TEST="$NAME: POSIX-MQ (Linux) with prio"
+TEST="$NAME: POSIX-MQ with prio"
 # Run a client/sender that creates a POSIX-MQ and sends a normal message and
 # then a client/sender with a higher priority message.
 # Run a passive/listening/receiving/reading process and check if it receives
 # both messages and in the prioritized order
 if ! eval $NUMCOND; then :;
-elif [ "$UNAME" != Linux ]; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! F=$(testfeats POSIXMQ STDIO); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "mq-prio unlink-early unlink-close"); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 tq=/test$N
-CMD0a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early"
-CMD0b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1"
-CMD1="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-close STDIO"
+CMD0a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early"
+CMD0b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1"
+CMD1="$TRACE $SOCAT $opts -u POSIXMQ-READ:$tq,unlink-close STDIO"
 printf "test $F_n $TEST... " $N
 echo "$da 0" |$CMD0a 2>"${te}0a"
 rc0a=$?
@@ -17563,16 +16796,14 @@ pid1=$!
 relsleep 1
 kill $pid1; wait
 if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (rc0a=$rc0a, rc0b=$rc0b)\n"
     echo "$CMD0a"
     cat "${te}0a" >&2
     echo "$CMD0b"
     cat "${te}0b" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
@@ -17581,10 +16812,9 @@ elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (diff)\n"
     echo "$CMD0a"
     cat "${te}0a" >&2
     echo "$CMD0b"
@@ -17593,50 +16823,35 @@ else
     cat "${te}1" >&2
     echo "difference:" >&2
     cat ${tdiff}1 >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
 N=$((N+1))
 
-# Test the POSIX MQ feature with RECV,fork on Linux
-NAME=LINUX_POSIXMQ_RECV_FORK
+# Test the POSIX MQ feature with RECV,fork
+NAME=POSIXMQ_RECV_FORK
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*)
-TEST="$NAME: POSIX-MQ (Linux) RECV with fork"
+TEST="$NAME: POSIX-MQ RECV with fork"
 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
 # output.
 # Run two clients/senders each with a message.
 # Check if both messages are stored.
 if ! eval $NUMCOND; then :;
-elif [ "$UNAME" != Linux ]; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! F=$(testfeats POSIXMQ STDIO); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "fork unlink-early unlink-close"); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 tq=/test$N
-CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO"
-CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
-CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
+CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO"
+CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq"
+CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
 printf "test $F_n $TEST... " $N
 $CMD0 2>"${te}0" >"${tf}0" &
 pid0=$!
@@ -17648,16 +16863,14 @@ rc1b=$?
 relsleep 1
 kill $pid0; wait
 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b)\n"
     echo "$CMD0"
     cat "${te}0" >&2
     echo "$CMD1a"
     cat "${te}1a" >&2
     echo "$CMD1b"
     cat "${te}1b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
@@ -17666,10 +16879,9 @@ elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then
     if [ "$DEBUG" ];   then cat "${te}1a" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
     if [ "$DEBUG" ];   then cat "${te}1b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (diff)\n"
     echo "$CMD0"
     cat "${te}0" >&2
     echo "$CMD1a"
@@ -17678,77 +16890,66 @@ else
     cat "${te}1b" >&2
     echo "difference:" >&2
     cat ${tdiff}0 >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
 N=$((N+1))
 
-# Test the POSIX MQ feature with RECV,fork,max-children on Linux
-NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN
+# Test the POSIX MQ feature with RECV,fork,max-children
+NAME=POSIXMQ_RECV_MAXCHILDREN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
-TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children"
+TEST="$NAME: POSIX-MQ RECV with fork,max-children"
 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
-# output via sub processes that sleeps after writing.
+# output via sub processes that sleep after writing.
 # Run a client/sender that sends message 1;
-# run a client/sender that sends message 3, has to wait;
-# write message 2 directly into output file;
+# run a client/sender that sends message 2;
+# run a client/sender that sends message 4, has to wait;
+# write message 3 directly into output file;
 # Check if the messages are stored in order of their numbers
 if ! eval $NUMCOND; then :;
-elif [ "$UNAME" != Linux ]; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SHELL" "fork max-children unlink-early unlink-close"); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 tq=/test$N
-CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\""
-CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
-CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
+CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=2 SHELL:\"cat\ >>${tf}0;\ relsleep\ 5\""
+CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq"
+CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
 printf "test $F_n $TEST... " $N
 eval $CMD0 2>"${te}0" >"${tf}0" &
 pid0=$!
 relsleep 1
 echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a"
 rc1a=$?
-echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b"
+echo "$da 2" |$CMD1a >/dev/null 2>"${te}1b"
 rc1b=$?
-sleep 0.5
-echo "$da 2" >>"${tf}0"
-sleep 1 	# as in SYSTEM
+echo "$da 4" |$CMD1b >/dev/null 2>"${te}1c"
+rc1c=$?
+#sleep 0.5
+relsleep 2
+echo "$da 3" >>"${tf}0"
+relsleep 5 	# as in SHELL
 kill $(childpids $pid0) $pid0 2>/dev/null
 wait 2>/dev/null
 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b, rc1c=$rc1c)\n"
     echo "$CMD0"
     cat "${te}0" >&2
     echo "$CMD1a"
     cat "${te}1a" >&2
     echo "$CMD1b"
     cat "${te}1b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
-elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
+    echo "$CMD1c"
+    cat "${te}1c" >&2
+    failed
+elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >${tdiff}0; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
@@ -17756,103 +16957,91 @@ elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
     if [ "$DEBUG" ];   then cat "${te}1a" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
     if [ "$DEBUG" ];   then cat "${te}1b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    if [ "$VERBOSE" ]; then echo "$CMD1c"; fi
+    if [ "$DEBUG" ];   then cat "${te}1c" >&2; fi
+    ok
 else
-    $PRINTF "$FAILED\n"
+    $PRINTF "$FAILED (diff)\n"
     echo "$CMD0"
     cat "${te}0" >&2
     echo "$CMD1a"
     cat "${te}1a" >&2
     echo "$CMD1b"
     cat "${te}1b" >&2
-    echo "difference:" >&2
+    echo "$CMD1c"
+    cat "${te}1c" >&2
+    echo "// diff:" >&2
     cat ${tdiff}0 >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
 esac
 N=$((N+1))
 
-# Test the POSIX MQ feature with SEND,fork,max-children on Linux
-NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN
+# Test the POSIX MQ feature with SEND,fork,max-children
+NAME=POSIXMQ_SEND_MAXCHILDREN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
-TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children"
-# Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from
-# there to an output file
-# Run a POSIX-MQ sender that two times forks and invokes a data generator
-# for messages 1 and 3 in a shell process with some trailing sleep.
-# Afterwards write message 2 directly into output file; message 3 should be
+TEST="$NAME: POSIX-MQ SEND with fork,max-children"
+# Start a POSIX-MQ receiver that creates the MQ and transfers data from it
+# to an output file
+# Run a POSIX-MQ sender that forks two child shell processes that get data from
+# a file queue with messages 1, 2, and 4, transfer it to the receiver and sleep
+# afterwards to delay the third child by option max-children=2
+# Afterwards write message 3 directly into output file; message 4 should be
 # delayed due to max-children option
 # Check if the messages are stored in order of their numbers.
-# The data generator is implemented as a receiver from an MQ with "1", "3"
+# The data generator is implemented with just a directory containing files
+# "1", "2", "4"
 if ! eval $NUMCOND; then :;
-elif [ "$UNAME" != Linux ]; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-#elif ! runsposixmq >/dev/null; then
-#    $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
-#    numCANT=$((numCANT+1))
-#    listCANT="$listCANT $N"
+elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-READ STDIO SHELL" "fork max-children mq-prio unlink-early unlink-close"); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
+tq="/test$N"
+tQ="$td/test$N.q"
 da="test$N $(date) $RANDOM"
-tq=/test$N
-CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-early STDIO"
-CMD1="$TRACE $SOCAT --experimental $opts -U POSIXMQ-SEND:$tq,fork,max-children=1,interval=0.1 SYSTEM:\"./socat\ --experimental\ -u\ POSIXMQ-RECV\:$tq-data\ -;\ sleep\ 1\""
+CMD1="$TRACE $SOCAT $opts -lp reader -u POSIXMQ-READ:$tq,unlink-early STDIO"
+#CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'f=\$(ls -1 $tQ|head -n 1);\ test\ -f\ "$tQ/\$f"\ ||\ exit\ 1;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'"
+CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'shopt\ -s\ nullglob;\ f=\$(ls -1 $tQ|head -n 1);\ test\ -z\ "\$f"\ &&\ exit;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'"
 printf "test $F_n $TEST... " $N
 # create data for the generator
-echo "$da 1" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data,unlink-early
-echo "$da 3" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data
-eval $CMD0 2>"${te}0" >>"${tf}0" &
-pid0=$!
-relsleep 1
-eval $CMD1 2>"${te}1" &
+mkdir -p $tQ
+echo "$da 1" >$tQ/01
+echo "$da 2" >$tQ/02
+echo "$da 4" >$tQ/04
+eval $CMD1 2>"${te}1" >>"${tf}1" &
 pid1=$!
-sleep 0.5
-echo "$da 2" >>"${tf}0"
-sleep 1 	# as in SYSTEM
-kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) 2>/dev/null
+relsleep 1
+eval $CMD2 2>"${te}2" &
+pid2=$!
+relsleep 4
+echo "$da 3" >>"${tf}1"
+relsleep 10
+kill $(childpids -r $pid1) $pid1 $(childpids -r $pid2) $pid2 2>/dev/null
 wait 2>/dev/null
-$SOCAT -u --experimental /dev/null POSIXMQ-SEND:$tq-data,unlink-close
-if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
+# remove the MQ
+$SOCAT -u /dev/null POSIXMQ-SEND:$tq,unlink-close 2>"${te}3b"
+if $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}1 >${tdiff}1; then
     $PRINTF "$OK\n"
-    if [ "$VERBOSE" ]; then echo "$CMD0"; fi
-    if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    if [ "$VERBOSE" ]; then echo "$CMD2"; fi
+    if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
+    ok
 else
     $PRINTF "$FAILED\n"
-    echo "$CMD0"
-    cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    echo "difference:" >&2
-    cat ${tdiff}0 >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    echo "$CMD2"
+    cat "${te}2" >&2
+    echo "// diff:" >&2
+    cat ${tdiff}1 >&2
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17871,16 +17060,13 @@ TEST="$NAME: sigint option with SHELL"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions setsid sigint) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -17901,15 +17087,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -17926,14 +17109,12 @@ TEST="$NAME: simple echo via SHELL of cat with socketpair"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t"
+    testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t"
 fi
 esac
 N=$((N+1))
@@ -17947,14 +17128,12 @@ TEST="$NAME: simple echo via SHELL of cat with pipes"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t"
+    testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t"
 fi
 esac
 N=$((N+1))
@@ -17968,19 +17147,16 @@ TEST="$NAME: simple echo via SHELL of cat with pty"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL PTY); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL PTY); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$SHELL" = /bin/ksh ]; then
     # on NetBSD-9.3 this test kills test.sh script...
     $PRINTF "test $F_n $TEST... ${YELLOW}/bin/ksh might kill test.sh${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t"
+    testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t"
 fi
 esac
 N=$((N+1))
@@ -17994,14 +17170,12 @@ TEST="$NAME: call  od -c  via SHELL using socketpair"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t"
+    testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t"
 fi
 esac
 N=$((N+1))
@@ -18015,14 +17189,12 @@ TEST="$NAME: call  od -c  via SHELL using pipes"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SHELL PIPE); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
-    testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t"
+    testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t"
 fi
 esac
 N=$((N+1))
@@ -18042,29 +17214,24 @@ elif [ "$UNAME" = "NetBSD" ]; then
     # On NetBSD-4.0 and NetBSD-9.3 this test hangs (signal has no effect)
     # (other versions not tried)
     $PRINTF "test $F_n $TEST... ${YELLOW}might hang on $UNAME${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats SYCLS STDIO SYSTEM SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO SYSTEM SOCKETPAIR); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions setsid sigint) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
 #CMD0="$TRACE $SOCAT $opts PIPE SYSTEM:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
-# -T is required on (only?) OpenBSD-4
-CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -lf\ ${te}1\ PIPE\ PIPE\",setsid,sigint"
-#CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
+# Without -T process remains on OpenBSD-4, AIX, ?
+CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
 printf "test $F_n $TEST... " $N
 eval $CMD0 >/dev/null 2>"${te}0" &
 pid0=$!
@@ -18077,15 +17244,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
-    $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?${NORMAL}\n"
+    $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?)${NORMAL}\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 fi
 fi # NUMCOND
  ;;
@@ -18105,20 +17269,16 @@ TEST="$NAME: test the res-nsaddr option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO IP4 UDP TCP); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions res-nsaddr) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! runsip4 >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -18141,26 +17301,21 @@ if grep "$da" "${tf}0" >/dev/null; then
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 elif pgrep -u root nscd >/dev/null 2>&1; then
     $PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCAnT="$namesCANT $NAME"
+    cant
 else
     $PRINTF "$FAILED (query not received)\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "$CMD1"
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -18189,16 +17344,13 @@ TEST="$NAME: restore of pwd after CREAT with chdir option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats CREAT SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs - CREAT SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions chdir) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18223,31 +17375,24 @@ else
 	$PRINTF "$FAILED\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif [ "$tpwd" != "$td" ]; then
 	$PRINTF "$FAILED (chdir failed)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
 	$PRINTF "$FAILED (bad pwd2)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -18267,16 +17412,13 @@ TEST="$NAME: restore of pwd after SYSTEM with chdir option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats SHELL SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs SHELL SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions chdir) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18302,31 +17444,24 @@ else
 	$PRINTF "$FAILED (rc=$rc0)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif [ "$tpwd" != "$td" ]; then
 	$PRINTF "$FAILED (chdir failed)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
 	$PRINTF "$FAILED (bad pwd)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -18347,16 +17482,13 @@ TEST="$NAME: test restore after CREAT with umask option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats CREAT SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs CREAT SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions umask) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18386,30 +17518,23 @@ else
 	$PRINTF "$FAILED\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
 	$PRINTF "$FAILED (umask failed)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! [ "$oumask" -eq $(cat "$tc") ]; then
 	$PRINTF "$FAILED (bad umask)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	cat "$tdebug" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -18429,16 +17554,13 @@ TEST="$NAME: test restore after SHELL with umask option"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats SHELL SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs SHELL SYSTEM); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions umask) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18468,30 +17590,23 @@ else
 	$PRINTF "$FAILED\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
 	$PRINTF "$FAILED (umask failed)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! [ "$oumask" -eq $(cat "$tc") ]; then
 	$PRINTF "$FAILED (bad umask)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	cat "$tdebug" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -18519,14 +17634,13 @@ TEST="$NAME: Option unix-bind-tempname"
 # log "Transport endpoint is not connected" and the TCP service does not fail
 # with "Address already in use"), the test succeeded.
 if ! eval $NUMCOND; then :;
-elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then
+#elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then
+elif re_match "$CLI_" 'ABSTRACT-*' && ! feat=$(testfeats abstract-unixsocket); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions unix-bind-tempname) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 ts="$td/test$N.sock"
 tf="$td/test$N.stdout"
@@ -18544,7 +17658,7 @@ CMD0="$TRACE $SOCAT $opts -lp server $SRV:${ts}0,fork PIPE"
 # The following command is the solution: option unix-bind-tempname generates
 # random names (like tempnam(2)) for binding the datagram client socket;
 # creating the XXXXXX file makes sure that the (non abstract) clients cannot
-# erronously bind there (part of the test)
+# erroneously bind there (part of the test)
 CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind=${ts}1"
 touch ${ts}1.XXXXXX; CMD1="$TRACE $SOCAT $opts -lp tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind-tempname=${ts}1.XXXXXX"
 CMD2="$TRACE $SOCAT $opts -lp client - TCP4-CONNECT:$LOCALHOST:$PORT"
@@ -18572,8 +17686,7 @@ if [ $rc2b -ne 0 ]; then
     cat "${te}2a" >&2
     echo "$CMD2"
     cat "${te}2b" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then
     $PRINTF "$FAILED (phase a)\n"
     echo "$CMD0 &"
@@ -18584,8 +17697,7 @@ elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then
     cat "${te}2a" >&2
     echo "diff a:" >&2
     cat ${tdiff}2a >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -18598,8 +17710,7 @@ elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then
     cat "${te}2b" >&2
     echo "diff b:" >&2
     cat ${tdiff}2b >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -18610,13 +17721,11 @@ else
     if [ "$DEBUG" ];   then cat "${te}2a" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD2"; fi
     if [ "$DEBUG" ];   then cat "${te}2b" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 done <<<"
@@ -18668,8 +17777,7 @@ if [ -e $ts3 ]; then
     cat "${te}0b" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif ! grep -q " E " ${te}1; then
     $PRINTF "$FAILED\n"
     echo "Socat did not fail"
@@ -18679,8 +17787,7 @@ elif ! grep -q " E " ${te}1; then
     cat "${te}0b" >&2
     echo "$CMD1" >&2
     cat "${te}1" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
@@ -18689,13 +17796,11 @@ else
     if [ "$DEBUG" ];   then cat "${te}0b" >&2; fi
     if [ "$VERBOSE" ]; then echo "$CMD1"; fi
     if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -18709,26 +17814,22 @@ TEST="$NAME: f-setpipe-sz on STDIN"
 if ! eval $NUMCOND; then :;
 elif ! $(type true >/dev/null 2>&1); then
     $PRINTF "test $F_n $TEST... ${YELLOW}true not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! F=$(testfeats STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions f-setpipe-sz nofork) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-newport tcp4 	# or whatever proto, or drop this line
+newport tcp4
 # Find the default pipe size
 PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
 PIPESZ2=$((2*PIPESZ))
@@ -18741,24 +17842,19 @@ if [ "$rc0" -ne 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0" >&2
     echo "diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -18775,16 +17871,13 @@ TEST="$NAME: f-setpipe-sz on EXEC with pipes"
 if ! eval $NUMCOND; then :;
 elif ! F=$(testfeats STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! A=$(testaddrs STDIO EXEC); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif ! o=$(testoptions pipes f-setpipe-sz) >/dev/null; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -18801,24 +17894,19 @@ if [ "$rc0" -ne 0 ]; then
     $PRINTF "$FAILED\n"
     echo "$CMD0"
     cat "${te}0" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
     cat "${te}0" >&2
     echo "diff:" >&2
     cat "$tdiff" >&2
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
-    namesFAIL="$namesFAIL $NAME"
+    failed
 else
     $PRINTF "$OK\n"
     if [ "$VERBOSE" ]; then echo "$CMD0"; fi
     if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 fi
 fi # NUMCOND
  ;;
@@ -18837,8 +17925,7 @@ elif ! cond=$(checkconds "" "" "" \
 			 "so-reuseaddr" \
 			 "dccp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -18859,9 +17946,7 @@ if [ $? -ne 0 ]; then
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED\n"
 	echo "$CMD0 &"
@@ -18870,17 +17955,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	cat "${te}1" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
 else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
 fi
 kill $pid1 2>/dev/null
 wait
@@ -18892,7 +17974,7 @@ N=$((N+1))
 NAME=UDPLITE4STREAM
 case "$TESTS" in
 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
-TEST="$NAME: echo via connection to UDP-Lite V4 socket"
+TEST="$NAME: echo via connection to UDP-Lite IPv4 socket"
 if ! eval $NUMCOND; then :;
 elif ! cond=$(checkconds \
 		  "" \
@@ -18903,9 +17985,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "udplite4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18928,8 +18008,7 @@ else
 	cat "${te}1" >&2
 	echo "$CMD2"
 	cat "${te}2" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD1 &" >&2
@@ -18938,28 +18017,24 @@ else
 	cat "${te}2" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD2"; fi
 	if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi ;; # NUMCOND
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
 NAME=UDPLITE4STREAM
 case "$TESTS" in
 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
-TEST="$NAME: echo via connection to UDP-Lite V4 socket"
+TEST="$NAME: echo via connection to UDP-Lite IPv4 socket"
 if ! eval $NUMCOND; then :;
 elif ! cond=$(checkconds \
 		  "" \
@@ -18970,9 +18045,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "udplite4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -18995,8 +18068,7 @@ else
 	cat "${te}1" >&2
 	echo "$CMD2"
 	cat "${te}2" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD1 &" >&2
@@ -19005,54 +18077,48 @@ else
 	cat "${te}2" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD2"; fi
 	if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi ;; # NUMCOND
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
-NAME=UDPLITE4STREAM
+NAME=UDPLITE6STREAM
 case "$TESTS" in
-*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
-TEST="$NAME: echo via connection to UDP-Lite V4 socket"
+*%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
+TEST="$NAME: echo via connection to UDP-Lite IPv6 socket"
 if ! eval $NUMCOND; then :;
 elif ! cond=$(checkconds \
 		  "" \
 		  "" \
 		  "" \
-		  "IP4 UDPLITE LISTEN STDIO PIPE" \
-		  "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
+		  "IP6 UDPLITE LISTEN STDIO PIPE" \
+		  "UDPLITE6-LISTEN PIPE STDIO UDPLITE6" \
 		  "so-reuseaddr" \
-		  "udplite4" ); then
+		  "udplite6" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
     tdiff="$td/test$N.diff"
     tsl=$PORT
-    ts="$LOCALHOST:$tsl"
+    ts="$LOCALHOST6:$tsl"
     da="test$N $(date) $RANDOM"
-    CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
-    CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
+    CMD1="$TRACE $SOCAT $opts UDPLITE6-LISTEN:$tsl,$REUSEADDR PIPE"
+    CMD2="$TRACE $SOCAT $opts - UDPLITE6:$ts"
     printf "test $F_n $TEST... " $N
     $CMD1 >"$tf" 2>"${te}1" &
     pid1=$!
-    waitudplite4port $tsl 1
+    waitudplite6port $tsl 1
     echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
     rc2=$?
     kill $pid1 2>/dev/null; wait
@@ -19062,8 +18128,7 @@ else
 	cat "${te}1" >&2
 	echo "$CMD2"
 	cat "${te}2" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
+	failed
     elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD1 &" >&2
@@ -19072,21 +18137,17 @@ else
 	cat "${te}2" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD2"; fi
 	if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi ;; # NUMCOND
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 
 
@@ -19116,9 +18177,7 @@ elif ! cond=$(checkconds \
 		  "$REUSEADDR bind" \
 		  "$protov" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -19156,8 +18215,7 @@ if [ $rc1 != 0 ]; then
     cat "${te}0"
     echo "$CMD1"
     cat "${te}1"
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
     "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
     \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
@@ -19170,8 +18228,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g"
 	echo "$CMD1"
 	cat "${te}1"
     fi
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -19180,8 +18237,7 @@ else
     cat "${te}1"
     echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
     diff - "${tf}"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND, feats
  ;;
@@ -19202,10 +18258,10 @@ RUNS=$(tolower $KEYW)
 PROTO=$KEYW
 proto="$(tolower "$PROTO")"
 # test the max-children option on pseudo connected sockets
-NAME=${KEYW}MAXCHILDREN
+NAME=${KEYW}_L_MAXCHILDREN
 case "$TESTS" in
 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
-TEST="$NAME: max-children option"
+TEST="$NAME: max-children option with $PROTO-LISTEN"
 # start a listen process with max-children=1; connect with a client, let it
 # send data and then sleep; connect with second client that wants to send
 # data immediately, but keep first client active until server terminates.
@@ -19221,9 +18277,7 @@ elif ! cond=$(checkconds \
 		  "$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \
 		  "$RUNS" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
 case "X$IPPORT" in
     "XPORT")
@@ -19257,8 +18311,7 @@ cpids="$(childpids $pid0)"
 kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait
 if echo -e "$da 1" |diff - $tf >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     echo "$CMD0 &"
@@ -19268,8 +18321,7 @@ else
     cat "${te}1"
     cat "${te}2"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 fi # NUMCOND
  ;;
@@ -19297,8 +18349,7 @@ elif ! cond=$(checkconds \
 		  "" \
 		  "" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19311,24 +18362,19 @@ else
 	$PRINTF "$FAILED\n"
 	echo "$CMD0"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! tty |diff - <(cat ${tf}0 |grep "controlling terminal" |grep -v -e '"/dev/tty"' -e none |head -n 1 |sed -e 's/controlling terminal by .*:[[:space:]]*//' -e 's/"//g') >$tdiff; then
 	$PRINTF "$FAILED\n"
 	echo "$CMD0"
 	cat "${te}0" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19353,9 +18399,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "tcp4 unix" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     ts="$td/test$N.sock"
     tf="$td/test$N.stdout"
@@ -19378,9 +18422,7 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD0 &"
@@ -19389,17 +18431,14 @@ else
 	cat "${te}1" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19424,14 +18463,10 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "tcp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
-elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then
+    cant
+elif re_match "$BASH_VERSION" '^[1-3]\.'; then
     $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     gentestcert testsrv
     tp="$td/test$N.pty"
@@ -19456,9 +18491,7 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD0 &"
@@ -19467,17 +18500,14 @@ else
 	cat "${te}1" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19505,9 +18535,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "tcp4 unix" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19545,9 +18573,7 @@ else
 	cat "${te}2a" >&2
 	echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"
 	cat "${te}2b" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2a" >${tdiff}_a; then
 	$PRINTF "$FAILED (diff a)\n"
 	echo "$CMD0 &"
@@ -19560,9 +18586,7 @@ else
 	cat "${te}2b" >&2
 	echo "// diff a:" >&2
 	cat "${tdiff}_a" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2b" >${tdiff}_b; then
 	$PRINTF "$FAILED (diff b)\n"
 	echo "$CMD0 &"
@@ -19575,9 +18599,7 @@ else
 	cat "${te}2b" >&2
 	echo "// diff b:" >&2
 	cat "${tdiff}_b" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -19588,8 +18610,7 @@ else
 	if [ "$DEBUG" ];   then cat "${te}2a" >&2; fi
 	if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"; fi
 	if [ "$DEBUG" ];   then cat "${te}2b" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19616,9 +18637,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "udp4 tcp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19647,9 +18666,7 @@ else
 	cat "${te}1a" >&2
 	echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1"
 	cat "${te}1b" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1a" >${tdiff}_a; then
 	$PRINTF "$FAILED (diff a)\n"
 	echo "$CMD0 &"
@@ -19660,9 +18677,7 @@ else
 	cat "${te}1b" >&2
 	echo "// diff a:" >&2
 	cat "${tdiff}_a" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1b" >${tdiff}_b; then
 	$PRINTF "$FAILED (diff b)\n"
 	echo "$CMD0 &"
@@ -19673,9 +18688,7 @@ else
 	cat "${te}1b" >&2
 	echo "// diff b:" >&2
 	cat "${tdiff}_b" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -19684,8 +18697,7 @@ else
 	if [ "$DEBUG" ];   then cat "${te}1a" >&2; fi
 	if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10.; } |$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1b" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19715,9 +18727,7 @@ elif ! cond=$(checkconds \
 		  "fork" \
 		  "udp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19739,35 +18749,28 @@ else
 	cat "${te}0" >&2
 	echo "echo \$da\" |$CMD1"
 	cat "${te}1" >&2
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
     elif [ $(grep -c " E open(" "${te}0") -eq 0 ]; then
 	$PRINTF "$CANT (no error)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	echo "echo \$da\" |$CMD1"
 	cat "${te}1" >&2
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
     elif [ $(grep -c " E open(" "${te}0") -ge 2 ]; then
 	$PRINTF "$FAILED (this bug)\n"
 	echo "$CMD0 &"
 	head -n 2 "${te}0" >&2
 	echo "echo \$da\" |$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19795,9 +18798,7 @@ elif ! cond=$(checkconds \
 		  "fork" \
 		  "udp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19822,9 +18823,7 @@ else
 	cat "${te}1a" >&2
 	echo "echo \$da b\" |$CMD1"
 	cat "${te}1b" >&2
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
     elif [ $(grep -c " I socketpair(" "${te}0") -ne 2 ]; then
 	$PRINTF "$CANT (not 2 socketpair())\n"
 	echo "$CMD0 &"
@@ -19833,9 +18832,7 @@ else
 	cat "${te}1a" >&2
 	echo "echo \$da b\" |$CMD1"
 	cat "${te}1b" >&2
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
     elif ! diff <(grep " I socketpair(" "${te}0" |head -n 1 |sed 's/.*\( I socketpair.*\)/\1/') <(grep " I socketpair(" "${te}0" |tail -n 1 |sed 's/.*\( I socketpair.*\)/\1/') >/dev/null 2>&1; then
 	$PRINTF "$FAILED (this bug)\n"
 	echo "$CMD0 &"
@@ -19844,9 +18841,7 @@ else
 	cat "${te}1a" >&2
 	echo "echo \$da b\" |$CMD1"
 	cat "${te}1b" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
@@ -19855,8 +18850,7 @@ else
 	if [ "$DEBUG" ];   then cat "${te}1a" >&2; fi
 	if [ "$VERBOSE" ]; then echo "echo \$da b\" |$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1b" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19885,9 +18879,7 @@ elif ! cond=$(checkconds \
 		  "pf" \
 		  "ip4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -19901,15 +18893,12 @@ else
 	$PRINTF "$FAILED (rc0=$rc0)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -19954,9 +18943,7 @@ TEST="$NAME: TCP-L with -0 accepts IPv4"
 if ! eval $NUMCOND; then :
 elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 elif ! cond=$(checkconds \
 		  "" \
 		  "" \
@@ -19966,9 +18953,7 @@ elif ! cond=$(checkconds \
 		  "" \
 		  "tcp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     opt0=
     if SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-0[[:space:]]' >/dev/null; then
@@ -19996,21 +18981,17 @@ else
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1)) ;;
+	ok ;;
       Linux)
 	$PRINTF "$FAILED (rc1=$rc1)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME" ;;
+	failed ;;
       *)
 	  $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-	  numCANT=$((numCANT+1))
-	  listCANT="$listCANT $N"
-	  namesCANT="$namesCANT $NAME" ;;
+	  cant ;;
       esac
     else
 	$PRINTF "$OK\n"
@@ -20018,7 +18999,7 @@ else
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
+	ok
     fi
 fi # NUMCOND
  ;;
@@ -20035,21 +19016,17 @@ TEST="$NAME: TCP-L with -0 accepts IPv6"
 if ! eval $NUMCOND; then :
 elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 elif ! cond=$(checkconds \
 		  "" \
 		  "" \
 		  "" \
 		  "IP6 TCP LISTEN FILE" \
 		  "TCP-LISTEN TCP6-CONNECT FILE" \
-		  "" \
+		  "ai-addrconfig" \
 		  "tcp6" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -20071,23 +19048,20 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
+	ok
     fi
 fi # NUMCOND
  ;;
 esac
 N=$((N+1))
 
-
 BIN_TIMEOUT=
 if type timeout >/dev/null 2>&1; then
     BIN_TIMEOUT=timeout
@@ -20124,9 +19098,7 @@ elif ! cond=$(checkconds \
 		  "${option%%=*}" \
 		  "$(tolower $PROTO)4 $(tolower $PROTO)6" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -20134,16 +19106,14 @@ else
     da="test$N $(date) $RANDOM"
     case X$IPPORT in
 	XPORT)  newport $(tolower $PROTO); _PORT=$PORT ;;
-	XPROTO) echo "IPPROTO=\"$IPPROTO\""
+	XPROTO) #echo "IPPROTO=\"$IPPROTO\""
 		_PORT=$IPPROTO ;;
     esac
     CMD0="$TRACE $SOCAT $opts ${ADDR}:$_PORT,$option,$ACCEPT_TIMEOUT PIPE"
     printf "test $F_n $TEST... " $N
     if [ -z "$ACCEPT_TIMEOUT" ] && [ -z "$BIN_TIMEOUT" ]; then
 	$PRINTF "$CANT (would block)\n"
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
-	namesCANT="$namesCANT $NAME"
+	cant
     else
       if [ "$BIN_TIMEOUT" ]; then
 	$BIN_TIMEOUT 0.1 $CMD0 >/dev/null 2>"${te}0"
@@ -20156,15 +19126,12 @@ else
 	$PRINTF "$FAILED (rc0=$rc0)\n"
 	echo "$CMD0 &"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
     fi 	# not would block
 fi # NUMCOND
@@ -20224,9 +19191,7 @@ elif ! cond=$(checkconds \
 		  "bind" \
 		  "$protov" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -20234,7 +19199,7 @@ else
     da="test$N $(date) $RANDOM"
     case X$IPPORT in
 	XPORT)  newport $(tolower $PROTO); _PORT=$PORT ;;
-	XPROTO) echo "IPPROTO=\"$IPPROTO\""
+	XPROTO) #echo "IPPROTO=\"$IPPROTO\""
 		_PORT=$IPPROTO ;;
     esac
     CMD0="$TRACE $SOCAT $opts -u /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1"
@@ -20245,20 +19210,16 @@ else
 	$PRINTF "$FAILED (rc0=$rc0)\n"
 	echo "$CMD0"
 	cat "${te}0" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 done <<<"
 UDP-SENDTO               udp4     PORT
@@ -20294,9 +19255,7 @@ elif ! cond=$(checkconds \
 		  "bind" \
 		  "$protov" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -20304,7 +19263,7 @@ else
     da="test$N $(date) $RANDOM"
     case X$IPPORT in
 	XPORT)  newport $(tolower $PROTO); _PORT=$PORT ;;
-	XPROTO) echo "IPPROTO=\"$IPPROTO\""
+	XPROTO) #echo "IPPROTO=\"$IPPROTO\""
 		_PORT=$IPPROTO ;;
     esac
     CMD0="$TRACE $SOCAT $opts ${ADDR%%-*}-LISTEN:$_PORT,pf=ip4 PIPE"
@@ -20322,20 +19281,16 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
 esac
-PORT=$((PORT+1))
 N=$((N+1))
 done <<<"
 TCP-CONNECT                tcp4      PORT
@@ -20349,6 +19304,10 @@ DCCP-CONNECT               dccp4     PORT
 "
 
 
+# Above tests introduced before or with 1.8.0.1
+#==============================================================================
+# Below test introduced with 1.8.0.2
+
 # Test the readline.sh file overwrite vulnerability
 NAME=READLINE_SH_OVERWRITE
 case "$TESTS" in
@@ -20367,9 +19326,7 @@ elif ! cond=$(checkconds \
 		  "" \
 		  "" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.file"
     te="$td/test$N.stderr"
@@ -20385,9 +19342,7 @@ else
 #	$PRINTF "$CANT (rc0=$rc0)\n"
 #	echo "$CMD0"
 #	cat "${te}0" >&2
-#	numCANT=$((numCANT+1))
-#	listCANT="$listCANT $N"
-#	namesCANT="$namesCANT $NAME"
+#	cant
 #    elif ! echo "$da" |diff - "$tf" >$tdiff; then
     if ! echo "$da" |diff - "$tf" >$tdiff; then
 	$PRINTF "$FAILED (diff)\n"
@@ -20395,30 +19350,773 @@ else
 	cat "${te}0" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
 fi # NUMCOND
  ;;
 esac
 N=$((N+1))
 
+
+# Above test introduced with 1.8.0.2
+#==============================================================================
+# Below tests introduced with 1.8.0.3 (or later)
+
+# Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4
+for SUFFIX in CONNECT LISTEN; do
+
+suffix=$(tolower $SUFFIX)
+if [ "$SUFFIX" = LISTEN ]; then
+    test=listen
+    LISTEN=LISTEN
+    listen=listen
+else
+    test=dont
+    LISTEN=
+    listen=
+fi
+NAME=SOCKS5${SUFFIX}_TCP4
+case "$TESTS" in
+*%$N%*|*%functions%*|*%socks%*|*%socks5%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$test%*|*%$NAME%*)
+TEST="$NAME: SOCKS5-$SUFFIX over TCP/IPv4"
+if ! eval $NUMCOND; then :;
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "od ./socks5server-echo.sh" \
+		  "SOCKS5 IP4 TCP $LISTEN STDIO" \
+		  "TCP4-LISTEN EXEC STDIN SOCKS5-$SUFFIX" \
+		  "so-reuseaddr readbytes" \
+		  "tcp4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp4 	# provide free port number in $PORT
+    CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks5server-echo.sh\""
+    CMD1="$TRACE $SOCAT $opts STDIO SOCKS5-$SUFFIX:$LOCALHOST:127.0.0.1:80,pf=ip4,socksport=$PORT"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid0=$!	# background process id
+    waittcp4port $PORT 1
+    echo "$da" |$CMD1 >${tf}1 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null
+    wait
+    if [ "$rc1" -ne 0 ]; then
+	$PRINTF "$FAILED (rc1=$rc1)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    fi
+fi ;; # NUMCOND, feats
+esac
+N=$((N+1))
+
+done 	# CONNECT LISTEN
+
+
+# Test UDP-LISTEN with bind to IPv4 address; this failed with Socat version
+# 1.8.0.0
+NAME=UDP_LISTEN_BIND4
+case "$TESTS" in
+*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%udp%*|*%udp4%*|*%listen%*|*%$NAME%*)
+TEST="$NAME: Test UDP-LISTEN with bind to IPv4 addr"
+# Start a listener with UDP-LISTEN and bind to 127.0.0.1; when it starts
+# without error and even processes data the test succeeded
+if ! eval $NUMCOND; then :
+# Remove unneeded checks, adapt lists of the remaining ones
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "IP4 UDP LISTEN STDIO PIPE" \
+		  "UDP-LISTEN PIPE STDIO UDP" \
+		  "bind" \
+		  "udp4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    newport udp4
+    CMD0="$TRACE $SOCAT $opts UDP-LISTEN:$PORT,bind=$LOCALHOST4 PIPE"
+    CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$LOCALHOST4:$PORT"
+    printf "test $F_n $TEST... " $N
+    $CMD0 >/dev/null 2>"${te}0" &
+    pid0=$!
+    waitudp4port $PORT 1
+    echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null; wait
+    if [ "$rc1" -ne 0 ]; then
+	$PRINTF "$FAILED (rc1=$rc1)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+
+# Test for useful error message on UNIX-L with bind option
+NAME=UNIX_L_BIND
+case "$TESTS" in
+*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%listen%*|*%unix%*|*%bind%*|*%$NAME%*)
+TEST="$NAME: Test if UNIX-L with bind does not fail INTERNAL"
+# Invoke Socat with a UNIX-LISTEN address with bind option.
+# When there is no INTERNAL error the test succeeded.
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "UNIX LISTEN PIPE" \
+		  "UNIX-LISTEN PIPE" \
+		  "bind,accept-timeout" \
+		  "" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+    ts="$td/test$N.sock"
+    tb="$td/test$N.bind"
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,accept-timeout=0.001,bind=$tb PIPE"
+    printf "test $F_n $TEST... " $N
+    $CMD0 >/dev/null 2>"${te}0"
+    rc0=$?
+    if [ "$rc0" -eq 0 ]; then
+	$PRINTF "$CANT (rc0=$rc0)\n"
+	echo "$CMD0"
+	cat "${te}0" >&2
+	cant
+    elif grep " E .* INTERNAL " "${te}0" >/dev/null; then
+	$PRINTF "$FAILED (INTERNAL)\n"
+	echo "$CMD0"
+	cat "${te}0" >&2
+	failed
+    else
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	ok
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+
+while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do
+if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
+
+if [ "X$CSUFF" != "X-" ]; then
+    CADDR=$ADDR-$CSUFF
+else
+    CADDR=$ADDR
+fi
+CNAME=$(echo $CADDR |tr - _)
+PROTO=$(toupper $proto)
+FEAT=$ADDR
+addr=$(tolower $ADDR)
+runs=$proto
+case "$CPARMS" in
+    PORT) newport $proto; CPARMS=$PORT ;;
+    *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;;
+esac
+#echo "PORT=$PORT CPARMS=$CPARMS" >&2
+case "X$COPTS" in
+    X-) COPTS= ;;
+    *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;;
+esac
+case "X$SOPTS" in
+    X-) SOPTS= ;;
+esac
+
+# Test if bind on *-CONNECT selects the matching IP version
+NAME=${CNAME}_BIND_6_4
+case "$TESTS" in
+*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%${proto}6%*|*%ip4%*|*%ip6%*|*%listen%*|*%bind%*|*%socket%*|*%$NAME%*)
+TEST="$NAME: $ADDR bind chooses matching IPv"
+# Have an IPv4 listener
+# Host name localhost-4-6.dest-unreach.net resolves to both 127.0.0.1 and [::1],
+# consequently; with option -6 we have Socat try IPv6 first, and on failure try
+# IPv4
+# Start Socat TCP-CONNECT with -6 and binding and connecting to this host name;
+# Up to version 1.8.0.0 Socat only tries IPv6 and fails
+# With version 1.8.0.1 Socat first connects using IPv6, and due to ECONNREFUSED
+# tries to connect using IPv4 but still binds to IPv6 which fails with
+# EAFNOSUPPORT "Address family not supported by protocol";
+# With 1.8.0.3 the connection attempt with IPv4 correctly binds to IPv4 and
+# succeeds
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "$FEAT IP4 IP6 TCP LISTEN STDIO PIPE" \
+		  "$CADDR $SADDR STDIO PIPE" \
+		  "bind pf" \
+		  "${runs}4 ${runs}6" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N
+    cant
+elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
+    cant
+elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    CMD0="$TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE"
+    CMD1="$TRACE $SOCAT $opts -6 STDIO $CADDR:localhost-4-6.dest-unreach.net:$CPARMS,bind=localhost-4-6.dest-unreach.net,$COPTS"
+    printf "test $F_n $TEST... " $N
+    $CMD0 >/dev/null 2>"${te}0" &
+    pid0=$!
+    wait${proto}4port $PORT 1
+    { echo "$da"; relsleep 10; } |$CMD1 >"${tf}1" 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null; wait
+    if echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then
+	$PRINTF "$FAILED (EAFNOSUPPORT)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif [ "$rc1" -ne 0 ]; then
+	$PRINTF "$CANT (unexpected error)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	cant
+    elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$CANT (unexpected problem)\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	cant
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+done <<<"
+TCP     tcp  CONNECT PORT        -                           TCP-L  -                                         PIPE
+SCTP    sctp CONNECT PORT        -                           SCTP-L -                                         PIPE
+DCCP    dccp CONNECT PORT        -                           DCCP-L -                                         PIPE
+OPENSSL tcp  CONNECT PORT        cafile=testsrv.pem,verify=0 SSL-L  cert=testsrv.pem,key=testsrv.key,verify=0 PIPE
+SOCKS4  tcp  -       32.98.76.54:32109 socksport=\$PORT,socksuser=nobody  TCP-L  -             EXEC:./socks4echo.sh
+SOCKS5  tcp  CONNECT \$PORT:127.0.0.1:80  -                               TCP-L  -      EXEC:./socks5server-echo.sh
+PROXY   tcp  CONNECT 127.0.0.1:80        proxyport=\$PORT,crlf            TCP-L  crlf          EXEC:./proxyecho.sh
+"
+
+
+# Test if TCP-CONNECT with host name resolving to IPv6 first and IPv4 second
+# (due to option -6) chooses IPv4 when bind option is specific.
+# This works only since version 1.8.0.3
+NAME=TCP_BIND_4
+case "$TESTS" in
+*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*)
+TEST="$NAME: TCP-CONNECT chooses IPv4 from bind"
+# Start a TCP4 listener with echo function
+# Start Socat TCP-CONNECT with host name resolving to IPv6 first and IPv4
+# second, and bind to IPv4 explicitly.
+# When connection and data transfer work the test succeeded.
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "IP4 IP6 TCP LISTEN STDIO PIPE" \
+		  "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \
+		  "" \
+		  "tcp4 tcp6" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N
+    cant
+elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
+    cant
+elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    newport tcp4
+    CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT PIPE"
+    CMD1="$TRACE $SOCAT $opts -6 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=127.0.0.1"
+    printf "test $F_n $TEST... " $N
+    $CMD0 >/dev/null 2>"${te}0" &
+    pid0=$!
+    waittcp4port $PORT 1
+    echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null; wait
+    if echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then
+	$PRINTF "$FAILED (EAFNOSUPPORT)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif [ "$rc1" -ne 0 ]; then
+	$PRINTF "$CANT (unexpected error)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	cant
+    elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$CANT (unexpected problem)\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	cant
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+# Test if TCP-CONNECT with host name resolving to IPv4 first and IPv6 second
+# (due to option -4) chooses IPv6 when bind option is specific.
+# This works only since version 1.8.0.3
+NAME=TCP_BIND_6
+case "$TESTS" in
+*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*)
+TEST="$NAME: TCP-CONNECT chooses IPv6 from bind"
+# Start a TCP6 listener with echo function
+# Start Socat TCP-CONNECT with host name resolving to IPv4 first and IPv6
+# second, and bind to IPv6 explicitly.
+# When connection and data transfer work the test succeeded.
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "IP4 IP6 TCP LISTEN STDIO PIPE" \
+		  "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \
+		  "" \
+		  "tcp4 tcp6" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-4[[:space:]]' >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N
+    cant
+elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
+    cant
+elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    newport tcp4
+    CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT PIPE"
+    CMD1="$TRACE $SOCAT $opt -4 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=[::1]"
+    printf "test $F_n $TEST... " $N
+    $CMD0 >/dev/null 2>"${te}0" &
+    pid0=$!
+    waittcp4port $PORT 1
+    echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null; wait
+    if echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then
+	$PRINTF "$FAILED (EAFNOSUPPORT)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif [ "$rc1" -ne 0 ]; then
+	$PRINTF "$CANT (unexpected error)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	cant
+    elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$CANT (unexpected problem)\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	cant
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+
+while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do
+if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
+
+if [ "X$CSUFF" != "X-" ]; then
+    CADDR=$ADDR-$CSUFF
+else
+    CADDR=$ADDR
+fi
+CNAME=$(echo $CADDR |tr - _)
+PROTO=$(toupper $proto)
+FEAT=$ADDR
+addr=$(tolower $ADDR)
+runs=$proto
+case "$CPARMS" in
+    PORT) newport $proto; CPARMS=$PORT ;;
+    *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;;
+esac
+#echo "PORT=$PORT CPARMS=$CPARMS" >&2
+case "X$COPTS" in
+    X-) COPTS= ;;
+    *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;;
+esac
+case "X$SOPTS" in
+    X-) SOPTS= ;;
+esac
+
+# Test the retry option with *-CONNECT addresses
+NAME=${CNAME}_RETRY
+case "$TESTS" in
+*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%retry%*|*%$NAME%*)
+TEST="$NAME: $ADDR can retry"
+# Have an IPv4 listener with delay
+# Start a connector whose first attempt must fail; check if the second attempt
+# succeeds.
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "$FEAT IP4 TCP LISTEN STDIO" \
+		  "$CADDR $SADDR STDIO PIPE" \
+		  "pf retry interval" \
+		  "${runs}4 ${runs}6" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N
+    cant
+else
+#    newport $proto
+#echo "PORT=$PORT CPARMS=$CPARMS" >&2
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"
+    CMD0="relsleep 5; $TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE"
+    CMD1="$TRACE $SOCAT $opts -4 STDIO $CADDR:$LOCALHOST:$CPARMS,retry=1,interval=$(relsecs 10),$COPTS"
+    printf "test $F_n $TEST... " $N
+#date +%Y/%m/%d" "%H:%M:%S.%N
+    eval "$CMD0" >/dev/null 2>"${te}0" &
+    pid0=$!
+    { echo "$da"; relsleep 15; } |$CMD1 >"${tf}1" 2>"${te}1"
+    rc1=$?
+    kill $pid0 2>/dev/null; wait
+    if echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then
+	$PRINTF "$FAILED (EAFNOSUPPORT)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif [ "$rc1" -ne 0 ]; then
+	$PRINTF "$CANT (unexpected error)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	cant
+    elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    else
+	$PRINTF "$CANT (unexpected problem)\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	cant
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+done <<<"
+TCP     tcp  CONNECT PORT        -                           TCP-L  -                                         PIPE
+SCTP    sctp CONNECT PORT        -                           SCTP-L -                                         PIPE
+DCCP    dccp CONNECT PORT        -                           DCCP-L -                                         PIPE
+OPENSSL tcp  CONNECT PORT        cafile=testsrv.pem,verify=0 SSL-L  cert=testsrv.pem,key=testsrv.key,verify=0 PIPE
+SOCKS4  tcp  -       32.98.76.54:32109 socksport=\$PORT,socksuser=nobody  TCP-L  -             EXEC:./socks4echo.sh
+SOCKS5  tcp  CONNECT \$PORT:127.0.0.1:80  -                               TCP-L  -      EXEC:./socks5server-echo.sh
+PROXY   tcp  CONNECT 127.0.0.1:80        proxyport=\$PORT,crlf            TCP-L  crlf          EXEC:./proxyecho.sh
+"
+
+#------------------------------------------------------------------------------
+
+while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE SLOW; do
+if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
+
+if [ "X$CSUFF" != "X-" ]; then
+    CADDR=$ADDR-$CSUFF
+else
+    CADDR=$ADDR
+fi
+CNAME=$(echo $CADDR |tr - _)
+PROTO=$(toupper $proto)
+FEAT=$ADDR
+addr=$(tolower $ADDR)
+runs=$proto
+case "$CPARMS" in
+    PORT) newport $proto; CPARMS=$PORT ;;
+    *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;;
+esac
+#echo "PORT=$PORT CPARMS=$CPARMS" >&2
+case "X$COPTS" in
+    X-) COPTS= ;;
+    *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;;
+esac
+case "X$SOPTS" in
+    X-) SOPTS= ;;
+esac
+
+# Test the fork and max-children options with CONNECT addresses
+NAME=${CNAME}_MAXCHILDREN
+case "$TESTS" in
+*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%fork%*|*%maxchildren%*|*%$NAME%*)
+TEST="$NAME: $ADDR with fork,max-children"
+# Start a reader process that transfers received data to an output file;
+# run a sending client that forks at most 2 parallel child processes that
+# transfer data from a simple directory queue to the reader but afterwards
+# hang some time to prevent more child process.
+# After the first two transfers write the third record directly to the file;
+# a little later the Socat mechanism puts a 4th record.
+# When the 4 records in the output file have the expected order the test
+# succeeded.
+if ! eval $NUMCOND; then :
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "" \
+		  "$FEAT IP4 TCP LISTEN STDIO PIPE" \
+		  "$CADDR $SADDR STDIO PIPE" \
+		  "pf" \
+		  "${runs}4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+#    newport $proto
+#echo "PORT=$PORT CPARMS=$CPARMS" >&2
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    tQ="$td/test$N.q"
+    ext=q.y.f. 	# some unusual extension to prevent from deleting wrong file
+    da="test$N $(date) $RANDOM"
+    CMD0="$TRACE $SOCAT $opts -lp reader $SADDR:$PORT,$SOPTS,pf=2,reuseaddr,fork $PIPE"
+    CMD1="$TRACE $SOCAT $opts -4 $CADDR:$LOCALHOST:$CPARMS,fork,max-children=2,interval=$(relsecs $((2*SLOW))),$COPTS SHELL:'shopt\ -s\ nullglob;\ F=\$(ls -1 $tQ|grep .$ext\\\$|head -n 1);\ test\ \"\$F\"\ ||\ exit;\ cat\ $tQ/\$F;\ mv\ -i\ $tQ/\$F\ $tQ/.\$F;\ sleep\ $(relsecs $((5*SLOW)) )'!!-"
+    printf "test $F_n $TEST... " $N
+    # create data for the generator
+    mkdir -p $tQ
+    echo "$da 1" >$tQ/01.$ext
+    echo "$da 2" >$tQ/02.$ext
+    echo "$da 4" >$tQ/04.$ext
+    eval "$CMD0" 2>"${te}0" &
+    pid0=$!
+    relsleep $((1*SLOW))
+    eval $CMD1 2>"${te}1" >>"${tf}0" &
+    pid1=$!
+    relsleep $((4*SLOW))
+#date +%Y/%m/%d" "%H:%M:%S.%N
+    echo "$da 3" >>"${tf}0"
+    relsleep $((4*SLOW))
+    kill $(childpids -r $pid0) $pid0 $(childpids -r $pid1) $pid1 2>/dev/null
+    wait 2>/dev/null
+    if ! test -e "${tf}0" || ! test -s "${tf}0"; then
+	$PRINTF "$FAILED\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	failed
+    elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >$tdiff; then
+	$PRINTF "$OK\n"
+	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
+	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
+	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
+	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+	ok
+    else
+	$PRINTF "$FAILED (diff)\n"
+	echo "$CMD0 &"
+	cat "${te}0" >&2
+	echo "$CMD1"
+	cat "${te}1" >&2
+	echo "// diff:" >&2
+	cat "$tdiff" >&2
+	failed
+    fi
+fi # NUMCOND
+ ;;
+esac
+N=$((N+1))
+
+done <<<"
+TCP     tcp  CONNECT PORT         -                                TCP-L  -                           PIPE 1
+SCTP    sctp CONNECT PORT         -                                SCTP-L -                           PIPE 1
+DCCP    dccp CONNECT PORT         -                                DCCP-L -                           PIPE 1
+OPENSSL tcp  CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE 7
+SOCKS4  tcp  - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L  -           EXEC:./socks4echo.sh 6
+SOCKS5  tcp  CONNECT \$PORT:127.0.0.1:80  -                        TCP-L  -    EXEC:./socks5server-echo.sh 5
+PROXY   tcp  CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf            TCP-L  crlf         EXEC:./proxyecho.sh 4
+"
+# detto IP6
+
+
+# test combined 4_6/6_4 with retry and fork
+
+
 # end of common tests
 
 ##################################################################################
 #=================================================================================
-# here come tests that might affect your systems integrity. Put normal tests
+# Here come tests that might affect your systems integrity. Put normal tests
 # before this paragraph.
-# tests must be explicitely selected by roottough or name (not number)
+# Tests must be explicitly selected by roottough or name (not number)
 
 NAME=PTYGROUPLATE
 case "$TESTS" in
@@ -20426,7 +20124,7 @@ case "$TESTS" in
 TEST="$NAME: pty with group-late works on pty"
 # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of
 # the pty with options user-late, group-late, or perm-late.
-# here we check for correct behaviour. 
+# here we check for correct behaviour.
 # ATTENTION: in case of failure of this test the
 # group of /dev/ptmx might be changed!
 if ! eval $NUMCOND; then :; else
@@ -20462,17 +20160,14 @@ if [ $rc1 -ne 0 ]; then
     echo "$CMD1"
     cat "${te}0"
     cat "${te}1"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 elif echo "$da" |diff - "$tf" >$tdiff; then
     $PRINTF "$OK\n"
-    numOK=$((numOK+1))
-    listOK="$listOK $N"
+    ok
 else
     $PRINTF "$FAILED\n"
     cat "$tdiff"
-    numFAIL=$((numFAIL+1))
-    listFAIL="$listFAIL $N"
+    failed
 fi
 if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then
     $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n"
@@ -20493,8 +20188,11 @@ set -- $listOK;   while [ "$1" ]; do echo "$1"; shift; done >"$td/success.lst"
 ln -sf "$td/success.lst" .
 set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst"
 ln -sf "$td/failed.lst" .
-sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt"
-ln -sf "$td/result.txt" .
+#sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt"
+#ln -sf "$td/result.txt" .
+
+ln -sf "$td/results.txt" .
+
 if [ "$numCANT" -gt 0 ]; then
     echo "CANT: $listCANT"
 fi
@@ -20507,8 +20205,6 @@ if [ -z "$OPT_EXPECT_FAIL" ]; then
     exit 	# with rc from above statement
 fi
 
-#set -vx
-
 if [ "$OPT_EXPECT_FAIL" ]; then
     diff  <(set -- $(echo "$EXPECT_FAIL" |tr ',' ' '); while [ "$1" ]; do echo "$1"; shift; done) "$td/failed.lst" >"$td/failed.diff"
     ln -sf "$td/failed.diff" .
@@ -20535,7 +20231,7 @@ rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips*
 # end
 
 # too dangerous - run as root and having a shell problem, it might purge your
-# file systems 
+# file systems
 #rm -r "$td"
 
 # sometimes subprocesses hang; we want to see this
@@ -20564,9 +20260,7 @@ elif ! cond=$(checkconds \
 		  "so-reuseaddr" \
 		  "tcp4" ); then
     $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
-    numCANT=$((numCANT+1))
-    listCANT="$listCANT $N"
-    namesCANT="$namesCANT $NAME"
+    cant
 else
     tf="$td/test$N.stdout"
     te="$td/test$N.stderr"
@@ -20589,9 +20283,7 @@ else
 	cat "${te}0" >&2
 	echo "$CMD1"
 	cat "${te}1" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
 	$PRINTF "$FAILED (diff)\n"
 	echo "$CMD0 &"
@@ -20600,9 +20292,7 @@ else
 	cat "${te}1" >&2
 	echo "// diff:" >&2
 	cat "$tdiff" >&2
-	numFAIL=$((numFAIL+1))
-	listFAIL="$listFAIL $N"
-	namesFAIL="$namesFAIL $NAME"
+	failed
     elif [ ??? ]; then
 	# The test could not run meaningfully
 	$PRINTF "$CANT\n"
@@ -20610,17 +20300,16 @@ else
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numCANT=$((numCANT+1))
-	listCANT="$listCANT $N"
+	cant
     else
 	$PRINTF "$OK\n"
 	if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
 	if [ "$DEBUG" ];   then cat "${te}0" >&2; fi
 	if [ "$VERBOSE" ]; then echo "$CMD1"; fi
 	if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
-	numOK=$((numOK+1))
-	listOK="$listOK $N"
+	ok
     fi
+    result
 fi # NUMCOND
  ;;
 esac
diff --git a/xio-ascii.c b/xio-ascii.c
index 2fb61b9..9493103 100644
--- a/xio-ascii.c
+++ b/xio-ascii.c
@@ -11,7 +11,7 @@
 
 #include "xio-ascii.h"
 
-/* for each 6 bit pattern we have an ASCII character in the arry */
+/* For each 6 bit pattern we have an ASCII character in the array */
 const static int base64chars[] = {
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
   'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
diff --git a/xio-exec.c b/xio-exec.c
index bed513c..303d429 100644
--- a/xio-exec.c
+++ b/xio-exec.c
@@ -84,7 +84,8 @@ static int xioopen_exec(
       while (*strp == ' ') {
 	 while (*++strp == ' ')  ;
 	 if ((pargc & 0x07) == 0) {
-	    pargv = Realloc(pargv, (pargc+8)*sizeof(char *));
+	    /*0 pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); */
+	    pargv = Realloc3(pargv, (pargc+8)*sizeof(char *), pargc*sizeof(char *));
 	    if (pargv == NULL)  return STAT_RETRYLATER;
 	 }
 	 pargv[pargc++] = tokp;
diff --git a/xio-fd.c b/xio-fd.c
index 6f50629..70b8634 100644
--- a/xio-fd.c
+++ b/xio-fd.c
@@ -31,7 +31,7 @@ const struct optdesc opt_o_noinherit = { "o-noinherit", "noinherit", OPT_O_NOINH
 const struct optdesc opt_o_noatime   = { "o-noatime",   "noatime",   OPT_O_NOATIME,   GROUP_OPEN|GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NOATIME };
 #endif
 /****** for ALL addresses - with fcntl(F_SETFD) ******/
-const struct optdesc opt_cloexec   = { "cloexec",   NULL, OPT_CLOEXEC,   GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC };
+const struct optdesc opt_cloexec     = { "cloexec",     NULL,        OPT_O_CLOEXEC,   GROUP_FD,            PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC };
 /****** ftruncate() ******/
 /* this record is good for ftruncate() or ftruncate64() if available */
 #if HAVE_FTRUNCATE64
diff --git a/xio-file.c b/xio-file.c
index c19be4b..cb61247 100644
--- a/xio-file.c
+++ b/xio-file.c
@@ -20,7 +20,7 @@ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xiof
 const struct optdesc opt_o_rdonly    = { "o-rdonly",    "rdonly", OPT_O_RDONLY,    GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDONLY, O_ACCMODE };
 const struct optdesc opt_o_wronly    = { "o-wronly",    "wronly", OPT_O_WRONLY,    GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_WRONLY, O_ACCMODE };
 const struct optdesc opt_o_rdwr      = { "o-rdwr",      "rdwr",   OPT_O_RDWR,      GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDWR,   O_ACCMODE };
-const struct optdesc opt_o_create    = { "o-create",    "creat",  OPT_O_CREATE,    GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT };
+const struct optdesc opt_o_creat     = { "o-creat",     "creat",  OPT_O_CREAT,     GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT };
 const struct optdesc opt_o_excl      = { "o-excl",      "excl",   OPT_O_EXCL,      GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_EXCL };
 const struct optdesc opt_o_noctty    = { "o-noctty",    "noctty", OPT_O_NOCTTY,    GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NOCTTY };
 #ifdef O_SYNC
diff --git a/xio-file.h b/xio-file.h
index f592d68..be01378 100644
--- a/xio-file.h
+++ b/xio-file.h
@@ -8,7 +8,7 @@
 extern const struct optdesc opt_o_rdonly;
 extern const struct optdesc opt_o_wronly;
 extern const struct optdesc opt_o_rdwr;
-extern const struct optdesc opt_o_create;
+extern const struct optdesc opt_o_creat;
 extern const struct optdesc opt_o_excl;
 extern const struct optdesc opt_o_noctty;
 extern const struct optdesc opt_o_sync;
diff --git a/xio-fs.c b/xio-fs.c
index 1678828..5630f23 100644
--- a/xio-fs.c
+++ b/xio-fs.c
@@ -87,7 +87,7 @@ const struct optdesc opt_fs_noatime      = { "fs-noatime",      "noatime",
 #endif /* FS_NOATIME_FL */
 
 /* FS_DIRTY_FL ??? */
-/* FS_COMPRBLK_FL one ore more compress clusters */
+/* FS_COMPRBLK_FL one or more compress clusters */
 /* FS_NOCOMPR_FL access raw compressed data */
 /* FS_ECOMPR_FL compression error */
 /* FS_BTREE_FL btree format dir */
diff --git a/xio-interface.c b/xio-interface.c
index d870f87..c09aec5 100644
--- a/xio-interface.c
+++ b/xio-interface.c
@@ -71,7 +71,7 @@ int _xioopen_interface(const char *ifname,
 
    if (ifindex(ifname, &ifidx, -1) < 0) {
       Error1("unknown interface \"%s\"", ifname);
-      ifidx = 0;	/* desparate attempt to continue */
+      ifidx = 0;	/* desperate attempt to continue */
    }
 
    if (sfd->howtoend == END_UNSPEC)
@@ -276,7 +276,7 @@ int _xiointerface_apply_iff(
 
 
 #if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA
-/* Converts the ancillary message in *cmsg into a form useable for further
+/* Converts the ancillary message in *cmsg into a form usable for further
    processing. Knows the specifics of common message types.
    On PACKET_AUXDATA it stored the ancillary data in the XFD.
    For other types:
diff --git a/xio-ip.c b/xio-ip.c
index 6821571..2b7deaf 100644
--- a/xio-ip.c
+++ b/xio-ip.c
@@ -68,7 +68,7 @@ const struct optdesc opt_ip_multicast_if  ={"ip-multicast-if",  "multicast-if",
 #ifdef IP_PKTOPTIONS
 const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS };
 #endif
-#ifdef IP_ADD_MEMBERSHIP
+#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN)
 const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IP, IP_ADD_MEMBERSHIP };
 #endif
 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
@@ -161,6 +161,79 @@ int Res_init(void) {
 #endif /* HAVE_RESOLV_H */
 
 
+/* Looks for a bind option and, if found, passes it to resolver;
+   for IP (v4, v6) and raw (PF_UNSPEC);
+   returns list of addrinfo results;
+   returns STAT_OK if option exists and could be resolved,
+   STAT_NORETRY if option exists but had error,
+   or STAT_NOACTION if it does not exist */
+int retropt_bind_ip(
+	struct opt *opts,
+	int af,
+	int socktype,
+	int ipproto,
+	struct addrinfo ***bindlist,
+	int feats,	/* TCP etc: 1..address allowed,
+			   3..address and port allowed
+			*/
+	const int ai_flags[2])
+{
+   const char portsep[] = ":";
+   const char *ends[] = { portsep, NULL };
+   const char *nests[] = { "[", "]", NULL };
+   bool portallowed;
+   char *bindname, *bindp;
+   char hostname[512], *hostp = hostname, *portp = NULL;
+   size_t hostlen = sizeof(hostname)-1;
+   int parsres;
+   int ai_flags2[2];
+   int result;
+
+   if (retropt_string(opts, OPT_BIND, &bindname) < 0) {
+      return STAT_NOACTION;
+   }
+   bindp = bindname;
+
+      portallowed = (feats>=2);
+      parsres =
+	 nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests,
+		 true, false, false);
+      if (parsres < 0) {
+	 Error1("option too long:  \"%s\"", bindp);
+	 return STAT_NORETRY;
+      } else if (parsres > 0) {
+	 Error1("syntax error in \"%s\"", bindp);
+	 return STAT_NORETRY;
+      }
+      *hostp++ = '\0';
+      if (!strncmp(bindp, portsep, strlen(portsep))) {
+	 if (!portallowed) {
+	    Error("port specification not allowed in this bind option");
+	    return STAT_NORETRY;
+	 } else {
+	    portp = bindp + strlen(portsep);
+	 }
+      }
+
+      /* Set AI_PASSIVE, except when it is explicitely disabled */
+      ai_flags2[0] = ai_flags[0];
+      ai_flags2[1] = ai_flags[1];
+      if (!(ai_flags2[1] & AI_PASSIVE))
+      ai_flags2[0] |= AI_PASSIVE;
+
+      if ((result =
+	   xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp,
+		      af, socktype, ipproto,
+		      bindlist, ai_flags2))
+	  != STAT_OK) {
+	 Error2("error resolving bind option \"%s\" with af=%d", bindname, af);
+	 return STAT_NORETRY;
+      }
+
+      return STAT_OK;
+}
+
+
 #if WITH_DEVTESTS
 
 /* Have a couple of hard coded sockaddr records, to be copied and adapted when
@@ -386,6 +459,7 @@ int _xiogetaddrinfo(const char *node, const char *service,
 #else /* HAVE_PROTOTYPE_LIB_getipnodebyname || nothing */
    struct hostent *host;
 #endif
+   bool restore_proto = false;
    int error_num;
 
    Debug8("_xiogetaddrinfo(node=\"%s\", service=\"%s\", family=%d, socktype=%d, protoco=%d, ai_flags={0x%04x/0x%04x} }, res=%p",
@@ -512,15 +586,16 @@ int _xiogetaddrinfo(const char *node, const char *service,
 	      return EAI_SERVICE;
 	   }
 	   /* Probably unsupported protocol (e.g. UDP-Lite), fallback to 0 */
+	   restore_proto = true;
 	   hints.ai_protocol = 0;
 	   continue;
 	}
       if ((error_num = Getaddrinfo(node, service, &hints, res)) != 0) {
-	 Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %d",
+	 Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %s",
 		node?node:"NULL", service?service:"NULL",
 		hints.ai_flags, hints.ai_family,
 		hints.ai_socktype, hints.ai_protocol,
-		error_num);
+		gai_strerror(error_num));
 	 if (numnode)
 	    free(numnode);
 
@@ -540,6 +615,14 @@ int _xiogetaddrinfo(const char *node, const char *service,
 #endif /* WITH_MSGLEVEL <= E_DEBUG */
    }
 
+   if (restore_proto) {
+      struct addrinfo *record = *res;
+      while (record) {
+	 record->ai_protocol = protocol;
+	 record = record->ai_next;
+      }
+   }
+
 #elif HAVE_PROTOTYPE_LIB_getipnodebyname /* !HAVE_GETADDRINFO */
 
    if (node != NULL) {
@@ -592,7 +675,7 @@ int _xiogetaddrinfo(const char *node, const char *service,
       freehostent(host);
    }
 
-#elsif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */
+#elif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */
 
    if (node != NULL) {
       /* this is not a typical IP6 resolver function - but Linux
@@ -760,6 +843,9 @@ void xiofreeaddrinfo(struct addrinfo **ai_sorted) {
    int ain;
    struct addrinfo *res;
 
+   if (ai_sorted == NULL)
+      return;
+
    /* Find the original *res from getaddrinfo past NULL */
    ain = 0;
    while (ai_sorted[ain] != NULL)
@@ -843,7 +929,7 @@ int xioresolve(const char *node, const char *service,
 }
 
 #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
-/* Converts the ancillary message in *cmsg into a form useable for further
+/* Converts the ancillary message in *cmsg into a form usable for further
    processing. knows the specifics of common message types.
    These are valid for IPv4 and IPv6
    Returns the number of resulting syntax elements in *num
@@ -902,16 +988,20 @@ int xiolog_ancillary_ip(
 	       '\0',
 	       inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
 			      scratch3, sizeof(scratch3)));
+#if HAVE_PKTINFO_IPI_SPEC_DST
       Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s",
 	      xiogetifname(pktinfo->ipi_ifindex, scratch1, -1),
-#if HAVE_PKTINFO_IPI_SPEC_DST
 	      inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr),
 			     scratch2, sizeof(scratch2)),
-#else
-	      "",
-#endif
 	      inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
 			     scratch3, sizeof(scratch3)));
+#else
+      Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s",
+	      xiogetifname(pktinfo->ipi_ifindex, scratch1, -1),
+	      "",
+	      inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
+			     scratch3, sizeof(scratch3)));
+#endif
    }
       return STAT_OK;
 #endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */
@@ -1001,7 +1091,7 @@ int xiolog_ancillary_ip(
       cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1;
       /*!!!*/
       break;
-#if XIO_ANCILLARY_TYPE_SOLARIS
+#if defined(IP_RECVTOS) && XIO_ANCILLARY_TYPE_SOLARIS
    case IP_RECVTOS:
 #else
    case IP_TOS:
@@ -1112,13 +1202,14 @@ int xiotype_ip_add_membership(
 		      opt->value2.u_string/*param2*/,
 		      opt->value3.u_string/*ifindex*/);
 	} else {
-		/*0 opt->value3.u_string = NULL; / * is NULL from init */
+		opt->value3.u_string = NULL; /* is not NULL from init! */
 		Info3("setting option \"%s\" to {\"%s\",\"%s\"}",
 		      ent->desc->defname,
 		      opt->value.u_string/*multiaddr*/,
 		      opt->value2.u_string/*param2*/);
 	}
 #else /* !HAVE_STRUCT_IP_MREQN */
+	opt->value3.u_string = NULL;
 	Info3("setting option \"%s\" to {\"%s\",\"%s\"}",
 	      ent->desc->defname,
 	      opt->value.u_string/*multiaddr*/,
@@ -1128,6 +1219,9 @@ int xiotype_ip_add_membership(
 }
 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
 
+
+#if _WITH_IP4
+
 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
 int xioapply_ip_add_membership(
 	struct single *sfd,
@@ -1352,7 +1446,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) {
    }
    ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr;
    /* second parameter is interface address */
-   rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL,
+   rc = xioresolve(opt->value2.u_string/*ifaddr*/, NULL,
 		   sfd->para.socket.la.soa.sa_family,
 		   SOCK_DGRAM, IPPROTO_IP,
 		   &sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags);
@@ -1361,7 +1455,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) {
    }
    ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr;
    /* third parameter is source address */
-   rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL,
+   rc = xioresolve(opt->value3.u_string/*srcaddr*/, NULL,
 		   sfd->para.socket.la.soa.sa_family,
 		   SOCK_DGRAM, IPPROTO_IP,
 		   &sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags);
@@ -1386,6 +1480,8 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) {
 
 #endif /* HAVE_STRUCT_IP_MREQ_SOURCE */
 
+#endif /* _WITH_IP4 */
+
 
 #if WITH_RESOLVE
 #if HAVE_RESOLV_H
diff --git a/xio-ip.h b/xio-ip.h
index ec94e16..c6c0355 100644
--- a/xio-ip.h
+++ b/xio-ip.h
@@ -49,6 +49,7 @@ extern const struct optdesc opt_res_nsaddr;
 
 extern int xioinit_ip(int *pf, char ipv);
 
+extern int retropt_bind_ip(struct opt *opts, int af, int socktype, int ipproto, struct addrinfo ***bindlist, int feats, const int ai_flags[2]);
 extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, struct addrinfo ***ai_sorted, const int ai_flags[2]);
 extern void xiofreeaddrinfo(struct addrinfo **ai_sorted);
 extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted);
diff --git a/xio-ip6.c b/xio-ip6.c
index 04eff08..221f01f 100644
--- a/xio-ip6.c
+++ b/xio-ip6.c
@@ -23,7 +23,7 @@ static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen);
 #ifdef IPV6_V6ONLY
 const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6ONLY, GROUP_SOCK_IP6, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_V6ONLY };
 #endif
-#ifdef IPV6_JOIN_GROUP
+#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN)
 const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IPV6, IPV6_JOIN_GROUP };
 #endif
 #ifdef MCAST_JOIN_SOURCE_GROUP
@@ -249,7 +249,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) {
 
 #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
 /* provides info about the ancillary message:
-   converts the ancillary message in *cmsg into a form useable for further
+   converts the ancillary message in *cmsg into a form usable for further
    processing. knows the specifics of common message types.
    returns the number of resulting syntax elements in *num
    returns a sequence of \0 terminated type strings in *typbuff
diff --git a/xio-ipapp.c b/xio-ipapp.c
index 1cb1b64..eab2078 100644
--- a/xio-ipapp.c
+++ b/xio-ipapp.c
@@ -6,7 +6,7 @@
 
 #include "xiosysincludes.h"
 
-#if WITH_TCP || WITH_UDP
+#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE
 
 #include "xioopen.h"
 #include "xio-socket.h"
@@ -19,7 +19,8 @@ const struct optdesc opt_sourceport = { "sourceport", "sp",       OPT_SOURCEPORT
 /*const struct optdesc opt_port = { "port",  NULL,    OPT_PORT,        GROUP_IPAPP, PH_BIND,    TYPE_USHORT,	OFUNC_SPEC };*/
 const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, PH_LATE, TYPE_BOOL, OFUNC_SPEC };
 
-#if WITH_IP4
+
+#if _WITH_IP4 || _WITH_IP6
 /* we expect the form "host:port" */
 int xioopen_ipapp_connect(
 	int argc,
@@ -31,20 +32,18 @@ int xioopen_ipapp_connect(
 {
    struct single *sfd = &xxfd->stream;
    struct opt *opts0 = NULL;
+   const char *hostname = argv[1], *portname = argv[2];
+   int pf = addrdesc->arg3;
    int socktype = addrdesc->arg1;
    int ipproto = addrdesc->arg2;
-   int pf = addrdesc->arg3;
-   const char *hostname = argv[1], *portname = argv[2];
    bool dofork = false;
    int maxchildren = 0;
-   union sockaddr_union us_sa,  *us = &us_sa;
-   socklen_t uslen = sizeof(us_sa);
-   struct addrinfo **themarr, *themp;
-   char infobuff[256];
+   struct addrinfo **bindarr = NULL;
+   struct addrinfo **themarr = NULL;
+   uint16_t bindport = 0;
    bool needbind = false;
    bool lowport = false;
-   int level;
-   int i;
+   int level = E_ERROR;
    int result;
 
    if (argc != 3) {
@@ -52,97 +51,84 @@ int xioopen_ipapp_connect(
       return STAT_NORETRY;
    }
 
-   if (sfd->howtoend == END_UNSPEC)
-      sfd->howtoend = END_SHUTDOWN;
+   /* Apply and retrieve some options */
+   result = _xioopen_ipapp_init(sfd, xioflags, opts,
+				&dofork, &maxchildren,
+				&pf, &socktype, &ipproto);
+   if (result != STAT_OK)
+      return result;
 
-   if (applyopts_single(sfd, opts, PH_INIT) < 0)
-      return -1;
-   applyopts(sfd, -1, opts, PH_INIT);
+   opts0 = opts; 	/* save remaining options for each loop */
+   opts = NULL;
 
-   retropt_bool(opts, OPT_FORK, &dofork);
-   if (dofork) {
-      if (!(xioflags & XIO_MAYFORK)) {
-	 Error("option fork not allowed here");
-	 return STAT_NORETRY;
-      }
-      sfd->flags |= XIO_DOESFORK;
-   }
+   Notice2("opening connection to %s:%s", hostname, portname);
 
-   retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
-
-   if (! dofork && maxchildren) {
-       Error("option max-children not allowed without option fork");
-       return STAT_NORETRY;
-   }
-
-   if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
-			      sfd->para.socket.ip.ai_flags,
-			      &themarr, us, &uslen, &needbind, &lowport,
-			      socktype) != STAT_OK) {
-      return STAT_NORETRY;
-   }
-
-   if (dofork) {
-      xiosetchilddied();	/* set SIGCHLD handler */
-   }
-
-   if (xioparms.logopt == 'm') {
-      Info("starting connect loop, switching to syslog");
-      diag_set('y', xioparms.syslogfac);  xioparms.logopt = 'y';
-   } else {
-      Info("starting connect loop");
-   }
-
-   do {	/* loop over retries, and forks */
-
-      /* Loop over themarr (which had been "ai_sorted") */
-      result = STAT_RETRYLATER;
-      i = 0;
-      themp = themarr[i++];
-      while (themp != NULL) {
-	 Notice1("opening connection to %s",
-		 sockaddr_info(themp->ai_addr, themp->ai_addrlen,
-			       infobuff, sizeof(infobuff)));
+   do {	/* loop over retries and/or forks */
+      int _errno;
 
 #if WITH_RETRY
-	 if (sfd->forever || sfd->retry) {
-	    level = E_INFO;
-	 } else if (themarr[i] != NULL) {
-	    level = E_WARN;
-         } else
+      if (sfd->forever || sfd->retry) {
+	 level = E_NOTICE;
+      } else
 #endif /* WITH_RETRY */
-	    level = E_ERROR;
+	 level = E_WARN;
 
-       result =
-	 _xioopen_connect(sfd,
-			  needbind?us:NULL, uslen,
-			  themp->ai_addr, themp->ai_addrlen,
-			  opts, pf?pf:themp->ai_family, socktype, ipproto,
-			  lowport, level);
-       if (result == STAT_OK)
-	  break;
-       themp = themarr[i++];
-       if (themp == NULL) {
-	  result = STAT_RETRYLATER;
-       }
-      }
+      opts = copyopts(opts0, GROUP_ALL);
+
+      result =
+	 _xioopen_ipapp_prepare(&opts, opts0, hostname, portname,
+				pf, socktype, ipproto,
+				sfd->para.socket.ip.ai_flags,
+				&themarr, &bindarr, &bindport, &needbind, &lowport);
       switch (result) {
       case STAT_OK: break;
 #if WITH_RETRY
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
-	 if (sfd->forever || sfd->retry) {
-	    --sfd->retry;
-	    if (result == STAT_RETRYLATER) {
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER)
 	       Nanosleep(&sfd->intervall, NULL);
-	    }
-	    dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
+	    if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	    xiofreeaddrinfo(themarr);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
-      default:
+	 /* FALLTHROUGH */
+      case STAT_NORETRY:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
 	 xiofreeaddrinfo(themarr);
-	 free(opts0);free(opts);
+	 freeopts(opts);
+	 freeopts(opts0);
+	 return result;
+      }
+
+      result =
+	 _xioopen_ipapp_connect(sfd, hostname, opts, themarr,
+				needbind, bindarr, bindport, lowport, level);
+      _errno = errno;
+      if (bindarr != NULL)
+	 xiofreeaddrinfo(bindarr);
+      xiofreeaddrinfo(themarr);
+      switch (result) {
+      case STAT_OK: break;
+#if WITH_RETRY
+      case STAT_RETRYLATER:
+      case STAT_RETRYNOW:
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER) {
+	       Nanosleep(&sfd->intervall, NULL);
+	    }
+	    freeopts(opts);
+	    continue;
+	 }
+#endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
+      default:
+	 Error4("%s:%s:%s: %s", argv[0], argv[1], argv[2],
+		_errno?strerror(_errno):"(See above)");
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
 
@@ -155,16 +141,18 @@ int xioopen_ipapp_connect(
 				   so Notice is too weak */
 	 }
 	 while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
-	    if (sfd->forever || --sfd->retry) {
-	       Nanosleep(&sfd->intervall, NULL); continue;
+	    if (sfd->forever || sfd->retry--) {
+	       Nanosleep(&sfd->intervall, NULL);
+	       continue;
 	    }
-	    xiofreeaddrinfo(themarr);
-	    free(opts0);
+	    freeopts(opts);
+	    freeopts(opts0);
 	    return STAT_RETRYLATER;
 	 }
 
 	 if (pid == 0) {	/* child process */
-	    sfd->forever = false;  sfd->retry = 0;
+	    sfd->forever = false;
+	    sfd->retry = 0;
 	    break;
 	 }
 
@@ -176,107 +164,269 @@ int xioopen_ipapp_connect(
 	    Info1("all %d allowed children are active, waiting", maxchildren);
 	    Nanosleep(&sfd->intervall, NULL);
 	 }
-	 dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
+	 freeopts(opts);
 	 continue;	/* with next socket() bind() connect() */
       } else
 #endif /* WITH_RETRY */
       {
 	 break;
       }
-   } while (true);
+   } while (true); 	/* end of loop over retries and/or forks */
    /* only "active" process breaks (master without fork, or child) */
-   xiofreeaddrinfo(themarr);
 
-   if ((result = _xio_openlate(sfd, opts)) < 0) {
-	   free(opts0);free(opts);
-      return result;
-   }
-   free(opts0); free(opts);
-   return 0;
+   Notice2("successfully connected to %s:%s", hostname, portname);
+
+   result = _xio_openlate(sfd, opts);
+   freeopts(opts);
+   freeopts(opts0);
+   return result;
 }
 
 
-/* returns STAT_OK on success or some other value on failure
+/* This function performs static initializations for addresses like TCP-CONNECT
+   before start of the outer loop:
+   it retrieves some options
+   returns STAT_OK on success or some other value on failure;
+   applies and consumes the following options:
+   PH_INIT, OPT_FORK, OPT_MAX_CHILDREN, OPT_PROTOCOL_FAMILY, OPT_SO_TYPE,
+   OPT_SO_PROTOTYPE
+*/
+int _xioopen_ipapp_init(
+	struct single *sfd,
+	int xioflags,
+	struct opt *opts,
+	bool *dofork,
+	int *maxchildren,
+	int *pf,
+	int *socktype,
+	int *ipproto)
+{
+   if (sfd->howtoend == END_UNSPEC)
+      sfd->howtoend = END_SHUTDOWN;
+
+   if (applyopts_single(sfd, opts, PH_INIT) < 0)
+      return -1;
+   if (applyopts(sfd, -1, opts, PH_INIT) < 0)
+      return -1;
+
+   retropt_bool(opts, OPT_FORK, dofork);
+   if (dofork) {
+      if (!(xioflags & XIO_MAYFORK)) {
+	 Error1("%s: option fork not allowed here", sfd->addr->defname);
+	 return STAT_NORETRY;
+      }
+      sfd->flags |= XIO_DOESFORK;
+   }
+
+   retropt_int(opts, OPT_MAX_CHILDREN, maxchildren);
+   if (! dofork && maxchildren) {
+      Error1("%s: option max-children not allowed without option fork", sfd->addr->defname);
+      return STAT_NORETRY;
+   }
+
+   retropt_socket_pf(opts, pf);
+   retropt_int(opts, OPT_SO_TYPE, socktype);
+   retropt_int(opts, OPT_SO_PROTOTYPE, ipproto);
+
+   if (dofork) {
+      xiosetchilddied();	/* set SIGCHLD handler */
+   }
+
+   if (xioparms.logopt == 'm') {
+      Info("starting connect loop, switching to syslog");
+      diag_set('y', xioparms.syslogfac);
+      xioparms.logopt = 'y';
+   } else {
+      Info("starting connect loop");
+   }
+
+   return STAT_OK;
+}
+
+
+/* This function performs preparations for addresses like TCP-CONNECT
+   at the beginning of the outer (retry/fork) loop:
+   it evaluates some options and performs name resolution of both server
+   (target, "them") address and bind ("us") address.
+   It is intended to be invoked before the connect loop starts;
+   returns STAT_OK on success or some other value on failure;
    applies and consumes the following options:
    PH_EARLY
-   OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT
- */
-int
-   _xioopen_ipapp_prepare(
-	   struct opt *opts,
-	   struct opt **opts0,
-	   const char *hostname,
-	   const char *portname,
-	   int *pf,
-	   int protocol,
-	   const int ai_flags[2],
-	   struct addrinfo ***themarr,
-	   union sockaddr_union *us,
-	   socklen_t *uslen,
-	   bool *needbind,
-	   bool *lowport,
-	   int socktype) {
+   OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT
+   returns STAT_OK, STAT_RETRYLATER, or STAT_NORETRY (+errno)
+*/
+int _xioopen_ipapp_prepare(
+	struct opt **opts,
+	struct opt *opts0,
+	const char *hostname,
+	const char *portname,
+	int pf,
+	int socktype,
+	int protocol,
+	const int ai_flags[2],
+	struct addrinfo ***themarr, 	/* always from getaddrinfo(); xiofreeaddrinfo()! */
+	struct addrinfo ***bindarr, 	/* on bind from getaddrinfo(); xiofreeaddrinfo()! */
+	uint16_t *bindport, 		/* for bind without address */
+	bool *needbind,
+	bool *lowport)
+{
    uint16_t port;
    int rc;
 
-   retropt_socket_pf(opts, pf);
+   *opts = copyopts(opts0, GROUP_ALL);
 
    if (hostname != NULL || portname != NULL) {
-      rc = xiogetaddrinfo(hostname, portname, *pf, socktype, protocol,
+      rc = xiogetaddrinfo(hostname, portname, pf, socktype, protocol,
 			  themarr, ai_flags);
       if (rc == EAI_AGAIN) {
 	 Warn4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s",
 	       hostname?hostname:"NULL", portname?portname:"NULL",
-	       *pf, gai_strerror(rc));
+	       pf, gai_strerror(rc));
+	 errno = EAGAIN;
 	 return STAT_RETRYLATER;
       } else if (rc != 0) {
 	 Error4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s",
 		hostname?hostname:"NULL", portname?portname:"NULL",
-		*pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc));
+		pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc));
+	 errno = 0; 	/* unspecified */
 	 return STAT_NORETRY;	/*! STAT_RETRYLATER? */
       }
    }
 
-   applyopts(NULL, -1, opts, PH_EARLY);
+   applyopts(NULL, -1, *opts, PH_EARLY);
 
    /* 3 means: IP address AND port accepted */
-   if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family,
-		    socktype, protocol, (struct sockaddr *)us, uslen, 3,
-		    ai_flags)
+   if (retropt_bind_ip(*opts, pf, socktype, protocol, bindarr, 3, ai_flags)
        != STAT_NOACTION) {
       *needbind = true;
-   } else {
-      switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) {
-#if WITH_IP4
-      case PF_INET:  socket_in_init(&us->ip4);  *uslen = sizeof(us->ip4); break;
-#endif /* WITH_IP4 */
-#if WITH_IP6
-      case PF_INET6: socket_in6_init(&us->ip6); *uslen = sizeof(us->ip6); break;
-#endif /* WITH_IP6 */
-      default: Error("unsupported protocol family");
-      }
    }
-
-   if (retropt_2bytes(opts, OPT_SOURCEPORT, &port) >= 0) {
-      switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) {
+   if (retropt_2bytes(*opts, OPT_SOURCEPORT, &port) >= 0) {
+      if (*bindarr) {
+	 struct addrinfo **bindp;
+	 bindp = *bindarr;
+	 switch ((*bindp)->ai_family) {
 #if WITH_IP4
-      case PF_INET:  us->ip4.sin_port = htons(port); break;
+	 case PF_INET:  ((struct sockaddr_in *)(*bindp)->ai_addr)->sin_port = htons(port); break;
 #endif /* WITH_IP4 */
 #if WITH_IP6
-      case PF_INET6: us->ip6.sin6_port = htons(port); break;
+	 case PF_INET6: ((struct sockaddr_in6 *)(*bindp)->ai_addr)->sin6_port = htons(port); break;
 #endif /* WITH_IP6 */
-      default: Error("unsupported protocol family");
+	 default:
+	    Error("unsupported protocol family");
+	    errno = EPROTONOSUPPORT;
+	    return STAT_NORETRY;
+	 }
+      } else {
+	 *bindport = port;
       }
       *needbind = true;
    }
 
-   retropt_bool(opts, OPT_LOWPORT, lowport);
-
-   *opts0 = copyopts(opts, GROUP_ALL);
+   retropt_bool(*opts, OPT_LOWPORT, lowport);
 
    return STAT_OK;
 }
-#endif /* WITH_IP4 */
+
+#endif /* _WITH_IP4 || _WITH_IP6 */
+
+
+/* Tries to connect to the addresses in themarr, for each one it tries to bind
+   to the addresses in bindarr.
+   Ends on success or when all attempts failed.
+   Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure. */
+int _xioopen_ipapp_connect(struct single *sfd,
+			   const char *hostname,
+			   struct opt *opts,
+			   struct addrinfo **themarr,
+			   bool needbind,
+			   struct addrinfo **bindarr,
+			   uint16_t bindport,
+			   bool lowport,
+			   int level)
+{
+   struct addrinfo **themp;
+   struct addrinfo **bindp;
+   union sockaddr_union bindaddr = {0};
+   union sockaddr_union *bindaddrp = NULL;
+   socklen_t bindlen = 0;
+   char infobuff[256];
+   int _errno;
+   int result = STAT_OK;
+
+   --level;
+
+   /* Loop over server addresses (themarr) */
+   themp = themarr;
+   while (*themp != NULL) {
+      Notice1("opening connection to %s",
+	      sockaddr_info((*themp)->ai_addr, (*themp)->ai_addrlen,
+			    infobuff, sizeof(infobuff)));
+
+      if (*(themp+1) == NULL) {
+	 ++level; 	/* last attempt */
+      }
+
+      /* Loop over array (list) of bind addresses */
+      if (needbind && bindarr != NULL) {
+	 /* Bind by hostname, use resolvers results list */
+	 bindp = bindarr;
+	 while (*bindp != NULL) {
+	    if ((*bindp)->ai_family == (*themp)->ai_family)
+	       break;
+	    ++bindp;
+	 }
+	 if (*bindp == NULL) {
+	    Warn3("%s: No bind address with matching address family (%d) of %s available",
+		  sfd->addr->defname, (*themp)->ai_family, hostname);
+	    ++themp;
+	    if ((*themp) == NULL) {
+	       result = STAT_RETRYLATER;
+	    }
+	    _errno = ENOPROTOOPT;
+	    continue;
+	 }
+	 bindaddrp = (union sockaddr_union *)(*bindp)->ai_addr;
+	 bindlen  = (*bindp)->ai_addrlen;
+      } else if (needbind && bindport) {
+	 /* Bind by sourceport option */
+	 switch ((*themp)->ai_family) {
+#if WITH_IP4
+	 case PF_INET:
+	    bindaddr.ip4.sin_family = (*themp)->ai_family;
+	    bindaddr.ip4.sin_port = htons(bindport);
+	    bindaddrp = &bindaddr;
+	    bindlen = sizeof(bindaddr.ip4);
+	    break;
+#endif
+#if WITH_IP6
+	 case PF_INET6:
+	    bindaddr.ip6.sin6_family = (*themp)->ai_family;
+	    bindaddr.ip6.sin6_port = htons(bindport);
+	    bindaddrp = &bindaddr;
+	    bindlen = sizeof(bindaddr.ip6);
+	    break;
+#endif
+	 }
+      }
+
+      result =
+	 _xioopen_connect(sfd,
+			  bindaddrp, bindlen,
+			  (*themp)->ai_addr, (*themp)->ai_addrlen,
+			  opts, /*pf?pf:*/(*themp)->ai_family, (*themp)->ai_socktype, (*themp)->ai_protocol,
+			  lowport, level);
+      if (result == STAT_OK)
+	 break;
+      _errno = errno;
+      ++themp;
+      if (*themp == NULL)
+	 result = STAT_RETRYLATER;
+   } 	/* end of loop over target addresses */
+
+   if (result != STAT_OK)
+      errno = _errno;
+   return result;
+}
 
 
 #if WITH_TCP && WITH_LISTEN
@@ -303,7 +453,7 @@ int _xioopen_ipapp_listen_prepare(
 
    retropt_string(opts, OPT_BIND, &bindname);
 
-   /* Set AI_PASSIVE, except when it is explicitely disabled */
+   /* Set AI_PASSIVE, except when it is explicitly disabled */
    ai_flags2[0] = ai_flags[0];
    ai_flags2[1] = ai_flags[1];
    if (!(ai_flags2[1] & AI_PASSIVE))
@@ -382,6 +532,6 @@ int xioopen_ipapp_listen(
       return result;
    return 0;
 }
-#endif /* WITH_IP4 && WITH_TCP && WITH_LISTEN */
+#endif /* WITH_TCP && WITH_LISTEN */
 
-#endif /* WITH_TCP || WITH_UDP */
+#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */
diff --git a/xio-ipapp.h b/xio-ipapp.h
index af9e7b4..e190e36 100644
--- a/xio-ipapp.h
+++ b/xio-ipapp.h
@@ -15,11 +15,9 @@ extern const struct optdesc opt_sourceport;
 extern const struct optdesc opt_lowport;
 
 extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
-extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo ***themlist, union sockaddr_union *us,  socklen_t *uslen, bool *needbind, bool *lowport, int socktype);
-extern int _xioopen_ip4app_connect(const char *hostname, const char *portname,
-				   struct single *xfd,
-				   int socktype, int ipproto, void *protname,
-				   struct opt *opts);
+extern int _xioopen_ipapp_init(struct single *sfd, int xioflags, struct opt *opts, bool *dofork, int *maxchildren, int *pf, int *socktype, int *protocol);
+extern int _xioopen_ipapp_prepare(struct opt **opts, struct opt *opts0, const char *hostname, const char *portname, int pf, int socktype, int protocol, const int ai_flags[2], struct addrinfo ***themarr, struct addrinfo ***bindarr, uint16_t *bindport, bool *needbind, bool *lowport);
+extern int _xioopen_ipapp_connect(struct single *sfd, const char *hostname, struct opt *opts, struct addrinfo **themarr, bool needbind, struct addrinfo **bindarr, uint16_t bindport, bool lowport, int level);
 extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
 extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype);
 
diff --git a/xio-openssl.c b/xio-openssl.c
index 1278bf4..9a2ca62 100644
--- a/xio-openssl.c
+++ b/xio-openssl.c
@@ -5,7 +5,7 @@
 /* this file contains the implementation of the openssl addresses */
 
 #include "xiosysincludes.h"
-#if WITH_OPENSSL	/* make this address configure dependend */
+#if WITH_OPENSSL	/* make this address configure dependent */
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
@@ -26,7 +26,6 @@
    (not only tcp, but also pipes, stdin, files...)
    for tcp we want to provide support for socks and proxy.
    read and write functions must use the openssl crypt versions.
-   but currently only plain tcp4 is implemented.
 */
 
 /* Linux: "man 3 ssl" */
@@ -239,13 +238,13 @@ static int xioopen_openssl_connect(
    int socktype = SOCK_STREAM;
    int ipproto = IPPROTO_TCP;
    bool dofork = false;
-   union sockaddr_union us_sa,  *us = &us_sa;
-   socklen_t uslen = sizeof(us_sa);
-   struct addrinfo **themarr, *themp;
+   int maxchildren = 0;
+   struct addrinfo **bindarr = NULL;
+   struct addrinfo **themarr = NULL;
+   uint16_t bindport = 0;
    bool needbind = false;
    bool lowport = false;
    int level = E_ERROR;
-   int i;
    SSL_CTX* ctx;
    bool opt_ver = true;	/* verify peer certificate */
    char *opt_cert = NULL;	/* file name of client certificate */
@@ -255,7 +254,7 @@ static int xioopen_openssl_connect(
    int result;
 
    if (!(xioflags & XIO_MAYCONVERT)) {
-      Error("address with data processing not allowed here");
+      Error1("%s: address with data processing not allowed here", argv[0]);
       return STAT_NORETRY;
    }
    sfd->flags |= XIO_DOESCONVERT;
@@ -267,20 +266,12 @@ static int xioopen_openssl_connect(
    hostname = argv[1];
    portname = argv[2];
    if (hostname[0] == '\0') {
-      /* we catch this explicitely because empty commonname (peername) disables
+      /* We catch this explicitly because empty commonname (peername) disables
 	 commonName check of peer certificate */
       Error1("%s: empty host name", argv[0]);
       return STAT_NORETRY;
    }
 
-   if (sfd->howtoend == END_UNSPEC)
-      sfd->howtoend = END_SHUTDOWN;
-   if (applyopts_single(sfd, opts, PH_INIT) < 0)
-      return -1;
-   applyopts(sfd, -1, opts, PH_INIT);
-
-   retropt_bool(opts, OPT_FORK, &dofork);
-
    retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
    retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
@@ -316,73 +307,83 @@ static int xioopen_openssl_connect(
       socktype = SOCK_DGRAM;
       ipproto = IPPROTO_UDP;
    }
-   retropt_int(opts, OPT_SO_TYPE,      &socktype);
-   retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
 
-   result =
-      _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
-			     sfd->para.socket.ip.ai_flags,
-			     &themarr, us, &uslen,
-			     &needbind, &lowport, socktype);
-   if (result != STAT_OK)  return STAT_NORETRY;
+   /* Apply and retrieve some options */
+   result = _xioopen_ipapp_init(sfd, xioflags, opts,
+				&dofork, &maxchildren,
+				&pf, &socktype, &ipproto);
+   if (result != STAT_OK)
+      return result;
 
-   if (xioparms.logopt == 'm') {
-      Info("starting connect loop, switching to syslog");
-      diag_set('y', xioparms.syslogfac);  xioparms.logopt = 'y';
-   } else {
-      Info("starting connect loop");
-   }
+   opts0 = opts; 	/* save remaining options for each loop */
+   opts = NULL;
 
-   do {	/* loop over failed connect and SSL handshake attempts */
+   Notice2("opening OpenSSL connection to %s:%s", hostname, portname);
 
-      /* Loop over themarr (which had been "ai_sorted") */
-      i = 0;
-      themp = themarr[i++];
-      while (themp != NULL) {
+   do {	/* loop over retries (failed connect and SSL handshake attempts) and/or forks */
+      int _errno;
 
 #if WITH_RETRY
-	 if (sfd->forever || sfd->retry || themarr[i] != NULL) {
-	    level = E_INFO;
-	 } else
+      if (sfd->forever || sfd->retry) {
+	 level = E_NOTICE;
+      } else
 #endif /* WITH_RETRY */
-	    level = E_ERROR;
+	 level = E_WARN;
 
-	 /* This cannot fork because we retrieved fork option above */
-       result =
-	 _xioopen_connect(sfd,
-			  needbind?us:NULL, uslen,
-			  themp->ai_addr, themp->ai_addrlen,
-			  opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level);
-       if (result == STAT_OK)
-	  break;
-       themp = themarr[i++];
-       if (themp == NULL) {
-	  result = STAT_RETRYLATER;
-      }
-      }
+      opts = copyopts(opts0, GROUP_ALL);
+
+      result =
+	 _xioopen_ipapp_prepare(&opts, opts0, hostname, portname,
+				pf, socktype, ipproto,
+				sfd->para.socket.ip.ai_flags,
+				&themarr, &bindarr, &bindport, &needbind, &lowport);
       switch (result) {
       case STAT_OK: break;
 #if WITH_RETRY
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
-	 if (sfd->forever || sfd->retry) {
-	    dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER)
+	       Nanosleep(&sfd->intervall, NULL);
+	    if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	    xiofreeaddrinfo(themarr);
+	    freeopts(opts);
+	    continue;
+	 }
+#endif /* WITH_RETRY */
+      case STAT_NORETRY:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	 xiofreeaddrinfo(themarr);
+	 freeopts(opts);
+	 freeopts(opts0);
+	 return result;
+      }
+
+      Notice2("opening connection to server %s:%s", hostname, portname);
+      result =
+	 _xioopen_ipapp_connect(sfd, hostname, opts, themarr,
+				needbind, bindarr, bindport, lowport, level);
+      _errno = errno;
+      if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+      xiofreeaddrinfo(themarr);
+      switch (result) {
+      case STAT_OK: break;
+#if WITH_RETRY
+      case STAT_RETRYLATER:
+      case STAT_RETRYNOW:
+	 if (sfd->forever || sfd->retry--) {
 	    if (result == STAT_RETRYLATER) {
 	       Nanosleep(&sfd->intervall, NULL);
 	    }
-	    --sfd->retry;
+	    freeopts(opts);
 	    continue;
 	 }
-	 xiofreeaddrinfo(themarr);
-	 return STAT_NORETRY;
 #endif /* WITH_RETRY */
       default:
-	 xiofreeaddrinfo(themarr);
-	 return result;
-      }
-      /*! isn't this too early? */
-      if ((result = _xio_openlate(sfd, opts)) < 0) {
-	 xiofreeaddrinfo(themarr);
+	 Error4("%s:%s:%s: %s", argv[0], hostname, portname,
+		_errno?strerror(_errno):"(See above)");
+	 freeopts(opts0);
+	 freeopts(opts);
 	 return result;
       }
 
@@ -393,19 +394,19 @@ static int xioopen_openssl_connect(
 #if WITH_RETRY
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
-	 if (sfd->forever || sfd->retry) {
-	    Close(sfd->fd);
-	    dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
+	 if (sfd->forever || sfd->retry--) {
 	    if (result == STAT_RETRYLATER) {
 	       Nanosleep(&sfd->intervall, NULL);
 	    }
-	    --sfd->retry;
+	    freeopts(opts);
+	    Close(sfd->fd);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
       default:
-	 xiofreeaddrinfo(themarr);
-	 return STAT_NORETRY;
+	 freeopts(opts);
+	 freeopts(opts0);
+	 return result;
       }
 
       if (dofork) {
@@ -420,15 +421,19 @@ static int xioopen_openssl_connect(
 	    level = E_WARN;
 	 }
 	 while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
-	    if (sfd->forever || --sfd->retry) {
-	       Nanosleep(&sfd->intervall, NULL); continue;
+	    if (sfd->forever || sfd->retry--) {
+	       Nanosleep(&sfd->intervall, NULL);
+	       freeopts(opts);
+	       continue;
 	    }
-	    xiofreeaddrinfo(themarr);
+	    freeopts(opts);
+	    freeopts(opts0);
 	    return STAT_RETRYLATER;
 	 }
 
 	 if (pid == 0) {	/* child process */
-	    sfd->forever = false;  sfd->retry = 0;
+	    sfd->forever = false;
+	    sfd->retry = 0;
 	    break;
 	 }
 
@@ -438,21 +443,29 @@ static int xioopen_openssl_connect(
 	 sfd->para.openssl.ssl = NULL;
 	 /* with and without retry */
 	 Nanosleep(&sfd->intervall, NULL);
-	 dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
+	 while (maxchildren > 0 && num_child >= maxchildren) {
+	    Info1("all %d allowed children are active, waiting", maxchildren);
+	    Nanosleep(&sfd->intervall, NULL);
+	 }
+	 freeopts(opts);
 	 continue;	/* with next socket() bind() connect() */
       }
 #endif /* WITH_RETRY */
       break;
+
    } while (true);	/* drop out on success */
-   xiofreeaddrinfo(themarr);
 
    openssl_conn_loginfo(sfd->para.openssl.ssl);
 
    free((void *)opt_commonname);
    free((void *)opt_snihost);
 
-   /* fill in the fd structure */
-   return STAT_OK;
+   Notice2("successfully connected to SSL server %s:%s", hostname, portname);
+
+   result = _xio_openlate(sfd, opts);
+   freeopts(opts);
+   freeopts(opts0);
+   return result;
 }
 
 
@@ -702,7 +715,7 @@ int _xioopen_openssl_listen(struct single *sfd,
 			    const char *opt_commonname,
 			     SSL_CTX *ctx,
 			     int level) {
-   char error_string[120];
+   char error_string[256];
    unsigned long err;
    int errint, ret;
 
@@ -764,7 +777,7 @@ int _xioopen_openssl_listen(struct single *sfd,
 	    while (err = ERR_get_error()) {
 	       ERR_error_string_n(err, error_string, sizeof(error_string));
 	       Msg4(level, "SSL_accept(): %s / %s / %s / %s", error_string,
-		    ERR_lib_error_string(err), ERR_func_error_string(err),
+		    ERR_lib_error_string(err), error_string,
 		    ERR_reason_error_string(err));
 	    }
 	    /* Msg1(level, "SSL_accept(): %s", ERR_error_string(e, buf));*/
@@ -793,7 +806,7 @@ int _xioopen_openssl_listen(struct single *sfd,
 
 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
 /* In OpenSSL 0.9.7 compression methods could be added using
- * SSL_COMP_add_compression_method(3), but the implemntation is not compatible
+ * SSL_COMP_add_compression_method(3), but the implementation is not compatible
  * with the standard (RFC3749).
  */
 static int openssl_setup_compression(SSL_CTX *ctx, char *method)
@@ -1976,12 +1989,20 @@ static int xioSSL_set_fd(struct single *sfd, int level) {
    should not retry for any reason. */
 static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
 			  bool opt_ver, int level) {
-   char error_string[120];
-   int errint, status, ret;
+   sigset_t masksigs, oldsigs;
+   char error_string[256];
+   int errint, status, _errno, ret;
    unsigned long err;
 
+   sigemptyset(&masksigs);
+   sigaddset(&masksigs, SIGCHLD);
+   sigaddset(&masksigs, SIGUSR1);
+   Sigprocmask(SIG_BLOCK, &masksigs, &oldsigs);
    /* connect via SSL by performing handshake */
-   if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) {
+   ret = sycSSL_connect(sfd->para.openssl.ssl);
+   _errno = errno;
+   Sigprocmask(SIG_SETMASK, &oldsigs, NULL);
+   if (ret <= 0) {
       /*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/
       errint = SSL_get_error(sfd->para.openssl.ssl, ret);
       switch (errint) {
@@ -2005,14 +2026,14 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
 	    if (ret == 0) {
 	       Msg(level, "SSL_connect(): socket closed by peer");
 	    } else if (ret == -1) {
-	       Msg1(level, "SSL_connect(): %s", strerror(errno));
+	       Msg1(level, "SSL_connect(): %s", strerror(_errno));
 	    }
 	 } else {
 	    Msg(level, "I/O error");	/*!*/
 	    while (err = ERR_get_error()) {
 	       ERR_error_string_n(err, error_string, sizeof(error_string));
 	       Msg4(level, "SSL_connect(): %s / %s / %s / %s", error_string,
-		    ERR_lib_error_string(err), ERR_func_error_string(err),
+		    ERR_lib_error_string(err), error_string,
 		    ERR_reason_error_string(err));
 	    }
 	 }
@@ -2037,7 +2058,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
 /* on result < 0: errno is set (at least to EIO) */
 ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) {
    unsigned long err;
-   char error_string[120];
+   char error_string[256];
    int _errno = EIO;	/* if we have no better idea about nature of error */
    int errint, ret;
 
@@ -2072,7 +2093,7 @@ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) {
 	    while (err = ERR_get_error()) {
 	       ERR_error_string_n(err, error_string, sizeof(error_string));
 	       Error4("SSL_read(): %s / %s / %s / %s", error_string,
-		      ERR_lib_error_string(err), ERR_func_error_string(err),
+		      ERR_lib_error_string(err), error_string,
 		      ERR_reason_error_string(err));
 	    }
 	 }
@@ -2098,7 +2119,7 @@ ssize_t xiopending_openssl(struct single *pipe) {
 /* on result < 0: errno is set (at least to EIO) */
 ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) {
    unsigned long err;
-   char error_string[120];
+   char error_string[256];
    int _errno = EIO;	/* if we have no better idea about nature of error */
    int errint, ret;
 
@@ -2131,7 +2152,7 @@ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) {
 	    while (err = ERR_get_error()) {
 	       ERR_error_string_n(err, error_string, sizeof(error_string));
 	       Error4("SSL_write(): %s / %s / %s / %s", error_string,
-		      ERR_lib_error_string(err), ERR_func_error_string(err),
+		      ERR_lib_error_string(err), error_string,
 		      ERR_reason_error_string(err));
 	    }
 	 }
diff --git a/xio-openssl.h b/xio-openssl.h
index 204aca6..3570856 100644
--- a/xio-openssl.h
+++ b/xio-openssl.h
@@ -5,7 +5,7 @@
 #ifndef __xio_openssl_included
 #define __xio_openssl_included 1
 
-#if WITH_OPENSSL	/* make this address configure dependend */
+#if WITH_OPENSSL	/* make this address configure dependent */
 
 #define SSLIO_BASE 0x53530000	/* "SSxx" */
 #define SSLIO_MASK 0xffff0000
diff --git a/xio-posixmq.c b/xio-posixmq.c
index 186e932..6fb969f 100644
--- a/xio-posixmq.c
+++ b/xio-posixmq.c
@@ -15,18 +15,21 @@
 
 #if WITH_POSIXMQ
 
-static int _posixmq_unlink(
-	const char *name,
-	int level); 		/* message level on error */
+static int _posixmq_flush(struct single *sfd);
+static int _posixmq_unlink(const char *name, int level);
 
 static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
 
-const struct addrdesc xioaddr_posixmq_bidir   = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR,   xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY,                  XIO_RDWR,   0, 0 HELP(":<mqname>") };
-const struct addrdesc xioaddr_posixmq_read    = { "POSIXMQ-READ",          1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY,                  XIO_RDONLY, 0, 0 HELP(":<mqname>") };
-const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE",       1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") };
-const struct addrdesc xioaddr_posixmq_send    = { "POSIXMQ-SEND",          1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_WRONLY, 0, 0 HELP(":<mqname>") };
+const struct addrdesc xioaddr_posixmq_bidir   = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR,   xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY,                  XIO_RDWR,   0, 0 HELP(":<mqname>") };
+const struct addrdesc xioaddr_posixmq_read    = { "POSIXMQ-READ",          1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY,                  XIO_RDONLY, 0, 0 HELP(":<mqname>") };
+const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE",       1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") };
+const struct addrdesc xioaddr_posixmq_send    = { "POSIXMQ-SEND",          1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_WRONLY, 0, 0 HELP(":<mqname>") };
+const struct addrdesc xioaddr_posixmq_write   = { "POSIXMQ-WRITE",         1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_WRONLY, 0, 0 HELP(":<mqname>") };
 
-const struct optdesc opt_posixmq_priority   = { "posixmq-priority",   "mq-pri",   OPT_POSIXMQ_PRIORITY,   GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 };
+const struct optdesc opt_posixmq_priority   = { "posixmq-priority",   "mq-prio",  OPT_POSIXMQ_PRIORITY,   GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 };
+const struct optdesc opt_posixmq_flush      = { "posixmq-flush",      "mq-flush", OPT_POSIXMQ_FLUSH,      GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC,   0,                               0,                             0 };
+const struct optdesc opt_posixmq_maxmsg     = { "posixmq-maxmsg",     "mq-maxmsg",  OPT_POSIXMQ_MAXMSG,   GROUP_POSIXMQ, PH_OPEN,  TYPE_LONG, OFUNC_SPEC,   0,                               0,                             0 };
+const struct optdesc opt_posixmq_msgsize    = { "posixmq-msgsize",    "mq-msgsize", OPT_POSIXMQ_MSGSIZE,  GROUP_POSIXMQ, PH_OPEN,  TYPE_LONG, OFUNC_SPEC,   0,                               0,                             0 };
 
 /* _read(): open immediately, stay in transfer loop
    _recv(): wait until data (how we know there is??), oneshot, opt.fork
@@ -45,8 +48,18 @@ static int xioopen_posixmq(
 	int dirs = addrdesc->arg1;
 	int oneshot = addrdesc->arg2;
 	bool opt_unlink_early = false;
+	bool nonblock = 0;
+	bool flush = false;
+	long maxmsg;
+	long msgsize;
+	struct mq_attr attr = { 0 };
+	bool setopts = false;
 	int oflag;
+	bool opt_o_creat = true;
 	bool opt_o_excl = false;
+#ifdef O_CLOEXEC
+	bool opt_o_cloexec = true;
+#endif
 	mode_t opt_mode = 0666;
 	mqd_t mqd;
 	int _errno;
@@ -55,10 +68,6 @@ static int xioopen_posixmq(
 	bool with_intv = false;
 	int result = 0;
 
-	if (!xioparms.experimental) {
-		Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
-		return STAT_NORETRY;
-	}
 	if (argc != 2) {
 		xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
 		return STAT_NORETRY;
@@ -77,7 +86,10 @@ static int xioopen_posixmq(
 			with_intv = true;
 		}
 	}
-
+	if (dirs == XIO_RDWR) {
+		/* Bidirectional ADDRESS in unidirectional mode? Adapt dirs */
+		dirs = (xioflags & XIO_ACCMODE);
+	}
 	retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
 	if (! dofork && maxchildren) {
 		Error("option max-children not allowed without option fork");
@@ -94,8 +106,54 @@ static int xioopen_posixmq(
 		Error1("strdup(\"%s\"): out of memory", name);
 	}
 
-	retropt_bool(opts, OPT_O_EXCL, &opt_o_excl);
-	retropt_mode(opts, OPT_PERM, &opt_mode);
+	retropt_bool(opts, OPT_O_CREAT,   &opt_o_creat);
+	retropt_bool(opts, OPT_O_EXCL,    &opt_o_excl);
+#ifdef O_CLOEXEC
+	retropt_bool(opts, OPT_O_CLOEXEC, &opt_o_cloexec);
+#endif
+	retropt_mode(opts, OPT_PERM,      &opt_mode);
+	retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush);
+	retropt_long(opts, OPT_POSIXMQ_MAXMSG,  &maxmsg) ||
+		(setopts = true);
+	retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &msgsize) ||
+		(setopts = true);
+
+	/* When just one of mq-maxmsg and mq-msgsize options has been provided,
+	   we must nevertheless set the other option value in struct mq_attr.
+	   For this we have to find the default, read it from /proc fs */
+	if (setopts) {
+		int pfd;
+		const static char *PROC_MAXMSG  = "/proc/sys/fs/mqueue/msg_default";
+		const static char *PROC_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default";
+		char buff[21]; 	/* fit a 64bit num in decimal */
+		ssize_t bytes;
+
+		if (maxmsg == 0) {
+			if ((pfd = Open(PROC_MAXMSG, O_RDONLY, 0)) < 0) {
+				Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MAXMSG, strerror(errno));
+			} else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) {
+				Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s",
+				      pfd, PROC_MAXMSG, sizeof(buff)-1, strerror (errno));
+				Close(pfd);
+			} else {
+				sscanf(buff, "%ld", &maxmsg);
+				Close(pfd);
+			}
+		}
+
+		if (msgsize == 0) {
+			if ((pfd = Open(PROC_MSGSIZE, O_RDONLY, 0)) < 0) {
+				Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MSGSIZE, strerror(errno));
+			} else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) {
+				Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s",
+				      pfd, PROC_MSGSIZE, sizeof(buff)-1, strerror (errno));
+				Close(pfd);
+			} else {
+				sscanf(buff, "%ld", &msgsize);
+				Close(pfd);
+			}
+		}
+	}
 
 	retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
 	if (opt_unlink_early) {
@@ -106,26 +164,65 @@ static int xioopen_posixmq(
 	   sfd->howtoend = END_CLOSE;
 	sfd->dtype = XIODATA_POSIXMQ | oneshot;
 
-	oflag = O_CREAT;
-	if (opt_o_excl)  oflag |= O_EXCL;
+	oflag = 0;
+	if (opt_o_creat)   oflag |= O_CREAT;
+	if (opt_o_excl)    oflag |= O_EXCL;
+#ifdef O_CLOEXEC
+	if (opt_o_cloexec) oflag |= O_CLOEXEC; 	/* does not seem to work (Ubuntu-20) */
+#endif
 	switch (dirs) {
 	case XIO_RDWR:   oflag |= O_RDWR;   break;
 	case XIO_RDONLY: oflag |= O_RDONLY; break;
 	case XIO_WRONLY: oflag |= O_WRONLY; break;
 	}
+	if (retropt_bool(opts, OPT_O_NONBLOCK, &nonblock) >= 0 && nonblock)
+		oflag |= O_NONBLOCK;
+
+	if (flush) {
+		if (_posixmq_flush(sfd) != STAT_OK)
+			return STAT_NORETRY;
+	}
 
 	/* Now open the message queue */
-	Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode);
-	mqd = mq_open(name, oflag, opt_mode, NULL);
+	if (setopts) {
+		attr.mq_maxmsg  = maxmsg;
+		attr.mq_msgsize = msgsize;
+		Debug8("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} )", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
+	} else {
+		Debug4("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL)", argv[0], name, oflag, opt_mode);
+	}
+	mqd = mq_open(name, oflag, opt_mode, setopts ? &attr : NULL);
 	_errno = errno;
 	Debug1("mq_open() -> %d", mqd);
 	if (mqd < 0) {
-		Error3("%s: mq_open(\"%s\"): %s", argv[0], name, strerror(errno));
+		if (setopts)
+			Error9("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} ): %s", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs, strerror(errno));
+		else
+			Error5("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL): %s", argv[0], name, oflag, opt_mode, strerror(errno));
 		errno = _errno;
 		return STAT_RETRYLATER;
 	}
+	/* applyopts_cloexec(mqd, opts); */	/* does not seem to work too (Ubuntu-20) */
 	sfd->fd = mqd;
 
+	Debug1("mq_getattr(%d, ...)", mqd);
+	if (mq_getattr(mqd, &attr) < 0) {
+		Warn4("mq_getattr(%d[\"%s\"], %p): %s",
+		      mqd, sfd->para.posixmq.name, &attr, strerror(errno));
+		mq_close(mqd);
+		return STAT_NORETRY;
+	}
+	Info5("POSIXMQ queue \"%s\" attrs: { flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld }",
+	      name, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
+	if (setopts) {
+		if (attr.mq_maxmsg != maxmsg)
+			Warn2("mq_open(): requested maxmsg=%ld, but result is %ld",
+			      maxmsg, attr.mq_maxmsg);
+		if (attr.mq_msgsize != msgsize)
+			Warn2("mq_open(): requested msgsize=%ld, but result is %ld",
+			      msgsize, attr.mq_msgsize);
+	}
+
 	if (!dofork && !oneshot) {
 		return STAT_OK;
 	}
@@ -155,6 +252,8 @@ static int xioopen_posixmq(
 		do {
 			struct pollfd pollfd;
 
+			if (oflag & O_NONBLOCK)
+				break;
 			pollfd.fd = sfd->fd;
 			pollfd.events = (dirs==XIO_RDONLY?POLLIN:POLLOUT);
 			if (xiopoll(&pollfd, 1, NULL) > 0) {
@@ -231,6 +330,81 @@ static int xioopen_posixmq(
 }
 
 
+/* With option flush try to open the queue and "consume" its current contents */
+static int _posixmq_flush(
+	struct single *sfd)
+{
+	mqd_t mqd;
+	struct mq_attr attr;
+	void *buff;
+	size_t bufsiz;
+	int _errno;
+	int p = 0; 		/* number of messages flushed */
+	size_t b = 0; 	/* number of bytes flushed */
+
+	Info1("flushing POSIXMQ queue \"%s\"", sfd->para.posixmq.name);
+	Debug1("mq_open(\"%s\", O_RDONLY|O_NONBLOCK, 0, NULL)",
+	       sfd->para.posixmq.name);
+	mqd = mq_open(sfd->para.posixmq.name, O_RDONLY|O_NONBLOCK, 0, NULL);
+	_errno = errno;
+	Debug1("mq_open() -> %d", mqd);
+	if (mqd < 0 && _errno == ENOENT) {
+		Info("this queue does not exist, no need to flush it");
+		return STAT_OK;
+	}
+	if (mqd < 0) {
+		Warn2("mq_open(\"%s\", ...): %s", sfd->para.posixmq.name,
+		      strerror(_errno));
+		return STAT_NORETRY;
+	}
+
+	Debug1("mq_getattr(%d, ...)", mqd);
+	if (mq_getattr(mqd, &attr) < 0) {
+		Warn4("mq_getattr(%d[\"%s\"], %p): %s",
+		      mqd, sfd->para.posixmq.name, &attr, strerror(errno));
+		mq_close(mqd);
+		return STAT_NORETRY;
+	}
+	if (attr.mq_curmsgs == 0) {
+		Info1("POSIXMQ \"%s\" is empty", sfd->para.posixmq.name);
+		mq_close(mqd);
+		return STAT_OK;
+	}
+	bufsiz = attr.mq_msgsize;
+	if ((buff = Malloc(bufsiz)) == NULL) {
+		mq_close(mqd);
+		return STAT_RETRYLATER;
+	}
+
+	/* Now read all messages to null */
+	while (true) {
+		ssize_t bytes;
+
+		Debug3("mq_receive(mqd=%d, %p, "F_Zu", {} )", mqd, buff, bufsiz);
+		bytes = mq_receive(mqd, buff, bufsiz, &sfd->para.posixmq.prio);
+		_errno = errno;
+		Debug1("mq_receive() -> "F_Zd, bytes);
+		errno = _errno;
+		if (bytes == 0 || (bytes < 0 && _errno == EAGAIN)) {
+			break;
+		}
+		if (bytes < 0) {
+			Warn2("flushing POSIXMQ \"%s\" failed: %s",
+			      sfd->para.posixmq.name, strerror(_errno));
+			free(buff);
+			mq_close(mqd);
+			return STAT_NORETRY;
+		}
+		++p;
+		b += bytes;
+	}
+	Info3("flushed "F_Zu" bytes in %u packets from queue \"%s\"", b, p,
+	      sfd->para.posixmq.name);
+	free(buff);
+	mq_close(mqd);
+	return STAT_OK;
+}
+
 ssize_t xiowrite_posixmq(
 	struct single *sfd,
 	const void *buff,
@@ -283,6 +457,9 @@ ssize_t xioclose_posixmq(
 	struct single *sfd)
 {
 	int res;
+
+	if (sfd->fd < 0)
+		return 0;
 	Debug1("xioclose_posixmq(): mq_close(%d)", sfd->fd);
 	res = mq_close(sfd->fd);
 	if (res < 0) {
diff --git a/xio-posixmq.h b/xio-posixmq.h
index 8359696..adf827b 100644
--- a/xio-posixmq.h
+++ b/xio-posixmq.h
@@ -9,8 +9,12 @@ extern const struct addrdesc xioaddr_posixmq_bidir;
 extern const struct addrdesc xioaddr_posixmq_read;
 extern const struct addrdesc xioaddr_posixmq_receive;
 extern const struct addrdesc xioaddr_posixmq_send;
+extern const struct addrdesc xioaddr_posixmq_write;
 
+extern const struct optdesc opt_posixmq_maxmsg;
+extern const struct optdesc opt_posixmq_msgsize;
 extern const struct optdesc opt_posixmq_priority;
+extern const struct optdesc opt_posixmq_flush;
 
 extern ssize_t xioread_posixmq(struct single *file, void *buff, size_t bufsiz);
 extern ssize_t xiopending_posixmq(struct single *pipe);
diff --git a/xio-progcall.c b/xio-progcall.c
index f980ef9..d0b8c1c 100644
--- a/xio-progcall.c
+++ b/xio-progcall.c
@@ -12,6 +12,7 @@
 #include "xio-progcall.h"
 
 #include "xio-socket.h"
+#include "xio-socketpair.h"
 
 
 /* these options are used by address pty too */
@@ -23,7 +24,7 @@ const struct optdesc opt_ptmx    = { "ptmx",      NULL, OPT_PTMX,        GROUP_P
 #endif
 const struct optdesc opt_sitout_eio = { "sitout-eio", NULL, OPT_SITOUT_EIO, GROUP_PTY, PH_OFFSET, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.exec.sitout_eio), XIO_SIZEOF(para.exec.sitout_eio) };
 
-#if WITH_EXEC || WITH_SYSTEM
+#if WITH_EXEC || WITH_SYSTEM || WITH_SHELL
 
 #define MAXPTYNAMELEN 64
 
@@ -623,7 +624,7 @@ int _xioopen_foxec(int xioflags,	/* XIO_RDONLY etc. */
    *optsp = popts;
    return pid;	/* indicate parent (main) process */
 }
-#endif /* WITH_EXEC || WITH_SYSTEM */
+#endif /* WITH_EXEC || WITH_SYSTEM || WITH_SHELL */
 
 
 int setopt_path(struct opt *opts, char **path) {
diff --git a/xio-proxy.c b/xio-proxy.c
index 86d86e3..ba82d5d 100644
--- a/xio-proxy.c
+++ b/xio-proxy.c
@@ -83,18 +83,18 @@ static int xioopen_proxy_connect(
 	xiofile_t *xxfd,
 	const struct addrdesc *addrdesc)
 {
-      /* we expect the form: host:host:port */
+   /* we expect the form: host:host:port */
    struct single *sfd = &xxfd->stream;
    struct opt *opts0 = NULL;
    struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars;
    /* variables to be filled with address option values */
    bool dofork = false;
+   int maxchildren = 0;
    /* */
    int pf = PF_UNSPEC;
-   union sockaddr_union us_sa,   *us = &us_sa;
-   socklen_t uslen = sizeof(us_sa);
-   struct addrinfo **themarr, *themp;
-   int i;
+   struct addrinfo **bindarr = NULL;
+   struct addrinfo **themarr = NULL;
+   uint16_t bindport = 0;
    const char *proxyname; char *proxyport = NULL;
    const char *targetname, *targetport;
    int ipproto = IPPROTO_TCP;
@@ -112,90 +112,123 @@ static int xioopen_proxy_connect(
    targetname = argv[2];
    targetport = argv[3];
 
-   if (sfd->howtoend == END_UNSPEC)
-      sfd->howtoend = END_SHUTDOWN;
-   if (applyopts_single(sfd, opts, PH_INIT) < 0)
-      return -1;
-   applyopts(sfd, 1, opts, PH_INIT);
-
-   retropt_int(opts, OPT_SO_TYPE, &socktype);
-
-   retropt_bool(opts, OPT_FORK, &dofork);
-
    if (retropt_string(opts, OPT_PROXYPORT, &proxyport) < 0) {
       if ((proxyport = strdup(PROXYPORT)) == NULL) {
 	 errno = ENOMEM;  return -1;
       }
    }
 
-   result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport,
-				   sfd->para.socket.ip.ai_flags);
-   if (result != STAT_OK)
-      return result;
-
-   Notice4("opening connection to %s:%u via proxy %s:%s",
-      proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport);
-
-   i = 0;
-   do {      /* loop over retries (failed connect and proxy-request attempts) */
-
-    level = E_INFO;
-
-    result =
-      _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport,
-			     &pf, ipproto,
-			     sfd->para.socket.ip.ai_flags,
-			     &themarr, us, &uslen,
-			     &needbind, &lowport, socktype);
+   result =
+      _xioopen_ipapp_init(sfd, xioflags, opts,
+			  &dofork, &maxchildren,
+			  &pf, &socktype, &ipproto);
    if (result != STAT_OK)
        return result;
 
-      /* Loop over themlist */
-      i = 0;
-      themp = themarr[i++];
-      while (themp != NULL) {
-	 Notice4("opening connection to %s:%u via proxy %s:%s",
-		 proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport);
-#if WITH_RETRY
-	 if (sfd->forever || sfd->retry || themarr[i] != NULL) {
-	    level = E_INFO;
-	 } else
-#endif /* WITH_RETRY */
-	    level = E_ERROR;
+   result = _xioopen_proxy_init(proxyvars, opts, targetname, targetport);
+   if (result != STAT_OK)
+      return result;
 
-   result =
-      _xioopen_connect(sfd,
-		       needbind?us:NULL, uslen,
-		       themp->ai_addr, themp->ai_addrlen,
-		       opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
-       if (result == STAT_OK)
-	  break;
-       themp = themarr[i++];
-       if (themp == NULL) {
-	  result = STAT_RETRYLATER;
-      }
+   opts0 = opts; 	/* save remaining options for each loop */
+   opts = NULL;
+
+   Notice4("opening connection to %s:%s via proxy %s:%s",
+      targetname, targetport, proxyname, proxyport);
+
+   do {      /* loop over retries (failed connect and proxy-request attempts)
+	        and/or forks */
+      int _errno;
+
+#if WITH_RETRY
+      if (sfd->forever || sfd->retry) {
+	 level = E_NOTICE;
+      } else
+#endif /* WITH_RETRY */
+	 level = E_WARN;
+
+      opts = copyopts(opts0, GROUP_ALL);
+
+      result =
+	 _xioopen_ipapp_prepare(&opts, opts0, proxyname, proxyport,
+				pf, socktype, ipproto,
+				sfd->para.socket.ip.ai_flags,
+				&themarr, &bindarr, &bindport, &needbind, &lowport);
       switch (result) {
       case STAT_OK: break;
 #if WITH_RETRY
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
-	 if (sfd->forever || sfd->retry) {
-	    --sfd->retry;
+	 if (sfd->forever || sfd->retry--) {
 	    if (result == STAT_RETRYLATER)
 	       Nanosleep(&sfd->intervall, NULL);
+	    if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	    xiofreeaddrinfo(themarr);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
-      default:
+	 /* FALLTHROUGH */
+      case STAT_NORETRY:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
 	 xiofreeaddrinfo(themarr);
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
-      }
-      xiofreeaddrinfo(themarr);
-      applyopts(sfd, -1, opts, PH_ALL);
 
-      if ((result = _xio_openlate(sfd, opts)) < 0)
+      result =
+	 _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport,
+				sfd->para.socket.ip.ai_flags);
+      switch (result) {
+      case STAT_OK: break;
+#if WITH_RETRY
+      case STAT_RETRYLATER:
+      case STAT_RETRYNOW:
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER)
+	       Nanosleep(&sfd->intervall, NULL);
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	 xiofreeaddrinfo(themarr);
+	    freeopts(opts);
+	    continue;
+	 }
+#endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
+      default:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	 xiofreeaddrinfo(themarr);
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
+      }
+
+      Notice2("opening connection to proxy %s:%s", proxyname, proxyport);
+      result =
+	 _xioopen_ipapp_connect(sfd, proxyname, opts, themarr,
+				needbind, bindarr, bindport, lowport, level);
+      _errno = errno;
+      if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+      xiofreeaddrinfo(themarr);
+      switch (result) {
+      case STAT_OK: break;
+#if WITH_RETRY
+      case STAT_RETRYLATER:
+      case STAT_RETRYNOW:
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER)
+	       Nanosleep(&sfd->intervall, NULL);
+	    freeopts(opts);
+	    continue;
+	 }
+#endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
+      default:
+	 Error4("%s:%s:...,proxyport=%s: %s", argv[0], proxyname, proxyport,
+		_errno?strerror(_errno):"(See above)");
+	 freeopts(opts0);
+	 freeopts(opts);
+	 return result;
+      }
 
       result = _xioopen_proxy_connect(sfd, proxyvars, level);
       switch (result) {
@@ -204,11 +237,16 @@ static int xioopen_proxy_connect(
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
 	 if (sfd->forever || sfd->retry--) {
-	    if (result == STAT_RETRYLATER)  Nanosleep(&sfd->intervall, NULL);
+	    if (result == STAT_RETRYLATER)
+	       Nanosleep(&sfd->intervall, NULL);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
       default:
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
 
@@ -225,21 +263,32 @@ static int xioopen_proxy_connect(
 	 }
 	 while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
 	    if (sfd->forever || --sfd->retry) {
-	       Nanosleep(&sfd->intervall, NULL); continue;
+	       if (sfd->retry > 0)
+		  --sfd->retry;
+	       Nanosleep(&sfd->intervall, NULL);
+	       freeopts(opts);
+	       continue;
 	    }
+	    freeopts(opts);
+	    freeopts(opts0);
 	    return STAT_RETRYLATER;
 	 }
 
 	 if (pid == 0) {	/* child process */
-	    sfd->forever = false;  sfd->retry = 0;
+	    sfd->forever = false;
+	    sfd->retry = 0;
 	    break;
 	 }
 
 	 /* parent process */
 	 Close(sfd->fd);
+	 /* With and without retry */
 	 Nanosleep(&sfd->intervall, NULL);
-	 dropopts(opts, PH_ALL);
-	 opts = copyopts(opts0, GROUP_ALL);
+	 while (maxchildren > 0 && num_child >= maxchildren) {
+	    Info1("all %d allowed children are active, waiting", maxchildren);
+	    Nanosleep(&sfd->intervall, NULL);
+	 }
+	 freeopts(opts);
 	 continue;
       } else
 #endif /* WITH_RETRY */
@@ -248,25 +297,25 @@ static int xioopen_proxy_connect(
       }
 
    } while (true);	/* end of complete open loop - drop out on success */
+   /* Only "active" process breaks (master without fork, or child) */
 
    Notice4("successfully connected to %s:%u via proxy %s:%s",
 	   proxyvars->targetaddr, proxyvars->targetport,
 	   proxyname, proxyport);
 
-   return 0;
+   result = _xio_openlate(sfd, opts);
+   freeopts(opts);
+   freeopts(opts0);
+   return result;
 }
 
 
-int _xioopen_proxy_prepare(
+int _xioopen_proxy_init(
 	struct proxyvars *proxyvars,
 	struct opt *opts,
 	const char *targetname,
-	const char *targetport,
-	const int ai_flags[2]) {
-   union sockaddr_union host;
-   socklen_t socklen = sizeof(host);
-   int rc;
-
+	const char *targetport)
+{
    retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr);
    retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve);
    retropt_string(opts, OPT_HTTP_VERSION,             &proxyvars->version);
@@ -316,6 +365,28 @@ int _xioopen_proxy_prepare(
       Close(authfd);
    }
 
+   if (!proxyvars->doresolve) {
+      proxyvars->targetaddr = strdup(targetname);
+      if (proxyvars->targetaddr == NULL) {
+	 Error1("strdup(\"%s\"): out of memory", targetname);
+	 return STAT_RETRYLATER;
+      }
+   }
+
+   return STAT_OK;
+}
+
+int _xioopen_proxy_prepare(
+	struct proxyvars *proxyvars,
+	struct opt *opts,
+	const char *targetname,
+	const char *targetport,
+	const int ai_flags[2])
+{
+   union sockaddr_union host;
+   socklen_t socklen = sizeof(host);
+   int rc;
+
    if (proxyvars->doresolve) {
       /* currently we only resolve to IPv4 addresses. This is in accordance to
 	 RFC 2396; however once it becomes clear how IPv6 addresses should be
@@ -325,6 +396,10 @@ int _xioopen_proxy_prepare(
 		      &host, &socklen, ai_flags);
       if (rc != STAT_OK) {
 	 proxyvars->targetaddr = strdup(targetname);
+	 if (proxyvars->targetaddr == NULL) {
+	    Error1("strdup(\"%s\"): out of memory", targetname);
+	    return STAT_RETRYLATER;
+	 }
       } else {
 #define LEN 16	/* www.xxx.yyy.zzz\0 */
 	 if ((proxyvars->targetaddr = Malloc(LEN)) == NULL) {
@@ -337,8 +412,6 @@ int _xioopen_proxy_prepare(
 		  ((unsigned char *)&host.ip4.sin_addr.s_addr)[3]);
 #undef LEN
       }
-   } else {
-      proxyvars->targetaddr = strdup(targetname);
    }
 
    proxyvars->targetport = htons(parseport(targetport, IPPROTO_TCP));
@@ -376,7 +449,7 @@ int _xioopen_proxy_connect(struct single *sfd,
    * xiosanitize(request, strlen(request), textbuff) = '\0';
    Info1("sending \"%s\"", textbuff);
    /* write errors are assumed to always be hard errors, no retry */
-   if (writefull(sfd->fd, request, strlen(request)) < 0) {
+   if (writefull(sfd->fd, request, strlen(request), NULL) < 0) {
       Msg4(level, "write(%d, %p, "F_Zu"): %s",
 	   sfd->fd, request, strlen(request), strerror(errno));
       if (Close(sfd->fd) < 0) {
@@ -406,7 +479,7 @@ int _xioopen_proxy_connect(struct single *sfd,
       *next = '\0';
       Info1("sending \"%s\\r\\n\"", header);
       *next++ = '\r';  *next++ = '\n'; *next++ = '\0';
-      if (writefull(sfd->fd, header, strlen(header)) < 0) {
+      if (writefull(sfd->fd, header, strlen(header), NULL) < 0) {
 	 Msg4(level, "write(%d, %p, "F_Zu"): %s",
 	      sfd->fd, header, strlen(header), strerror(errno));
 	 if (Close(sfd->fd) < 0) {
@@ -419,7 +492,7 @@ int _xioopen_proxy_connect(struct single *sfd,
    }
 
    Info("sending \"\\r\\n\"");
-   if (writefull(sfd->fd, "\r\n", 2) < 0) {
+   if (writefull(sfd->fd, "\r\n", 2, NULL) < 0) {
       Msg2(level, "write(%d, \"\\r\\n\", 2): %s",
 	   sfd->fd, strerror(errno));
       if (Close(sfd->fd) < 0) {
diff --git a/xio-proxy.h b/xio-proxy.h
index fee18b7..f7fb2b8 100644
--- a/xio-proxy.h
+++ b/xio-proxy.h
@@ -25,9 +25,8 @@ extern const struct optdesc opt_proxy_authorization_file;
 
 extern const struct addrdesc xioaddr_proxy_connect;
 
+extern int _xioopen_proxy_init(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport);
 extern int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport, const int ai_flags[2]);
-int _xioopen_proxy_connect(struct single *xfd,
-			   struct proxyvars *proxyvars,
-			   int level);
+extern int _xioopen_proxy_connect(struct single *xfd, struct proxyvars *proxyvars, int level);
 
 #endif /* !defined(__xio_proxy_h_included) */
diff --git a/xio-readline.c b/xio-readline.c
index 376cd26..69423c0 100644
--- a/xio-readline.c
+++ b/xio-readline.c
@@ -184,7 +184,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) {
 	 /* we must carriage return, because readline will first print the
 	    prompt */
 	 ssize_t writt;
-	 writt = writefull(pipe->fd, "\r", 1);
+	 writt = writefull(pipe->fd, "\r", 1, NULL);
 	 if (writt < 0) {
 	    Warn2("write(%d, \"\\r\", 1): %s",
 		   pipe->fd, strerror(errno));
@@ -204,6 +204,9 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) {
       if (line == NULL) {
 	 return 0;	/* EOF */
       }
+      if (strlen(line) == 0) {
+	 Write(STDOUT_FILENO, "\n", 1);
+      }
 #if _WITH_TERMIOS
       xiotermios_clrflag(pipe->fd, 3, ECHO);
       xiotermios_flush(pipe->fd);
diff --git a/xio-shell.c b/xio-shell.c
index 8a41e21..a06358b 100644
--- a/xio-shell.c
+++ b/xio-shell.c
@@ -81,7 +81,7 @@ static int xioopen_shell(
 		Setenv("SHELL", shellpath, 1);
 
 		Info1("executing shell command \"%s\"", string);
-		Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL",
+		Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL)",
 		       shellpath, shellname, string);
 		result = execl(shellpath, shellname, "-c", string, (char *)NULL);
 		if (result != 0) {
diff --git a/xio-socket.c b/xio-socket.c
index 5a7782f..e2c0ab2 100644
--- a/xio-socket.c
+++ b/xio-socket.c
@@ -7,8 +7,6 @@
 
 #include "xiosysincludes.h"
 
-#if _WITH_SOCKET
-
 #include "xioopen.h"
 #include "xio-ascii.h"
 #include "xio-socket.h"
@@ -30,6 +28,8 @@
 #include "xio-tcpwrap.h"
 
 
+#if _WITH_SOCKET
+
 static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
 static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
 static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
@@ -191,6 +191,8 @@ const struct optdesc opt_setsockopt_int    = { "setsockopt-int",    "sockopt-int
 const struct optdesc opt_setsockopt_bin    = { "setsockopt-bin",    "sockopt-bin",    OPT_SETSOCKOPT_BIN,        GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN,     OFUNC_SOCKOPT_GENERIC, 0, 0 };
 const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING,     GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_STRING,  OFUNC_SOCKOPT_GENERIC, 0, 0 };
 const struct optdesc opt_setsockopt_listen = { "setsockopt-listen", "sockopt-listen", OPT_SETSOCKOPT_LISTEN,     GROUP_SOCKET,PH_PREBIND,   TYPE_INT_INT_BIN,     OFUNC_SOCKOPT_GENERIC, 0, 0 };
+const struct optdesc opt_setsockopt_socket    = { "setsockopt-socket",    "sockopt-sock", OPT_SETSOCKOPT_SOCKET,    GROUP_SOCKET,PH_PASTSOCKET, TYPE_INT_INT_BIN,    OFUNC_SOCKOPT_GENERIC, 0, 0 };
+const struct optdesc opt_setsockopt_connected = { "setsockopt-connected", "sockopt-conn", OPT_SETSOCKOPT_CONNECTED, GROUP_SOCKET,PH_CONNECTED,  TYPE_INT_INT_BIN,    OFUNC_SOCKOPT_GENERIC, 0, 0 };
 
 const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCKET, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.null_eof) };
 
@@ -262,8 +264,13 @@ static int xioopen_socket_connect(
    sfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM;
 
    socket_init(0, &us);
-   if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3,
-		    sfd->para.socket.ip.ai_flags)
+   if (retropt_bind(opts, pf, socktype, proto, (struct sockaddr *)&us, &uslen, -1,
+#if _WITH_IP4 || _WITH_IP6
+		    sfd->para.socket.ip.ai_flags
+#else
+		    NULL
+#endif /* _WITH_IP4 || _WITH_IP6 */
+		    )
        != STAT_NOACTION) {
       needbind = true;
       us.soa.sa_family = pf;
@@ -540,7 +547,12 @@ int xioopen_socket_recvfrom(
 
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, 0, &sfd->para.socket.range,
-			sfd->para.socket.ip.ai_flags)
+#if _WITH_IP4 || _WITH_IP6
+			sfd->para.socket.ip.ai_flags
+#else
+			NULL
+#endif /* _WITH_IP4 */
+			)
 	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
@@ -626,7 +638,12 @@ int xioopen_socket_recv(
 
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, 0, &sfd->para.socket.range,
-			sfd->para.socket.ip.ai_flags)
+#if _WITH_IP4 || _WITH_IP6
+			sfd->para.socket.ip.ai_flags
+#else
+			NULL
+#endif /* _WITH_IP4 */
+			)
 	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
@@ -712,7 +729,12 @@ static int xioopen_socket_datagram(
    /* which reply sockets will accept - determine by range option */
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, 0, &sfd->para.socket.range,
-			sfd->para.socket.ip.ai_flags)
+#if _WITH_IP4 || _WITH_IP6
+			sfd->para.socket.ip.ai_flags
+#else
+			NULL
+#endif /* _WITH_IP4 */
+			)
 	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
@@ -779,13 +801,13 @@ int xiogetpacketinfo(struct single *sfd, int fd)
    PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT,
    PH_CONNECTED, PH_LATE,
    OFUNC_OFFSET,
-   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
+   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC
    Does not fork, does not retry.
    Alternate (alt) bind semantics are:
       with IP sockets: lowport (selects randomly a free port from 640 to 1023)
       with UNIX and abstract sockets: uses tmpname() to find a free file system
       entry.
-   returns 0 on success.
+   Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure.
 */
 int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 		     struct sockaddr *them, size_t themlen,
@@ -815,7 +837,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
    applyopts_cloexec(sfd->fd, opts);
 
    if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) {
-      return -1;
+      return STAT_RETRYLATER;
    }
 
    applyopts(sfd, -1, opts, PH_CONNECT);
@@ -855,6 +877,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 	       Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s",
 		    sfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno));
 	       Close(sfd->fd);
+	       errno = _errno;
 	       return STAT_RETRYLATER;
 	    }
 	    if (result == 0) {
@@ -862,6 +885,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 		    sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
 		    strerror(ETIMEDOUT));
 	       Close(sfd->fd);
+	       errno = _errno;
 	       return STAT_RETRYLATER;
 	    }
 	    if (writefd.revents & POLLERR) {
@@ -877,15 +901,19 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 		     sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
 		     themlen, strerror(errno));
 #endif
+	       _errno = errno;
 	       Close(sfd->fd);
+	       errno = _errno;
 	       return STAT_RETRYLATER;
 	    }
 	    /* otherwise OK or network error */
 	    result = Getsockopt(sfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen);
 	    if (result != 0) {
+	       _errno = errno;
 	       Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s",
 		    sfd->fd, strerror(err));
 	       Close(sfd->fd);
+	       errno = _errno;
 	       return STAT_RETRYLATER;
 	    }
 	    Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0",
@@ -895,6 +923,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 		     sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
 		     themlen, strerror(err));
 	       Close(sfd->fd);
+	       errno = err;
 	       return STAT_RETRYLATER;
 	    }
 	    Fcntl_l(sfd->fd, F_SETFL, fcntl_flags);
@@ -925,6 +954,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
 	      sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
 	      themlen, strerror(errno));
 	 Close(sfd->fd);
+	 errno = _errno;
 	 return STAT_RETRYLATER;
       }
    } else {	/* result >= 0 */
@@ -952,7 +982,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
    PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT,
    PH_CONNECTED, PH_LATE,
    OFUNC_OFFSET,
-   OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
+   OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC
    returns 0 on success.
 */
 int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
@@ -1052,7 +1082,7 @@ int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
    applies and consumes the following option:
    PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE
    OFUNC_OFFSET
-   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
+   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC
  */
 int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
 			union sockaddr_union *us, socklen_t uslen,
@@ -1202,6 +1232,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags,
    }
 #endif
 
+#if WITH_IP4 || WITH_IP6
    /* for generic sockets, this has already been retrieved */
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, pf, &sfd->para.socket.range,
@@ -1213,6 +1244,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags,
       free(rangename);
       sfd->para.socket.dorange = true;
    }
+#endif /* WITH_IP4 || WITH_IP6 */
 
 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
    xio_retropt_tcpwrap(sfd, opts);
@@ -1424,6 +1456,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
    }
 #endif
 
+#if WITH_IP4 || WITH_IP6
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, pf, &sfd->para.socket.range,
 			sfd->para.socket.ip.ai_flags)
@@ -1434,6 +1467,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
       free(rangename);
       sfd->para.socket.dorange = true;
    }
+#endif /* WITH_IP4 || WITH_IP6 */
 
 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
    xio_retropt_tcpwrap(sfd, opts);
@@ -1449,7 +1483,10 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
    return STAT_OK;
 }
 
+#endif /* _WITH_SOCKET */
 
+
+#if _WITH_SOCKET || _WITH_SOCKETPAIR
 int retropt_socket_pf(struct opt *opts, int *pf) {
    char *pfname;
 
@@ -1478,8 +1515,11 @@ int retropt_socket_pf(struct opt *opts, int *pf) {
    }
    return -1;
 }
+#endif /* _WITH_SOCKET || _WITH_SOCKETPAIR */
 
 
+#if _WITH_SOCKET
+
 /* This function calls recvmsg(..., MSG_PEEK, ...) to obtain information about
    the arriving packet, thus it does not "consume" the packet.
    In msgh the msg_name pointer must refer to an (empty) sockaddr storage.
@@ -1651,7 +1691,7 @@ int xiocheckpeer(xiosingle_t *sfd,
    char infobuff[256];
    int result;
 
-#if WITH_IP4
+#if WITH_IP4 || WITH_IP6
    if (sfd->para.socket.dorange) {
       if (pa == NULL)  { return -1; }
       if (xiocheckrange(pa, &sfd->para.socket.range) < 0) {
@@ -1736,7 +1776,7 @@ int xiocheckpeer(xiosingle_t *sfd,
 
 
 #if HAVE_STRUCT_CMSGHDR
-/* converts the ancillary message in *cmsg into a form useable for further
+/* Converts the ancillary message in *cmsg into a form usable for further
    processing. knows the specifics of common message types.
    returns the number of resulting syntax elements in *num
    returns a sequence of \0 terminated type strings in *typbuff
@@ -1957,7 +1997,7 @@ int xioparserange(
       return -1;
    }
    /* we have parsed the address and mask; now we make sure that the stored
-      address has 0 where mask is 0, to simplify comparisions */
+      address has 0 where mask is 0, to simplify comparisons */
    switch (pf) {
 #if WITH_IP4
    case PF_INET:
@@ -2055,15 +2095,12 @@ int xiosetsockaddrenv(const char *lr,
 #  undef XIOSOCKADDRENVLEN
 }
 
-#endif /* _WITH_SOCKET */
-
-/* these do sockets internally */
+/* These do sockets internally */
 
 /* retrieves options so-type and so-prototype from opts, calls socket, and
    ev. generates an appropriate error message.
-   returns 0 on success or -1 if an error occurred. */
-int
-xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
+   returns 0 on success or -1 (and errno) if an error occurred. */
+int xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
    int result;
 
    retropt_int(opts, OPT_SO_TYPE, &socktype);
@@ -2080,24 +2117,6 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
    return result;
 }
 
-/* retrieves options so-type and so-prototype from opts, calls socketpair, and
-   ev. generates an appropriate error message.
-   returns 0 on success or -1 if an error occurred. */
-int
-xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) {
-   int result;
-
-   retropt_int(opts, OPT_SO_TYPE, &socktype);
-   retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
-   result = Socketpair(pf, socktype, proto, sv);
-   if (result < 0) {
-      Error5("socketpair(%d, %d, %d, %p): %s",
-	     pf, socktype, proto, sv, strerror(errno));
-      return -1;
-   }
-   return result;
-}
-
 /* Binds a socket to a socket address. Handles IP (internet protocol), UNIX
    domain, Linux abstract UNIX domain.
    The bind address us may be NULL in which case no bind() happens, except with
@@ -2106,6 +2125,7 @@ xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) {
       with IP sockets: lowport (selects randomly a free port from 640 to 1023)
       with UNIX and abstract sockets: uses a method similar to tmpname() to
       find a free file system entry.
+   On success returns STAT_OK, otherwise errno is set.
 */
 int xiobind(
 	struct single *sfd,
@@ -2142,18 +2162,20 @@ int xiobind(
 	       usrname = strndup(us->un.sun_path, sizeof(us->un.sun_path));
 	    if (usrname	== NULL) {
 	       int _errno = errno;
-	       Error2("strndup(\"%s\", "F_Zu"): out of memory",
+	       Msg2(level, "strndup(\"%s\", "F_Zu"): out of memory",
 		      us->un.sun_path, sizeof(us->un.sun_path));
 	       errno = _errno;
-	       return -1;
+	       return STAT_RETRYLATER;
 	    }
 	 }
 
 	 do {	/* loop over tempnam bind() attempts */
 	    sockname = xio_tempnam(usrname, abstract);
 	    if (sockname == NULL) {
+	       int _errno = errno;
 	       Error2("tempnam(\"%s\"): %s", usrname, strerror(errno));
 	       free(usrname);
+	       errno = _errno;
 	       return -1;
 	    }
 	    strncpy(us->un.sun_path+(abstract?1:0), sockname, sizeof(us->un.sun_path));
@@ -2167,8 +2189,10 @@ int xiobind(
 					   infobuff, sizeof(infobuff)),
 		    uslen, strerror(errno));
 	       if (errno != EADDRINUSE) {
+		  int _errno = errno;
 		  free(usrname);
 		  Close(sfd->fd);
+		  errno = _errno;
 		  return STAT_RETRYLATER;
 	       }
 	    } else {
@@ -2181,10 +2205,12 @@ int xiobind(
 
       if (us != NULL) {
 	 if (Bind(sfd->fd, &us->soa, uslen) < 0) {
+	    int _errno = errno;
 	    Msg4(level, "bind(%d, {%s}, "F_Zd"): %s",
 		 sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
 		 uslen, strerror(errno));
 	    Close(sfd->fd);
+	    errno = _errno;
 	    return STAT_RETRYLATER;
 	 }
 	 applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
@@ -2206,8 +2232,12 @@ int xiobind(
       if (us) {
 	 sinp = us;
       } else {
-	 if (pf == AF_INET) {
+	 if (0) {
+	    ;
+#if WITH_IP4
+	 } else if (pf == AF_INET) {
 	    socket_in_init(&sin.ip4);
+#endif
 #if WITH_IP6
 	 } else {
 	    socket_in6_init(&sin.ip6);
@@ -2252,12 +2282,14 @@ int xiobind(
       do {	/* loop over lowport bind() attempts */
 	 *port = htons(i);
 	 if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) {
+	    int _errno = errno;
 	    Msg4(errno==EADDRINUSE?E_INFO:level,
 		 "bind(%d, {%s}, "F_Zd"): %s", sfd->fd,
 		 sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)),
 		 sizeof(*sinp), strerror(errno));
-	    if (errno != EADDRINUSE) {
+	    if (_errno != EADDRINUSE) {
 	       Close(sfd->fd);
+	       errno = _errno;
 	       return STAT_RETRYLATER;
 	    }
 	 } else {
@@ -2266,8 +2298,8 @@ int xiobind(
 	 --i;  if (i < XIO_IPPORT_LOWER)  i = IPPORT_RESERVED-1;
 	 if (i == N) {
 	    Msg(level, "no low port available");
-	    /*errno = EADDRINUSE; still assigned */
 	    Close(sfd->fd);
+	    errno = EADDRINUSE;
 	    return STAT_RETRYLATER;
 	 }
       } while (i != N);
@@ -2278,24 +2310,26 @@ int xiobind(
       if (us) {
 	 applyopts(sfd, sfd->fd, opts, PH_BIND);
 	 if (Bind(sfd->fd, &us->soa, uslen) < 0) {
+	    int _errno = errno;
 	    Msg4(level, "bind(%d, {%s}, "F_Zd"): %s",
 		 sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
 		 uslen, strerror(errno));
 	    Close(sfd->fd);
+	    errno = _errno;
 	    return STAT_RETRYLATER;
 	 }
       }
    }
 
    applyopts(sfd, -1, opts, PH_PASTBIND);
-   return 0;
+   return STAT_OK;
 }
 
 /* Handles the SO_REUSEADDR socket option for TCP LISTEN addresses depending on
    Socat option so-reuseaddr:
    Option not applied: set it to 1
    Option applied with a value: set it to the value
-   Option applied eith empty value "so-reuseaddr=": do not call setsockopt() for
+   Option applied with empty value "so-reuseaddr=": do not call setsockopt() for
    SO_REUSEADDR
    Return 0 on success, or -1 with errno when an error occurred.
  */
@@ -2303,15 +2337,25 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts)
 {
 	union integral val;
 	union integral notnull;
+	int result;
 	int _errno;
 
 	val.u_int = 0;
 	notnull.u_bool = false;
+#if WITH_TCP
 	if (ipproto == IPPROTO_TCP) {
 		val.u_int = 1;
 		notnull.u_bool = true;
 	}
-	retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, &notnull);
+#endif /* WITH_TCP */
+	result = retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, &notnull);
+#if WITH_TCP
+	if (ipproto == IPPROTO_TCP && result < 0) {
+		Info("Setting SO_REUSADDR on TCP listen socket implicitly");
+		val.u_int = 1;
+		notnull.u_bool = true;
+	}
+#endif /* WITH_TCP */
 	if (notnull.u_bool) {
 		if (Setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val.u_int, sizeof(int))
 		    != 0) {
@@ -2324,3 +2368,6 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts)
 	}
 	return 0;
 }
+
+#endif /* _WITH_SOCKET */
+
diff --git a/xio-socket.h b/xio-socket.h
index 2064ed3..2ecb28b 100644
--- a/xio-socket.h
+++ b/xio-socket.h
@@ -83,6 +83,8 @@ extern const struct optdesc opt_setsockopt_bin;
 extern const struct optdesc opt_setsockopt_string;
 extern const struct optdesc opt_setsockopt_listen;
 extern const struct optdesc opt_null_eof;
+extern const struct optdesc opt_setsockopt_socket;
+extern const struct optdesc opt_setsockopt_connected;
 
 
 extern
@@ -135,8 +137,6 @@ extern int xioparserange(const char *rangename, int pf, struct xiorange *range,
 
 extern int
 xiosocket(struct opt *opts, int pf, int socktype, int proto, int level);
-extern int
-xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]);
 extern int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts);
 
 #endif /* !defined(__xio_socket_h_included) */
diff --git a/xio-socketpair.c b/xio-socketpair.c
index 0da0c99..e062a44 100644
--- a/xio-socketpair.c
+++ b/xio-socketpair.c
@@ -95,3 +95,26 @@ static int xioopen_socketpair(
 }
 
 #endif /* WITH_SOCKETPAIR */
+
+
+#if _WITH_SOCKETPAIR
+
+/* retrieves options so-type and so-prototype from opts, calls socketpair, and
+   ev. generates an appropriate error message.
+   returns 0 on success or -1 if an error occurred. */
+int
+xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) {
+   int result;
+
+   retropt_int(opts, OPT_SO_TYPE, &socktype);
+   retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
+   result = Socketpair(pf, socktype, proto, sv);
+   if (result < 0) {
+      Error5("socketpair(%d, %d, %d, %p): %s",
+	     pf, socktype, proto, sv, strerror(errno));
+      return -1;
+   }
+   return result;
+}
+
+#endif /* _WITH_SOCKETPAIR */
diff --git a/xio-socketpair.h b/xio-socketpair.h
index 2f92f70..5822798 100644
--- a/xio-socketpair.h
+++ b/xio-socketpair.h
@@ -7,4 +7,6 @@
 
 const extern struct addrdesc xioaddr_socketpair;
 
+extern int xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]);
+
 #endif /* !defined(__xio_socketpair_h_included) */
diff --git a/xio-socks.c b/xio-socks.c
index d5234cb..ea0805c 100644
--- a/xio-socks.c
+++ b/xio-socks.c
@@ -6,14 +6,16 @@
 
 #include "xiosysincludes.h"
 
-#if WITH_SOCKS4 || WITH_SOCKS4A
-
 #include "xioopen.h"
 #include "xio-ascii.h"
 #include "xio-socket.h"
 #include "xio-ip.h"
 #include "xio-ipapp.h"
 
+#define SOCKSPORT "1080"
+
+#if WITH_SOCKS4 || WITH_SOCKS4A
+
 #include "xio-socks.h"
 
 
@@ -24,7 +26,6 @@ enum {
    SOCKS_CD_IDENTFAILED
 } ;
 
-#define SOCKSPORT "1080"
 #define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512)
 
 static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
@@ -53,13 +54,12 @@ static int xioopen_socks4_connect(
    int pf = PF_UNSPEC;
    int ipproto = IPPROTO_TCP;
    bool dofork = false;
-   union sockaddr_union us_sa,  *us = &us_sa;
-   socklen_t uslen = sizeof(us_sa);
-   struct addrinfo **themarr, *themp;
-   int i;
+   int maxchildren = 0;
+   struct addrinfo **bindarr = NULL;
+   struct addrinfo **themarr = NULL;
+   uint16_t bindport = 0;
    bool needbind = false;
    bool lowport = false;
-   char infobuff[256];
    unsigned char buff[BUFF_LEN];
    struct socks4 *sockhead = (struct socks4 *)buff;
    size_t buflen = sizeof(buff);
@@ -75,41 +75,43 @@ static int xioopen_socks4_connect(
    targetname = argv[2];
    targetport = argv[3];
 
-   if (sfd->howtoend == END_UNSPEC)
-      sfd->howtoend = END_SHUTDOWN;
-   if (applyopts_single(sfd, opts, PH_INIT) < 0)  return -1;
-   applyopts(sfd, 1, opts, PH_INIT);
-
-   retropt_int(opts, OPT_SO_TYPE, &socktype);
-
-   retropt_bool(opts, OPT_FORK, &dofork);
-
-   result = _xioopen_socks4_prepare(targetport, opts, &socksport, sockhead, &buflen);
+   /* Apply and retrieve some options */
+   result = _xioopen_ipapp_init(sfd, xioflags, opts,
+			        &dofork, &maxchildren,
+			        &pf, &socktype, &ipproto);
    if (result != STAT_OK)
       return result;
 
+   result = _xioopen_socks4_init(targetport, opts, &socksport, sockhead,
+				 &buflen);
+   if (result != STAT_OK)
+      return result;
+
+   opts0 = opts; 	/* save remaining options for each loop */
+   opts = NULL;
+
    Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"",
-	   targetname,
-	   ntohs(sockhead->port),
+	   targetname, ntohs(sockhead->port),
 	   sockdname, socksport, sockhead->userid);
 
-   i = 0;
-   do {	/* loop over retries (failed connect and socks-request attempts) */
+   do {	/* loop over retries (failed connect and socks-request attempts)
+	   and/or forks */
+      int _errno;
 
-      level = E_INFO;
+#if WITH_RETRY
+      if (sfd->forever || sfd->retry) {
+	 level = E_NOTICE;
+      } else
+#endif /* WITH_RETRY */
+	 level = E_WARN;
+
+      opts = copyopts(opts0, GROUP_ALL);
 
       result =
-	 _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
-				&pf, ipproto,
+	 _xioopen_ipapp_prepare(&opts, opts0, sockdname, socksport,
+				pf, socktype, ipproto,
 				sfd->para.socket.ip.ai_flags,
-				&themarr, us, &uslen,
-				&needbind, &lowport, socktype);
-
-      /* we try to resolve the target address _before_ connecting to the socks
-	 server: this avoids unnecessary socks connects and timeouts */
-      result =
-	 _xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead,
-				  (ssize_t *)&buflen, level);
+				&themarr, &bindarr, &bindport, &needbind, &lowport);
       switch (result) {
       case STAT_OK: break;
 #if WITH_RETRY
@@ -118,60 +120,78 @@ static int xioopen_socks4_connect(
 	 if (sfd->forever || sfd->retry--) {
 	    if (result == STAT_RETRYLATER)
 	       Nanosleep(&sfd->intervall, NULL);
+	    if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	    xiofreeaddrinfo(themarr);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
-      default:
+	 /* FALLTHROUGH */
+      case STAT_NORETRY:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	 xiofreeaddrinfo(themarr);
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
 
-      /* loop over themarr */
-      i = 0;
-      themp = themarr[i++];
-      while (themp != NULL) {
-	 Notice1("opening connection to %s",
-		 sockaddr_info(themp->ai_addr, themp->ai_addrlen,
-			       infobuff, sizeof(infobuff)));
-#if WITH_RETRY
-	 if (sfd->forever || sfd->retry || themarr[i] != NULL) {
-	    level = E_INFO;
-	 } else
-#endif /* WITH_RETRY */
-	    level = E_ERROR;
-
-      /* this cannot fork because we retrieved fork option above */
-	 result =
-	    _xioopen_connect(sfd,
-			     needbind?us:NULL, uslen,
-			     themp->ai_addr, themp->ai_addrlen,
-			     opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
-	 if (result == STAT_OK)
-	    break;
-	   themp = themarr[i++];
-	 if (themp == NULL)
-	    result = STAT_RETRYLATER;
-      }
+      /* we try to resolve the target address _before_ connecting to the socks
+	 server: this may avoid unnecessary connects and timeouts */
+      result =
+	 _xioopen_socks4_prepare(sfd, targetname, socks4a, sockhead,
+				 (ssize_t *)&buflen, level);
       switch (result) {
       case STAT_OK: break;
 #if WITH_RETRY
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
-	 if (sfd->forever || sfd->retry) {
-	    --sfd->retry;
+	 if (sfd->forever || sfd->retry--) {
 	    if (result == STAT_RETRYLATER)
 	       Nanosleep(&sfd->intervall, NULL);
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+	 xiofreeaddrinfo(themarr);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
       default:
+	 if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
 	 xiofreeaddrinfo(themarr);
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
-      xiofreeaddrinfo(themarr);
-      applyopts(sfd, -1, opts, PH_ALL);
 
-      if ((result = _xio_openlate(sfd, opts)) < 0)
+      Notice2("opening connection to sockd %s:%s", sockdname, socksport);
+      result =
+	 _xioopen_ipapp_connect(sfd, sockdname, opts, themarr,
+				needbind, bindarr, bindport, lowport, level);
+      _errno = errno;
+      if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+      xiofreeaddrinfo(themarr);
+      switch (result) {
+      case STAT_OK: break;
+#if WITH_RETRY
+      case STAT_RETRYLATER:
+      case STAT_RETRYNOW:
+	 if (sfd->forever || sfd->retry--) {
+	    if (result == STAT_RETRYLATER) {
+	       Nanosleep(&sfd->intervall, NULL);
+	    }
+	    freeopts(opts);
+	    continue;
+	 }
+#endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
+      default:
+	 errno = _errno;
+	 Error4("%s:%s:...,socksport=%s: %s", argv[0], sockdname, socksport,
+		_errno?strerror(_errno):"(See above)");
+	 freeopts(opts0);
+	 freeopts(opts);
 	 return result;
+      }
 
       result = _xioopen_socks4_connect(sfd, sockhead, buflen, level);
       switch (result) {
@@ -180,11 +200,16 @@ static int xioopen_socks4_connect(
       case STAT_RETRYLATER:
       case STAT_RETRYNOW:
 	 if (sfd->forever || sfd->retry--) {
-	    if (result == STAT_RETRYLATER)  Nanosleep(&sfd->intervall, NULL);
+	    if (result == STAT_RETRYLATER)
+	       Nanosleep(&sfd->intervall, NULL);
+	    freeopts(opts);
 	    continue;
 	 }
 #endif /* WITH_RETRY */
+	 /* FALLTHROUGH */
       default:
+	 freeopts(opts);
+	 freeopts(opts0);
 	 return result;
       }
 
@@ -201,10 +226,13 @@ static int xioopen_socks4_connect(
 				   so Notice is too weak */
 	 }
 	 while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
-	    if (sfd->forever || --sfd->retry) {
+	    if (sfd->forever || sfd->retry--) {
 	       Nanosleep(&sfd->intervall, NULL);
+	       freeopts(opts);
 	       continue;
 	    }
+	    freeopts(opts);
+	    freeopts(opts0);
 	    return STAT_RETRYLATER;
 	 }
 
@@ -216,8 +244,13 @@ static int xioopen_socks4_connect(
 
 	 /* parent process */
 	 Close(sfd->fd);
+	 /* with and without retry */
 	 Nanosleep(&sfd->intervall, NULL);
-	 dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
+	 while (maxchildren > 0 && num_child >= maxchildren) {
+	    Info1("all %d allowed children are active, waiting", maxchildren);
+	    Nanosleep(&sfd->intervall, NULL);
+	 }
+	 freeopts(opts);
 	 continue;
       } else
 #endif /* WITH_RETRY */
@@ -226,9 +259,19 @@ static int xioopen_socks4_connect(
       }
 
    } while (true);	/* end of complete open loop - drop out on success */
-   return 0;
+   /* only "active" process breaks (master without fork, or child) */
+
+   Notice4("successfully connected to %s:%s via sockd %s:%s",
+	   targetname, targetport, sockdname, socksport);
+
+   result = _xio_openlate(sfd, opts);
+   freeopts(opts);
+   freeopts(opts0);
+   return result;
 }
 
+#endif /* WITH_SOCKS4 || WITH_SOCKS4A */
+#if WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5
 
 int _xioopen_opt_socksport(
 	struct opt *opts,
@@ -236,7 +279,8 @@ int _xioopen_opt_socksport(
 {
    struct servent *se;
 
-   if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) {
+   if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0 &&
+       *socksport == NULL) {
       if ((se = getservbyname("socks", "tcp")) != NULL) {
 	 Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port));
 	 if ((*socksport = Malloc(6)) == NULL) {
@@ -253,8 +297,16 @@ int _xioopen_opt_socksport(
    return 0;
 }
 
+#endif /* WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 */
+#if WITH_SOCKS4 || WITH_SOCKS4A
 
-int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) {
+int _xioopen_socks4_init(
+	const char *targetport,
+	struct opt *opts,
+	char **socksport,
+	struct socks4 *sockhead,
+	size_t *headlen)
+{
    char *userid;
 
    /* generate socks header - points to final target */
@@ -280,14 +332,14 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc
 
 
 /* called within retry/fork loop, before connect() */
-int
-   _xioopen_socks4_connect0(struct single *sfd,
-			    const char *hostname,	/* socks target host */
-			    int socks4a,
-			    struct socks4 *sockhead,
-			    ssize_t *headlen,		/* get available space,
-							   return used length*/
-			    int level) {
+int _xioopen_socks4_prepare(
+	struct single *sfd,
+	const char *hostname,	/* socks target host */
+	int socks4a,
+	struct socks4 *sockhead,
+	ssize_t *headlen,	/* get available space, return used length*/
+	int level)
+{
    int result;
 
    if (!socks4a) {
@@ -364,7 +416,7 @@ int _xioopen_socks4_connect(struct single *sfd,
       }
    }
 #endif /* WITH_MSGLEVEL <= E_DEBUG */
-   if (writefull(sfd->fd, sockhead, headlen) < 0) {
+   if (writefull(sfd->fd, sockhead, headlen, NULL) < 0) {
       Msg4(level, "write(%d, %p, "F_Zu"): %s",
 	   sfd->fd, sockhead, headlen, strerror(errno));
       if (Close(sfd->fd) < 0) {
@@ -429,16 +481,7 @@ int _xioopen_socks4_connect(struct single *sfd,
    switch (replyhead->action) {
    case SOCKS_CD_GRANTED:
       /* Notice("socks: connect request succeeded"); */
-#if 0
-      if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) {
-	 Warn4("getsockname(%d, %p, {%d}): %s",
-		sfd->fd, &us, uslen, strerror(errno));
-      }
-      Notice1("successfully connected from %s via socks4",
-	      sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff)));
-#else
       Notice("successfully connected via socks4");
-#endif
       break;
 
    case SOCKS_CD_FAILED:
diff --git a/xio-socks.h b/xio-socks.h
index b089ec2..f5abfb9 100644
--- a/xio-socks.h
+++ b/xio-socks.h
@@ -10,9 +10,9 @@ struct socks4 {
    uint8_t  action;
    uint16_t port;
    uint32_t dest;
-   char userid[1];	/* just to have access via this struct */
+   char userid[0];	/* just to have access via this struct */
 } ;
-#define SIZEOF_STRUCT_SOCKS4 8
+#define SIZEOF_STRUCT_SOCKS4 ((size_t)&((struct socks4 *)0)->userid)
 
 extern const struct optdesc opt_socksport;
 extern const struct optdesc opt_socksuser;
@@ -21,15 +21,8 @@ extern const struct addrdesc xioaddr_socks4_connect;
 extern const struct addrdesc xioaddr_socks4a_connect;
 
 extern int _xioopen_opt_socksport(struct opt *opts, char **socksport);
-extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen);
-extern int
-   _xioopen_socks4_connect0(struct single *xfd,
-			    const char *hostname,	/* socks target host */
-			    int socks4a,
-			    struct socks4 *sockhead,
-			    ssize_t *headlen,		/* get available space,
-							   return used length*/
-			    int level);
+extern int _xioopen_socks4_init(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen);
+extern int _xioopen_socks4_prepare(struct single *xfd, const char *hostname, int socks4a, struct socks4 *sockhead, ssize_t *headlen, int level);
 extern int _xioopen_socks4_connect(struct single *xfd,
 				   struct socks4 *sockhead,
 				   size_t headlen,
diff --git a/xio-socks5.c b/xio-socks5.c
index 8543881..27ae1b1 100644
--- a/xio-socks5.c
+++ b/xio-socks5.c
@@ -53,7 +53,7 @@ static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xi
 
 const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>[:<socks-port>]:<target-host>:<target-port>") };
 
-const struct addrdesc xioaddr_socks5_listen  = { "SOCKS5-LISTEN",  1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND,    0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") };
+const struct addrdesc xioaddr_socks5_listen  = { "SOCKS5-LISTEN",  1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND,    0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") };
 
 static const char * _xioopen_socks5_strerror(uint8_t r)
 {
@@ -136,7 +136,7 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level)
 	}
 #endif
 
-	if (writefull(sfd->fd, client_hello, client_hello_size) < 0) {
+	if (writefull(sfd->fd, client_hello, client_hello_size, NULL) < 0) {
 		Msg4(level, "write(%d, %p, %d): %s",
 		     sfd->fd, client_hello, client_hello_size,
 		     strerror(errno));
@@ -188,6 +188,8 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level)
 		return STAT_RETRYLATER;
 	}
 
+	Debug2("received SOCKS5 server hello %02x %02x",
+	       server_hello_ptr[0], server_hello_ptr[1]);
 	Info2("received SOCKS5 server hello version=%d method=%d",
 		server_hello.version,
 		server_hello.method);
@@ -332,6 +334,12 @@ static int _xioopen_socks5_read_reply(
 			}
 			return STAT_RETRYLATER;
 		}
+		Debug5("received SOCKS5 reply %02x %02x %02x %02x %02x",
+		       ((unsigned char *)reply+bytes_read)[0],
+		       ((unsigned char *)reply+bytes_read)[1],
+		       ((unsigned char *)reply+bytes_read)[2],
+		       ((unsigned char *)reply+bytes_read)[3],
+		       ((unsigned char *)reply+bytes_read)[4]);
 		bytes_read += result;
 
 		/* Once we've read 5 bytes, figure out total message length and
@@ -418,7 +426,7 @@ static int _xioopen_socks5_request(
 	}
 #endif
 
-	if (writefull(sfd->fd, req, bytes) < 0) {
+	if (writefull(sfd->fd, req, bytes, NULL) < 0) {
 		Msg4(level, "write(%d, %p, %d): %s",
 			sfd->fd, req, bytes, strerror(errno));
 		if (Close(sfd->fd) < 0) {
@@ -504,6 +512,7 @@ static int xioopen_socks5(
 {
 	int socks_command = addrdesc->arg1;
 	bool dofork = false;
+	int maxchildren = 0;
 	int socktype = SOCK_STREAM;
 	int pf = PF_UNSPEC;
 	int ipproto = IPPROTO_TCP;
@@ -511,17 +520,12 @@ static int xioopen_socks5(
 	struct opt *opts0 = NULL;
 	struct single *sfd = &xxfd->stream;
 	const char *socks_server, *target_name, *target_port, *socks_port;
-	union sockaddr_union us_sa, *us = &us_sa;
-	socklen_t uslen = sizeof(us_sa);
-	struct addrinfo **themarr, *themp;
+	struct addrinfo **bindarr = NULL;
+	struct addrinfo **themarr = NULL;
+	uint16_t bindport = 0;
 	bool needbind = false;
 	bool lowport = false;
-	char infobuff[256];
 
-	if (!xioparms.experimental) {
-		Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
-		return STAT_NORETRY;
-	}
 	if (argc < 4 || argc > 5) {
 		xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
 		return STAT_NORETRY;
@@ -533,78 +537,120 @@ static int xioopen_socks5(
 		target_name = argv[3];
 		target_port = argv[4];
 	} else {
+		socks_port = NULL;
 		target_name = argv[2];
 		target_port = argv[3];
 	}
 
-	if (sfd->howtoend == END_UNSPEC)
-		sfd->howtoend = END_SHUTDOWN;
-	if (applyopts_single(sfd, opts, PH_INIT) < 0)	return -1;
-	applyopts(sfd, -1, opts, PH_INIT);
-
-	retropt_int(opts, OPT_SO_TYPE, &socktype);
-	retropt_bool(opts, OPT_FORK, &dofork);
+	/* Apply and retrieve some options */
+	result = _xioopen_ipapp_init(sfd, xioflags, opts,
+			        &dofork, &maxchildren,
+			        &pf, &socktype, &ipproto);
+	if (result != STAT_OK)
+		return result;
 
 	if (_xioopen_opt_socksport(opts, (char **)&socks_port) < 0) {
 		return STAT_NORETRY;
 	}
+	/*! possible memory leak */
 
-	result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
-					&pf, ipproto,
-					sfd->para.socket.ip.ai_flags,
-					&themarr, us, &uslen,
-					&needbind, &lowport, socktype);
+	opts0 = opts;
+	opts = NULL;
 
-	Notice2("connecting to socks5 server %s:%s",
-		socks_server, socks_port);
+	Notice4("opening connection to %s:%s vis socks5 server %s:%s",
+		target_name, target_port, socks_server, socks_port);
 
-	do {
+	do {	/* loop over retries (failed connect and socks-request attempts)
+		   and/or forks */
+		int _errno;
 #if WITH_RETRY
 		if (sfd->forever || sfd->retry) {
-			level = E_INFO;
-		} else {
-			level = E_ERROR;
-		}
+			level = E_NOTICE;
+		} else
 #endif
+			level = E_WARN;
 
-		/* loop over themarr */
-		themp = themarr[0];
-		while (themp != NULL) {
-			Notice1("opening connection to %s",
-				sockaddr_info(themp->ai_addr, themp->ai_addrlen,
-					      infobuff, sizeof(infobuff)));
-			result = _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us),
-						  themp->ai_addr, themp->ai_addrlen,
-						  opts, pf?pf:themp->ai_family, socktype,
-						  IPPROTO_TCP, lowport, level);
-			if (result == STAT_OK)
-				break;
-			themp = themp->ai_next;
-			if (themp == NULL)
-				result = STAT_RETRYLATER;
+		opts = copyopts(opts0, GROUP_ALL);
 
-			switch(result){
-				break;
+		result =
+			_xioopen_ipapp_prepare(&opts, opts0, socks_server, socks_port,
+					       pf, socktype, ipproto,
+					       sfd->para.socket.ip.ai_flags,
+					       &themarr, &bindarr, &bindport, &needbind,
+					       &lowport);
+		switch (result) {
+		case STAT_OK: break;
 #if WITH_RETRY
-			case STAT_RETRYLATER:
-			case STAT_RETRYNOW:
-				if (sfd->forever || sfd->retry-- ) {
-					if (result == STAT_RETRYLATER)	Nanosleep(&sfd->intervall, NULL);
-					continue;
-				}
-#endif
-			default:
+		case STAT_RETRYLATER:
+		case STAT_RETRYNOW:
+			if (sfd->forever || sfd->retry--) {
+				if (result == STAT_RETRYLATER)
+					Nanosleep(&sfd->intervall, NULL);
+				if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
 				xiofreeaddrinfo(themarr);
-				return result;
+				freeopts(opts);
+				continue;
 			}
-		}
-		xiofreeaddrinfo(themarr);
-		applyopts(sfd, -1, opts, PH_ALL);
-
-		if ((result = _xio_openlate(sfd, opts)) < 0)
+#endif /* WITH_RETRY */
+			/* FALLTHROUGH */
+		case STAT_NORETRY:
+			if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+			xiofreeaddrinfo(themarr);
+			freeopts(opts);
+			freeopts(opts0);
 			return result;
+		}
 
-		if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) {
+		Notice2("opening connection to socks5 server %s:%s",
+			socks_server, socks_port);
+		result =
+			_xioopen_ipapp_connect(sfd, socks_server, opts, themarr,
+					       needbind, bindarr, bindport, lowport, level);
+		_errno = errno;
+		if (bindarr != NULL)  xiofreeaddrinfo(bindarr);
+		xiofreeaddrinfo(themarr);
+		switch (result) {
+		case STAT_OK: break;
+#if WITH_RETRY
+		case STAT_RETRYLATER:
+		case STAT_RETRYNOW:
+			if (sfd->forever || sfd->retry--) {
+				if (result == STAT_RETRYLATER) {
+					Nanosleep(&sfd->intervall, NULL);
+				}
+				freeopts(opts);
+				continue;
+			}
+#endif /* WITH_RETRY */
+			/* FALLTHROUGH */
+		default:
+			Error4("%s:%s:%s:...: %s",
+			       argv[0], socks_server, socks_port,
+			       _errno?strerror(_errno):"(See above)");
+			freeopts(opts0);
+			freeopts(opts);
+			return result;
+		}
+
+		result = _xioopen_socks5_handshake(sfd, level);
+		switch (result) {
+		case STAT_OK: break;
+#if WITH_RETRY
+		case STAT_RETRYLATER:
+		case STAT_RETRYNOW:
+			if (sfd->forever || sfd->retry--) {
+				if (result == STAT_RETRYLATER) {
+					Nanosleep(&sfd->intervall, NULL);
+				}
+				freeopts(opts);
+				continue;
+			}
+#endif /* WITH_RETRY */
+			/* FALLTHROUGH */
+		default:
+			Error3("%s:%s:%s: Connection failed", argv[0], socks_server, socks_port);
+			freeopts(opts0);
+			freeopts(opts);
 			return result;
 		}
 
@@ -616,11 +662,16 @@ static int xioopen_socks5(
 		case STAT_RETRYLATER:
 		case STAT_RETRYNOW:
 			if ( sfd->forever || sfd->retry-- ) {
-				if (result == STAT_RETRYLATER)	Nanosleep(&sfd->intervall, NULL);
+				if (result == STAT_RETRYLATER)
+					Nanosleep(&sfd->intervall, NULL);
+				freeopts(opts);
 				continue;
 			}
-#endif
+#endif /* WITH_RETRY */
+			/* FALLTHROUGH */
 		default:
+			freeopts(opts);
+			freeopts(opts0);
 			return result;
 		}
 
@@ -636,12 +687,18 @@ static int xioopen_socks5(
 				level = E_WARN;
 			}
 			while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
-				if (sfd->forever || --sfd->retry) {
+				if (sfd->forever || sfd->retry) {
+					if (sfd->retry > 0)
+						--sfd->retry;
 					Nanosleep(&sfd->intervall, NULL);
+					freeopts(opts);
 					continue;
 				}
+				freeopts(opts);
+				freeopts(opts0);
 				return STAT_RETRYLATER;
 			}
+
 			if ( pid == 0 ) {
 				sfd->forever = false;
 				sfd->retry = 0;
@@ -650,17 +707,26 @@ static int xioopen_socks5(
 
 			Close(sfd->fd);
 			Nanosleep(&sfd->intervall, NULL);
-			dropopts(opts, PH_ALL);
-			opts = copyopts(opts0, GROUP_ALL);
+			while (maxchildren > 0 && num_child >= maxchildren) {
+				Info1("all %d allowed children are active, waiting", maxchildren);
+				Nanosleep(&sfd->intervall, NULL);
+			}
+			freeopts(opts);
 			continue;
 		} else
-#endif
+#endif /* WITH_RETRY */
 		{
 			break;
 		}
 	} while (true);
 
-	return 0;
+	Notice4("successfully connected to %s:%s via socks5 server %s:%s",
+		target_name, target_port, socks_server, socks_port);
+
+	result = _xio_openlate(sfd, opts);
+	freeopts(opts);
+	freeopts(opts0);
+	return STAT_OK;
 }
 
 #endif /* WITH_SOCKS5 */
diff --git a/xio-stdio.c b/xio-stdio.c
index 9f8aac9..a84c61e 100644
--- a/xio-stdio.c
+++ b/xio-stdio.c
@@ -17,7 +17,7 @@ static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xio
 static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
 
 
-/* we specify all option groups that we can imagine for a FD, becasue the
+/* We specify all option groups that we can imagine for a FD, because the
    changed parsing mechanism does not allow us to check the type of FD before
    applying the options */
 const struct addrdesc xioaddr_stdio  = { "STDIO",  3, xioopen_stdio, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(NULL) };
diff --git a/xio-streams.c b/xio-streams.c
index e470f3e..3be956e 100644
--- a/xio-streams.c
+++ b/xio-streams.c
@@ -65,7 +65,7 @@ void dummy(void) {
 #else /* !defined(ENABLE_APPLYOPT) */
 
 #include "xiosysincludes.h"
-#if WITH_STREAMS        /* make this address configure dependend */
+#if WITH_STREAMS        /* make this address configure dependent */
 #include "xioopen.h"
 
 #include "xio-fd.h"
diff --git a/xio-tcpwrap.c b/xio-tcpwrap.c
index 26a3a1f..b8d2797 100644
--- a/xio-tcpwrap.c
+++ b/xio-tcpwrap.c
@@ -79,7 +79,7 @@ int xio_retropt_tcpwrap(
 }
 
 
-/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
+/* Returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitly allowed
    */
 int xio_tcpwrap_check(
 	struct single *sfd,
diff --git a/xio-termios.c b/xio-termios.c
index 60209f7..976165d 100644
--- a/xio-termios.c
+++ b/xio-termios.c
@@ -501,7 +501,7 @@ int xiotermios_spec(int fd, int optcode) {
 #if HAVE_CFMAKERAW
       cfmakeraw(&_xiotermios_data.termarg);
 #else
-      /* these setting follow the Linux documenation of cfmakeraw */
+      /* These settings follow the Linux documentation of cfmakeraw */
       _xiotermios_data.termarg.c_iflag &=
 	 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
       _xiotermios_data.termarg.c_oflag &= ~(OPOST);
diff --git a/xio-tun.c b/xio-tun.c
index f66be7e..4618da4 100644
--- a/xio-tun.c
+++ b/xio-tun.c
@@ -120,7 +120,7 @@ static int xioopen_tun(
    if (retropt_bool(opts, OPT_IFF_NO_PI, &no_pi) == 0) {
       if (no_pi) {
 	 ifr.ifr_flags |= IFF_NO_PI;
-#if 0 /* not neccessary for now */
+#if 0 /* not necessary for now */
       } else {
 	 ifr.ifr_flags &= ~IFF_NO_PI;
 #endif
@@ -139,7 +139,7 @@ static int xioopen_tun(
    /* we seem to need a socket for manipulating the interface */
    if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
       Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno));
-      sockfd = sfd->fd;	/* desparate fallback attempt */
+      sockfd = sfd->fd;	/* desperate fallback attempt */
    }
 
    /*--------------------- setting interface address and netmask ------------*/
diff --git a/xio-udp.c b/xio-udp.c
index 10704e3..94a8947 100644
--- a/xio-udp.c
+++ b/xio-udp.c
@@ -85,7 +85,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
        return STAT_NORETRY;
    }
 
-#if WITH_IP4 /*|| WITH_IP6*/
+#if WITH_IP4 || WITH_IP6
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, pf, &sfd->para.socket.range,
 			sfd->para.socket.ip.ai_flags)
@@ -277,8 +277,10 @@ int xioopen_ipdgram_listen(
    int pf = addrdesc->arg1;
    int ipproto = addrdesc->arg2;
    union sockaddr_union us;
+   int bind_rc;
    int socktype = SOCK_DGRAM;
    socklen_t uslen;
+   int result;
 
    if (argc != 2) {
       xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
@@ -295,12 +297,31 @@ int xioopen_ipdgram_listen(
    applyopts(sfd, -1, opts, PH_INIT);
 
    uslen = socket_init(pf, &us);
-   retropt_bind(opts, pf, socktype, ipproto,
+   bind_rc = retropt_bind(opts, pf, socktype, ipproto,
 		(struct sockaddr *)&us, &uslen, 1,
 		xfd->stream.para.socket.ip.ai_flags);
+   if (bind_rc == STAT_NORETRY)
+      return STAT_NORETRY;
+   if (pf == PF_UNSPEC && bind_rc == STAT_OK)
+      pf = us.soa.sa_family;
 
    if (false) {
       ;
+#if WITH_IP4 || WITH_IP6
+   } else if (pf == PF_UNSPEC && bind_rc == STAT_NOACTION) {
+      int ai_flags[2];
+      ai_flags[0] = sfd->para.socket.ip.ai_flags[0];
+      ai_flags[1] = sfd->para.socket.ip.ai_flags[1];
+      if (!(ai_flags[1] & AI_PASSIVE))
+	 ai_flags[0] |= AI_PASSIVE;
+      result =
+	 xioresolve(NULL, portname, pf, socktype, ipproto, &us, &uslen, ai_flags);
+      if (result != STAT_OK) {
+	 Error("error resolving bind option");
+	 return STAT_NORETRY;
+      }
+      pf = us.soa.sa_family;
+#endif /* WITH_IP4 || WITH_IP6*/
 #if WITH_IP4
    } else if (pf == PF_INET) {
       us.ip4.sin_port = parseport(portname, ipproto);
@@ -349,7 +370,7 @@ int xioopen_udp_sendto(
    applies and consumes the following option:
    PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE
    OFUNC_OFFSET
-   OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
+   OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC
  */
 int _xioopen_udp_sendto(const char *hostname, const char *servname,
 			struct opt *opts,
@@ -529,7 +550,7 @@ int xioopen_udp_recvfrom(
    if (sfd->howtoend == END_UNSPEC)
       sfd->howtoend = END_NONE;
 
-   /* Set AI_PASSIVE, except when it is explicitely disabled */
+   /* Set AI_PASSIVE, except when it is explicitly disabled */
    ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0];
    ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1];
    if (!(ai_flags2[1] & AI_PASSIVE))
@@ -605,7 +626,7 @@ int xioopen_udp_recv(
    xioinit_ip(&pf, xioparms.default_ip);
    retropt_socket_pf(opts, &pf);
 
-   /* Set AI_PASSIVE, except when it is explicitely disabled */
+   /* Set AI_PASSIVE, except when it is explicitly disabled */
    ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0];
    ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1];
    if (!(ai_flags2[1] & AI_PASSIVE))
@@ -646,7 +667,7 @@ int xioopen_udp_recv(
    }
 #endif
 
-#if WITH_IP4 /*|| WITH_IP6*/
+#if WITH_IP4 || WITH_IP6
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
       if (xioparserange(rangename, pf, &xfd->stream.para.socket.range,
 			xfd->stream.para.socket.ip.ai_flags)
diff --git a/xio-unix.c b/xio-unix.c
index 42bb2a3..735b4af 100644
--- a/xio-unix.c
+++ b/xio-unix.c
@@ -15,7 +15,7 @@
 
 #if WITH_UNIX
 
-/* to avoid unneccessary runtime if () conditionals when no abstract support is
+/* To avoid unnecessary runtime if () conditionals when no abstract support is
    compiled in (or at least to give optimizing compilers a good chance) we need
    a constant that can be used in C expressions */
 #if WITH_ABSTRACT_UNIXSOCKET
@@ -33,7 +33,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
 
 /* the first free parameter is 0 for "normal" unix domain sockets, or 1 for
    abstract unix sockets (Linux); the second and third free parameter are
-   unsused */
+   unused */
 const struct addrdesc xioaddr_unix_connect = { "UNIX-CONNECT",  1+XIO_RDWR,   xioopen_unix_connect,  GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY,                          0, 0, 0 HELP(":<filename>") };
 #if WITH_LISTEN
 const struct addrdesc xioaddr_unix_listen  = { "UNIX-LISTEN",   1+XIO_RDWR,   xioopen_unix_listen,   GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
@@ -123,6 +123,7 @@ static int xioopen_unix_listen(
    /* we expect the form: filename */
    const char *name;
    xiosingle_t *sfd = &xxfd->stream;
+   char *bindstring = NULL;
    int pf = PF_UNIX;
    int socktype = SOCK_STREAM;
    int protocol = 0;
@@ -140,6 +141,12 @@ static int xioopen_unix_listen(
    }
    name = argv[1];
 
+   if (retropt_string(opts, OPT_BIND, &bindstring) == 0) {
+      Error2("%s:%s: binds implicitly, bind option not allowed",
+	     addrdesc->defname, argv[1]);
+      free(bindstring);
+   }
+
    sfd->para.socket.un.tight = UNIX_TIGHTSOCKLEN;
    retropt_socket_pf(opts, &pf);
    if (sfd->howtoend == END_UNSPEC)
@@ -257,7 +264,12 @@ static int xioopen_unix_connect(
 
    if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
 		    (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight,
-		    sfd->para.socket.ip.ai_flags)
+#if WITH_TCP
+		    sfd->para.socket.ip.ai_flags
+#else
+		    0
+#endif /* WITH_TCP */
+)
       == STAT_OK) {
       needbind = true;
    }
@@ -426,7 +438,12 @@ static int xioopen_unix_sendto(
 
    if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
 		    (addrdesc->arg1/*abstract*/<<1)| sfd->para.socket.un.tight,
-		    sfd->para.socket.ip.ai_flags)
+#if WITH_TCP
+		    sfd->para.socket.ip.ai_flags
+#else
+		    0
+#endif /* WITH_TCP */
+		    )
        == STAT_OK) {
       needbind = true;
    }
@@ -665,7 +682,7 @@ static int xioopen_unix_client(
    PH_CONNECTED, PH_LATE, ?PH_CONNECT
    OFUNC_OFFSET,
    OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND,
-   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK,
+   OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_O_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK,
 */
 int
 _xioopen_unix_client(
@@ -709,7 +726,12 @@ _xioopen_unix_client(
 
    if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
 		    (abstract<<1)|sfd->para.socket.un.tight,
-		    sfd->para.socket.ip.ai_flags)
+#if WITH_TCP
+		    sfd->para.socket.ip.ai_flags
+#else
+		    0
+#endif /* WITH_TCP */
+		    )
        != STAT_NOACTION) {
       needbind = true;
    }
@@ -773,7 +795,7 @@ _xioopen_unix_client(
 			    opts, pf, SOCK_SEQPACKET, protocol,
 			    needtemp, E_INFO)) == 0)
 	 break;
-      if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/
+      if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/ && errno != ESOCKTNOSUPPORT/*Debian3*/
 #if WITH_ABSTRACT_UNIXSOCKET
 	  && !(abstract && errno == ECONNREFUSED)
 #endif
diff --git a/xio-vsock.c b/xio-vsock.c
index fcd09bc..0531994 100644
--- a/xio-vsock.c
+++ b/xio-vsock.c
@@ -98,7 +98,7 @@ static int xioopen_vsock_connect(
 
    ret = retropt_bind(opts, pf, socktype, protocol,
                       (struct sockaddr *)&sa_local, &sa_len, 3,
-		      sfd->para.socket.ip.ai_flags);
+		      NULL);
    if (ret == STAT_NORETRY)
       return ret;
    if (ret == STAT_OK)
diff --git a/xio.h b/xio.h
index a276a56..05bef49 100644
--- a/xio.h
+++ b/xio.h
@@ -120,12 +120,13 @@ typedef struct xioparms {
    const char *sniffleft_name; 		/* file name with -r */
    const char *sniffright_name; 	/* file name with -R */
    size_t bufsiz;
+   struct timeval total_timeout;/* when nothing happens, die after seconds */
 } xioparms_t;
 
 /* pack the description of a lock file */
 typedef struct {
    const char     *lockfile;	/* name of lockfile; NULL if no locking */
-   bool            waitlock;	/* dont't exit when already locked */
+   bool            waitlock;	/* don't exit when already locked */
    struct timespec intervall;	/* polling intervall */
 } xiolock_t;
 
diff --git a/xioconfig.h b/xioconfig.h
index 1c12c1a..ab3d115 100644
--- a/xioconfig.h
+++ b/xioconfig.h
@@ -16,7 +16,13 @@
 #  define WITH_OPEN 1
 #endif
 
-#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY
+#if WITH_INTERFACE || WITH_TUN
+#  define _WITH_INTERFACE 1
+#else
+#  define _WITH_INTERFACE 0
+#endif
+
+#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY || _WITH_INTERFACE
 #  define WITH_NAMED 1
 #endif
 
@@ -34,7 +40,7 @@
 			   with IP6 */
 #endif
 
-#if WITH_OPENSSL
+#if WITH_OPENSSL || WITH_SOCKS5
 #  define WITH_TCP 1
 #  define WITH_IP4 1
 #endif
@@ -57,7 +63,7 @@
 #  define _WITH_UDP 1
 #endif
 
-#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP || WITH_GENERICSOCKET
+#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_SOCKS5 || WITH_RAWIP || WITH_GENERICSOCKET || WITH_SOCKETPAIR || WITH_VSOCK
 #  define _WITH_SOCKET 1
 #else
 #  undef _WITH_SOCKET
@@ -71,10 +77,8 @@
 #  undef WITH_LIBWRAP
 #endif
 
-#if WITH_INTERFACE || WITH_TUN
-#  define _WITH_INTERFACE 1
-#else
-#  define _WITH_INTERFACE 0
+#if WITH_SOCKETPAIR || WITH_EXEC || WITH_SYSTEM || WITH_SHELL
+#  define _WITH_SOCKETPAIR 1
 #endif
 
 #if WITH_GENERICSOCKET || _WITH_INTERFACE
diff --git a/xiohelp.c b/xiohelp.c
index 1ba92a8..fae8cfb 100644
--- a/xiohelp.c
+++ b/xiohelp.c
@@ -53,7 +53,7 @@ static const char *addressgroupnames[] = {
 
 /* keep consistent with xioopts.h:enum ephase ! */
 static char *optionphasenames[] = {
-	"ALL",		"INIT",		"EARLY",
+	"ALL",		"OFFSET",	"INIT",		"EARLY",
 	"PREOPEN",	"OPEN",		"PASTOPEN",
 	"PRESOCKET",	"SOCKET",	"PASTSOCKET",
 	"PREBIGEN",	"BIGEN",	"PASTBIGEN",
@@ -87,6 +87,8 @@ static int xiohelp_option(FILE *of, const struct optname *on, const char *name)
    groups = on->desc->group;
    occurred = false;
    chars = 7;
+   if (groups == 0)
+      fputs("(all)", of);
    for (j = 0; j < 8*sizeof(groups_t); ++j) {
       if (groups & 1) {
 	 if (occurred) {
@@ -150,8 +152,9 @@ int xioopenhelp(FILE *of,
 	 i = (40 - chars + 7) / 8;
 	 for (; i > 0; --i) { fputc('\t', of); }
 	 fputs("\tgroups=", of);
-	 groups = an->desc->groups;  occurred = false;
-	 for (j = 0; j < 32; ++j) {
+	 groups = an->desc->groups;
+	 occurred = false;
+	 for (j = 0; j < sizeof(groups_t)*8; ++j) {
 	    if (groups & 1) {
 	       if (occurred) { fputc(',', of); }
 	       fprintf(of, "%s", addressgroupnames[j]);
diff --git a/xioinitialize.c b/xioinitialize.c
index b06915e..3abc8e2 100644
--- a/xioinitialize.c
+++ b/xioinitialize.c
@@ -175,8 +175,8 @@ static int xio_nokill(xiofile_t *sock) {
    return result;
 }
 
-/* call this function immediately after fork() in child process */
-/* it performs some neccessary actions
+/* Call this function immediately after fork() in child process */
+/* It performs some necessary actions
    returns 0 on success or != 0 if an error occurred */
 int xio_forked_inchild(void) {
    int result = 0;
diff --git a/xiolayer.c b/xiolayer.c
index 83b8839..a378293 100644
--- a/xiolayer.c
+++ b/xiolayer.c
@@ -48,7 +48,8 @@ int xio_chdir(
 		free(tmp_dir);
 		return -1;
 	}
-	*orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1);
+	/*0 *orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1); */
+	*orig_dir = Realloc3(*orig_dir, strlen(*orig_dir)+1, PATH_MAX);
 
 	if (Chdir(tmp_dir) < 0) {
 		Error2("chdir(\"%s\"): %s", tmp_dir, strerror(errno));
diff --git a/xiolockfile.c b/xiolockfile.c
index c6896d4..ff29c2f 100644
--- a/xiolockfile.c
+++ b/xiolockfile.c
@@ -52,7 +52,7 @@ int xiogetlock(const char *lockfile) {
 
    pid = Getpid();
    bytes = sprintf(pidbuf, F_pid"\n", pid);
-   if (writefull(fd, pidbuf, bytes) < 0) {
+   if (writefull(fd, pidbuf, bytes, NULL) < 0) {
       Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno));
       return -1;
    }
diff --git a/xioopen.c b/xioopen.c
index be17e3b..30ec859 100644
--- a/xioopen.c
+++ b/xioopen.c
@@ -177,11 +177,13 @@ const struct addrname addressnames[] = {
    { "PIPE",			&xioaddr_pipe },
 #endif
 #if WITH_POSIXMQ
+   { "POSIXMQ", 		&xioaddr_posixmq_bidir },
    { "POSIXMQ-BIDIRECTIONAL", 	&xioaddr_posixmq_bidir },
    { "POSIXMQ-READ", 		&xioaddr_posixmq_read },
    { "POSIXMQ-RECEIVE", 	&xioaddr_posixmq_receive },
    { "POSIXMQ-RECV", 		&xioaddr_posixmq_receive },
    { "POSIXMQ-SEND", 		&xioaddr_posixmq_send },
+   { "POSIXMQ-WRITE", 		&xioaddr_posixmq_write },
 #endif
 #if WITH_PROXY
    { "PROXY",			&xioaddr_proxy_connect },
@@ -471,14 +473,14 @@ static xiofile_t *xioallocfd(void) {
    fd->stream.escape	= -1;
 /* fd->stream.para.exec.pid = 0; */
    fd->stream.lineterm  = LINETERM_RAW;
-#if WITH_RESOLVE
+#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE
 #if HAVE_RES_RETRANS
    fd->stream.para.socket.ip.res.retrans = -1;
 #endif
 #if HAVE_RES_RETRY
    fd->stream.para.socket.ip.res.retry   = -1;
 #endif
-#endif /* WITH_RESOLVE */
+#endif /* ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE */
    return fd;
 }
 
@@ -701,10 +703,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
    mode_t orig_umask, tmp_umask;
    int result;
    /* Values to be saved until xioopen() is finished */
-#if WITH_RESOLVE && HAVE_RESOLV_H
+#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H
    int do_res;
    struct __res_state save_res;
-#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
+#endif
 #if WITH_NAMESPACES
    int save_netfd = -1;
 #endif
@@ -730,15 +732,15 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
    if (applyopts_single(sfd, sfd->opts, PH_OFFSET) < 0)
       return -1;
 
-#if WITH_NAMESPACES
+#if WITH_NAMESPACES 	/* netns */
    if ((save_netfd = xio_apply_namespace(sfd->opts)) < 0)
       return -1;
 #endif /* WITH_NAMESPACES */
 
-#if WITH_RESOLVE && HAVE_RESOLV_H
+#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H
    if ((do_res = xio_res_init(sfd, &save_res)) < 0)
       return STAT_NORETRY;
-#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
+#endif
 
    if (xio_chdir(sfd->opts, &orig_dir) < 0)
       return STAT_NORETRY;
@@ -769,10 +771,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
       free(orig_dir);
    }
 
-#if WITH_RESOLVE && HAVE_RESOLV_H
+#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H
    if (do_res)
       xio_res_restore(&save_res);
-#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
+#endif
 
 #if WITH_NAMESPACES
    if (save_netfd > 0) {
diff --git a/xioopts.c b/xioopts.c
index a751fd3..901a82b 100644
--- a/xioopts.c
+++ b/xioopts.c
@@ -177,7 +177,7 @@ static int applyopt(struct single *sfd,	int fd,	struct opt *opt);
    binary search! */
 /* NULL terminated */
 const struct optname optionnames[] = {
-#if HAVE_RESOLV_H && WITH_RES_AAONLY
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_AAONLY
 	IF_RESOLVE("aaonly",		&opt_res_aaonly)
 #endif
 #ifdef TCP_ABORT_THRESHOLD  /* HP_UX */
@@ -352,7 +352,7 @@ const struct optname optionnames[] = {
 #endif /* SO_CKSUMRECV */
 	/*IF_NAMED  ("cleanup",	&opt_cleanup)*/
 	IF_TERMIOS("clocal",	&opt_clocal)
-	IF_ANY    ("cloexec",	&opt_cloexec)
+	IF_ANY    ("cloexec",		&opt_cloexec)
 	IF_ANY    ("close",	&opt_end_close)
 	IF_OPENSSL("cn",		&opt_openssl_commonname)
 	IF_OPENSSL("commonname",	&opt_openssl_commonname)
@@ -390,8 +390,8 @@ const struct optname optionnames[] = {
 #  endif
 #endif /* defined(CRDLY) */
 	IF_TERMIOS("cread",	&opt_cread)
-	IF_OPEN   ("creat",	&opt_o_create)
-	IF_OPEN   ("create",	&opt_o_create)
+	IF_OPEN   ("creat",	&opt_o_creat)
+	IF_OPEN   ("create",	&opt_o_creat)
 	IF_ANY    ("crlf",      &opt_crnl)
 	IF_ANY    ("crnl",      &opt_crnl)
 	IF_TERMIOS("crterase",	&opt_echoe)
@@ -421,7 +421,7 @@ const struct optname optionnames[] = {
 #ifdef TCP_DEFER_ACCEPT	/* Linux 2.4.0 */
 	IF_TCP    ("defer-accept",	&opt_tcp_defer_accept)
 #endif
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("defnames",		&opt_res_defnames)
 #endif /* HAVE_RESOLV_H */
 #ifdef O_DELAY
@@ -454,10 +454,10 @@ const struct optname optionnames[] = {
 #ifdef VDISCARD
 	IF_TERMIOS("discard",	&opt_vdiscard)
 #endif
-#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
+#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
 	IF_IP     ("dns",		&opt_res_nsaddr)
 #endif
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("dnsrch",		&opt_res_dnsrch)
 #endif /* HAVE_RESOLV_H */
 #ifdef SO_DONTLINGER
@@ -721,7 +721,7 @@ const struct optname optionnames[] = {
 	IF_ANY    ("ignoreeof",	&opt_ignoreeof)
 	IF_ANY    ("ignoreof",	&opt_ignoreeof)
 	IF_TERMIOS("ignpar",	&opt_ignpar)
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("igntc",		&opt_res_igntc)
 #endif /* HAVE_RESOLV_H */
 	IF_TERMIOS("imaxbel",	&opt_imaxbel)
@@ -1032,7 +1032,10 @@ const struct optname optionnames[] = {
 #endif
 	IF_ANY    ("mode",	&opt_perm)
 #if WITH_POSIXMQ
-	IF_ANY	  ("mq-prio",	&opt_posixmq_priority)
+	IF_ANY	  ("mq-flush",		&opt_posixmq_flush)
+	IF_ANY	  ("mq-maxmsg",		&opt_posixmq_maxmsg)
+	IF_ANY	  ("mq-msgsize", 	&opt_posixmq_msgsize)
+	IF_ANY	  ("mq-prio",		&opt_posixmq_priority)
 #endif
 #ifdef TCP_MAXSEG
 	IF_TCP    ("mss",	&opt_tcp_maxseg)
@@ -1050,7 +1053,7 @@ const struct optname optionnames[] = {
 	IF_IP     ("multicast-ttl",	&opt_ip_multicast_ttl)
 	IF_IP     ("multicastloop",	&opt_ip_multicast_loop)
 	IF_IP     ("multicastttl",	&opt_ip_multicast_ttl)
-#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
+#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
 	IF_IP     ("nameserver",	&opt_res_nsaddr)
 #endif
 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
@@ -1118,7 +1121,7 @@ const struct optname optionnames[] = {
 	IF_OPENSSL("nosni",		&opt_openssl_no_sni)
 #endif
 	IF_INTERFACE("notrailers",	&opt_iff_notrailers)
-#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
+#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
 	IF_IP     ("nsaddr",		&opt_res_nsaddr)
 #endif
 #ifdef O_NSHARE
@@ -1132,8 +1135,8 @@ const struct optname optionnames[] = {
 #ifdef O_BINARY
 	IF_OPEN   ("o-binary",		&opt_o_binary)
 #endif
-	IF_OPEN   ("o-creat",	&opt_o_create)
-	IF_OPEN   ("o-create",	&opt_o_create)
+	IF_OPEN   ("o-creat",	&opt_o_creat)
+	IF_OPEN   ("o-create",	&opt_o_creat)
 #ifdef O_DEFER
 	IF_OPEN   ("o-defer",	&opt_o_defer)
 #endif
@@ -1191,7 +1194,8 @@ const struct optname optionnames[] = {
 #endif
 	IF_OPEN   ("o-trunc",	&opt_o_trunc)
 	IF_OPEN   ("o-wronly",	&opt_o_wronly)
-	IF_OPEN   ("o_create",	&opt_o_create)
+	IF_OPEN   ("o_creat",	&opt_o_creat)
+	IF_OPEN   ("o_create",	&opt_o_creat)
 #ifdef O_DEFER
 	IF_OPEN   ("o_defer",	&opt_o_defer)
 #endif
@@ -1348,9 +1352,12 @@ const struct optname optionnames[] = {
 	IF_INTERFACE("portsel",	&opt_iff_portsel)
 #endif
 #if WITH_POSIXMQ
+	IF_ANY	  ("posixmq-flush",	&opt_posixmq_flush)
+	IF_ANY	  ("posixmq-maxmsg",	&opt_posixmq_maxmsg)
+	IF_ANY	  ("posixmq-msgsize", 	&opt_posixmq_msgsize)
 	IF_ANY	  ("posixmq-priority",	&opt_posixmq_priority)
 #endif
-#if HAVE_RESOLV_H && WITH_RES_PRIMARY
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY
 	IF_RESOLVE("primary",		&opt_res_primary)
 #endif
 #ifdef SO_PRIORITY
@@ -1411,7 +1418,7 @@ const struct optname optionnames[] = {
 	IF_OPEN   ("rdonly",	&opt_o_rdonly)
 	IF_OPEN   ("rdwr",	&opt_o_rdwr)
 	IF_ANY    ("readbytes", &opt_readbytes)
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("recurse",		&opt_res_recurse)
 #endif /* HAVE_RESOLV_H */
 #ifdef IP_RECVDSTADDR
@@ -1451,7 +1458,7 @@ const struct optname optionnames[] = {
 #ifdef VREPRINT
 	IF_TERMIOS("reprint",	&opt_vreprint)
 #endif
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 #  if WITH_AA_ONLY
 	IF_RESOLVE("res-aaonly",	&opt_res_aaonly)
 #  endif
@@ -1480,15 +1487,15 @@ const struct optname optionnames[] = {
 #  endif
 	IF_RESOLVE("res-stayopen",	&opt_res_stayopen)
 	IF_RESOLVE("res-usevc",		&opt_res_usevc)
-#endif /* HAVE_RESOLV_H */
+#endif /* (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H */
 	IF_PROXY  ("resolv",	&opt_proxy_resolve)
 	IF_PROXY  ("resolve",	&opt_proxy_resolve)
 #ifdef IP_RETOPTS
 	IF_IP     ("retopts",	&opt_ip_retopts)
 #endif
-#  if HAVE_RES_RETRANS
+#if (WITH_IP4 || WITH_IP6) && HAVE_RES_RETRANS
 	IF_RESOLVE("retrans",		&opt_res_retrans)
-#  endif
+#endif
 #if WITH_INTERFACE && defined(PACKET_AUXDATA)
 	IF_SOCKET ("retrieve-vlan", 		&opt_retrieve_vlan)
 #endif
@@ -1576,8 +1583,10 @@ const struct optname optionnames[] = {
 #endif
 	IF_SOCKET ("setsockopt",	&opt_setsockopt)
 	IF_SOCKET ("setsockopt-bin",	&opt_setsockopt_bin)
+	IF_SOCKET ("setsockopt-connected",	&opt_setsockopt_connected)
 	IF_SOCKET ("setsockopt-int",	&opt_setsockopt_int)
 	IF_SOCKET ("setsockopt-listen",	&opt_setsockopt_listen)
+	IF_SOCKET ("setsockopt-socket",		&opt_setsockopt_socket)
 	IF_SOCKET ("setsockopt-string",	&opt_setsockopt_string)
 	IF_ANY    ("setuid",	&opt_setuid)
 	IF_ANY    ("setuid-early",	&opt_setuid_early)
@@ -1712,8 +1721,10 @@ const struct optname optionnames[] = {
 #endif /* SO_USELOOPBACK */
 	IF_SOCKET ("sockopt",		&opt_setsockopt)
 	IF_SOCKET ("sockopt-bin",	&opt_setsockopt_bin)
+	IF_SOCKET ("sockopt-conn",	&opt_setsockopt_connected)
 	IF_SOCKET ("sockopt-int",	&opt_setsockopt_int)
 	IF_SOCKET ("sockopt-listen",	&opt_setsockopt_listen)
+	IF_SOCKET ("sockopt-sock",	&opt_setsockopt_socket)
 	IF_SOCKET ("sockopt-string",	&opt_setsockopt_string)
 	IF_SOCKS4 ("socksport",	&opt_socksport)
 	IF_SOCKS4 ("socksuser",	&opt_socksuser)
@@ -1724,7 +1735,7 @@ const struct optname optionnames[] = {
 	IF_IPAPP  ("sourceport",	&opt_sourceport)
 	IF_IPAPP  ("sp",	&opt_sourceport)
 	IF_TERMIOS("start",	&opt_vstart)
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("stayopen",		&opt_res_stayopen)
 #endif /* HAVE_RESOLV_H */
 	IF_EXEC   ("stderr",    &opt_stderr)
@@ -1930,7 +1941,7 @@ const struct optname optionnames[] = {
 	IF_ANY    ("user",	&opt_user)
 	IF_NAMED  ("user-early",	&opt_user_early)
 	IF_ANY    ("user-late",	&opt_user_late)
-#if HAVE_RESOLV_H
+#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H
 	IF_RESOLVE("usevc",		&opt_res_usevc)
 #endif /* HAVE_RESOLV_H */
 #if defined(AI_V4MAPPED)
@@ -2654,13 +2665,13 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
 	       (*opts)[i].value3.u_string);
 	 break;
 
-#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
+#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) )
       case TYPE_IP_MREQN:
 	 xiotype_ip_add_membership(token, ent, opt);
 	 break;
-#endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
+#endif /* WITH_IP && defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) */
 
-#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
+#if _WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE)
       case TYPE_IP_MREQ_SOURCE:
 	 xiotype_ip_add_source_membership(token, ent, opt);
 	 break;
@@ -2768,7 +2779,8 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
 
       ++i;
       if ((i % 8) == 0) {
-	 *opts = Realloc(*opts, (i+8) * sizeof(struct opt));
+	 /*0 *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); */
+	 *opts = Realloc3(*opts, (i+8) * sizeof(struct opt), i * sizeof(struct opt));
 	 if (*opts == NULL) {
 	    return -1;
 	 }
@@ -2904,7 +2916,6 @@ int showleft(const struct opt *opts) {
    return 0;
 }
 
-
 /* determines the address group from mode_t */
 /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */
 groups_t _groupbits(mode_t mode) {
@@ -3100,7 +3111,7 @@ int retropt_int(struct opt *opts, int optcode, int *result) {
 /* Looks for the first option of type <optcode>. If the option is found,
    this function stores its int value in *result, "consumes" the
    option, and returns 0.
-   If the option is not found, *result is not modified, and -1 is returned. */
+   If the option is not found, values are not modified, and -1 is returned. */
 int retropt_2integrals(struct opt *opts, int optcode,
 		       union integral *value1, union integral *value2)
 {
@@ -3250,7 +3261,8 @@ int retropt_bind(struct opt *opts,
 		 int ipproto,
 		 struct sockaddr *sa,
 		 socklen_t *salen,
-		 int feats,	/* TCP etc: 1..address allowed,
+		 int feats,	/*         -1..generic addr spec
+				   TCP etc: 1..address allowed,
 					    3..address and port allowed
 				   UNIX (or'd): 1..tight
 						2..abstract
@@ -3274,10 +3286,13 @@ int retropt_bind(struct opt *opts,
    }
    bindp = bindname;
 
-   switch (af) {
+#if WITH_IP4 && WITH_IP6
+   /* Try to derive address family from string */
+   if (af == AF_UNSPEC && bindname[0] == '[')
+      af = AF_INET6;
+#endif /* WITH_IP4 && WITH_IP6 */
 
-   case AF_UNSPEC:
-      {
+   if (feats == -1) {
 	 size_t p = 0;
 	 dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i');
 	 *salen = p + sizeof(sa->sa_family);
@@ -3289,10 +3304,13 @@ int retropt_bind(struct opt *opts,
 #if HAVE_STRUCT_SOCKADDR_SALEN
 	 sa->sa_len = *salen;
 #endif
-      }
-      break;
+	 return STAT_OK;
+   }
+
+   switch (af) {
 
 #if WITH_IP4 || WITH_IP6 || WITH_VSOCK
+   case AF_UNSPEC:
 #if WITH_VSOCK
    case AF_VSOCK:
 #endif
@@ -3323,11 +3341,12 @@ int retropt_bind(struct opt *opts,
 	 }
       }
 
-      /* Set AI_PASSIVE, except when it is explicitely disabled */
+#  if WITH_IP4 || WITH_IP6
+      /* Set AI_PASSIVE, except when it is explicitly disabled */
       ai_flags2[0] = ai_flags[0];
       ai_flags2[1] = ai_flags[1];
       if (!(ai_flags2[1] & AI_PASSIVE))
-      ai_flags2[0] |= AI_PASSIVE;
+	 ai_flags2[0] |= AI_PASSIVE;
 
       if ((result =
 	   xioresolve(hostname[0]!='\0'?hostname:NULL, portp,
@@ -3337,6 +3356,8 @@ int retropt_bind(struct opt *opts,
 	 Error("error resolving bind option");
 	 return STAT_NORETRY;
       }
+/*#  else */
+#  endif /* WITH_IP4 || WITH_IP6 */
       break;
 #endif /* WITH_IP4 || WITH_IP6 || WITH_VSOCK */
 
@@ -3567,6 +3588,8 @@ int applyopt_ioctl_generic(
 	return 0;
 }
 
+#if _WITH_SOCKET
+
 int applyopt_sockopt(
 	int fd,
 	struct opt *opt)
@@ -3695,7 +3718,7 @@ int applyopt_sockopt(
 	}
 	break;
 #endif /* HAVE_STRUCT_LINGER */
-#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
+#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) )
 	case TYPE_IP_MREQN:
 		/* handled in applyopts_single */
 		break;
@@ -3815,6 +3838,9 @@ int applyopt_sockopt_generic(
 	return 0;
 }
 
+#endif /* _WITH_SOCKET */
+
+#if HAVE_FLOCK
 int applyopt_flock(
 	int fd,
 	struct opt *opt)
@@ -3826,6 +3852,7 @@ int applyopt_flock(
 	}
 	return 0;
 }
+#endif /* defined(HAVE_FLOCK) */
 
 /* Applies an option that needs handling specific to its OPT_* setting.
    Does not overwrite the option instance with ODESC_DONE or ODESC_ERROR,
@@ -3921,8 +3948,12 @@ int applyopt_spec(
 	{
 		struct passwd *pwd;
 		if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) {
-			Error1("getpwuid("F_uid"): no such user",
-			       opt->value.u_uidt);
+			if (errno != 0)
+				Error2("getpwuid("F_uid"): %s",
+				       opt->value.u_uidt, strerror(errno));
+			else
+				Error1("getpwuid("F_uid"): no such user",
+				       opt->value.u_uidt);
 			return -1;
 		}
 		if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) {
@@ -4216,7 +4247,7 @@ int applyopts_cloexec(int fd, struct opt *opts) {
 
    if (!opts)  return 0;
 
-   retropt_bool(opts, OPT_CLOEXEC, &docloexec);
+   retropt_bool(opts, OPT_O_CLOEXEC, &docloexec);
    if (docloexec) {
       if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) {
 	 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno));
@@ -4272,6 +4303,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) {
    case TYPE_CONST:
       *(int *)ptr = opt->desc->minor;
       break;
+#if WITH_IP4
    case TYPE_IP4NAME:
       memset(ptr, 0, sizeof(struct sockaddr_in));
       ((struct sockaddr_in *)ptr)->sin_addr   = opt->value.u_ip4addr;
@@ -4281,6 +4313,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) {
       memset(ptr, 0, sizeof(struct sockaddr_in));
       *(struct sockaddr_in *)ptr = opt->value.u_ip4sock;
       break;
+#endif /* WITH_IP4 */
    default:
       Error2("applyopt_offset(opt:%s): type %s not implemented",
 	     opt->desc->defname, xiohelp_opttypename(opt->desc->type));
@@ -4664,3 +4697,11 @@ int dumpopts(struct opt *opts)
 	}
 	return 0;
 }
+
+/* Better with type specific free function */
+void freeopts(
+	struct opt *opts)
+{
+   free(opts);
+   return;
+}
diff --git a/xioopts.h b/xioopts.h
index ef3b31c..1f32161 100644
--- a/xioopts.h
+++ b/xioopts.h
@@ -72,7 +72,7 @@ enum e_types {
 #if HAVE_STRUCT_LINGER
    TYPE_LINGER,		/* struct linger */
 #endif /* HAVE_STRUCT_LINGER */
-#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN
+#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) )
    TYPE_IP_MREQN,	/* for  struct ip_mreq  or  struct ip_mreqn */
 #endif
 #if HAVE_STRUCT_IP_MREQ_SOURCE
@@ -150,7 +150,7 @@ enum e_func {
 #define GROUP_NONE	0x00000000
 #define GROUP_ADDR	0x00000000 	/* options that apply to all addresses */
 
-#define GROUP_FD	0x00000001	/* everything applyable to a fd */
+#define GROUP_FD	0x00000001	/* everything applicable to a fd */
 #define GROUP_FIFO	0x00000002
 #define GROUP_CHR	0x00000004 	/* not yet used? */
 #define GROUP_BLK	0x00000008
@@ -272,7 +272,6 @@ enum e_optcode {
    OPT_CHROOT_EARLY,	/* chroot() before file system access */
    /*OPT_CIBAUD,*/		/* termios.c_cflag */
    OPT_CLOCAL,		/* termios.c_cflag */
-   OPT_CLOEXEC,
    OPT_CONNECT_TIMEOUT,	/* socket connect */
    OPT_COOL_WRITE,
    OPT_CR,		/* customized */
@@ -482,6 +481,9 @@ enum e_optcode {
    OPT_LOWPORT,
    OPT_MAX_CHILDREN,
 #if WITH_POSIXMQ
+   OPT_POSIXMQ_FLUSH,
+   OPT_POSIXMQ_MAXMSG,
+   OPT_POSIXMQ_MSGSIZE,
    OPT_POSIXMQ_PRIORITY,
 #endif
 #ifdef NLDLY
@@ -552,7 +554,8 @@ enum e_optcode {
    OPT_O_ASYNC,
 #endif
    OPT_O_BINARY,		/* Cygwin */
-   OPT_O_CREATE,
+   OPT_O_CLOEXEC,
+   OPT_O_CREAT,
 #ifdef O_DEFER
    OPT_O_DEFER,
 #endif
@@ -660,8 +663,10 @@ enum e_optcode {
    OPT_SETPGID,
    OPT_SETSID,
    OPT_SETSOCKOPT_BIN,
+   OPT_SETSOCKOPT_CONNECTED,
    OPT_SETSOCKOPT_INT,
    OPT_SETSOCKOPT_LISTEN,
+   OPT_SETSOCKOPT_SOCKET,
    OPT_SETSOCKOPT_STRING,
    OPT_SETUID,
    OPT_SETUID_EARLY,
@@ -1028,6 +1033,7 @@ extern groups_t _groupbits(mode_t mode);
 extern int dropopts(struct opt *opts, unsigned int phase);
 extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to);
 extern int dumpopts(struct opt *opts);
+extern void freeopts(struct opt *opts);
 
 #if HAVE_BASIC_UID_T==1
 #  define retropt_uid(o,c,r) retropt_short(o,c,r)
diff --git a/xioshutdown.c b/xioshutdown.c
index c1ec796..6af190e 100644
--- a/xioshutdown.c
+++ b/xioshutdown.c
@@ -10,6 +10,7 @@
 
 #include "xio-openssl.h"
 
+
 static pid_t socat_kill_pid;	/* here we pass the pid to be killed in sighandler */
 
 static void signal_kill_pid(int dummy) {
@@ -51,6 +52,7 @@ int xioshutdown(xiofile_t *sock, int how) {
 	       sock->stream.fd, strerror(errno));
       }
       return 0;
+#if _WITH_SOCKET
    case XIOSHUT_DOWN:
       result = Shutdown(sock->stream.fd, how);
       if (result < 0) {
@@ -70,7 +72,6 @@ int xioshutdown(xiofile_t *sock, int how) {
 	 return -1;
       }
       return 0;
-#if _WITH_SOCKET
    case XIOSHUT_NULL:
       writenull = '\0'; 	/* assign something to make gcc happy */
       /* send an empty packet; only useful on datagram sockets? */
diff --git a/xiowrite.c b/xiowrite.c
index 5388baf..c5885ad 100644
--- a/xiowrite.c
+++ b/xiowrite.c
@@ -50,7 +50,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
    switch (pipe->dtype & XIODATA_WRITEMASK) {
 
    case XIOWRITE_STREAM:
-      writt = writefull(pipe->fd, buff, bytes);
+      writt = writefull(pipe->fd, buff, bytes, NULL);
       if (writt < 0) {
 	 _errno = errno;
 	 switch (_errno) {
@@ -116,8 +116,10 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
    case XIOWRITE_PIPE:
       if (pipe->para.bipipe.socktype == SOCK_STREAM) {
 	 writt = Write(pipe->para.bipipe.fdout, buff, bytes);
+#if _WITH_SOCKET
       } else {
 	 writt = Send(pipe->para.bipipe.fdout, buff, bytes, 0);
+#endif /* _WITH_SOCKET */
       }
       _errno = errno;
       if (writt < 0) {