From 557f299b82977bd350fcd97b82da4e901da4edc2 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 14 Jun 2023 11:14:46 +0200 Subject: [PATCH] Print warning messages per default; new options -d0..-d4 --- CHANGES | 6 ++++++ configure.ac | 2 +- doc/socat.yo | 15 +++++++++------ error.c | 6 ++++-- fdname.c | 6 +++--- socat.c | 28 ++++++++++++++++++++++++++-- test.sh | 18 ++++++++++++------ xio-listen.c | 2 +- xio-named.c | 24 ++++++++++++++++++++++++ xio-named.h | 2 ++ xio-pipe.c | 7 +------ xio-pty.c | 4 +--- xio-socket.c | 4 +++- xio-unix.c | 33 +++++++-------------------------- xioclose.c | 2 +- xioshutdown.c | 14 +++++++++++--- xiosigchld.c | 4 +++- 17 files changed, 115 insertions(+), 62 deletions(-) diff --git a/CHANGES b/CHANGES index 53f5063..dc9a590 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,12 @@ Features: Added the --experimental option that enables use of features that might change in the future. + Now warning messages are printed by default. If you want to see only + errors and fatals as in previous versions, use option -d0; + option -d4 is equivalent to -dddd and to -d -d -d -d + The number of warnings has been reduced, e.g.removing a non existing + file does in most cases no longer log a warning. + ####################### V 1.7.4.5 (not released): Corrections: diff --git a/configure.ac b/configure.ac index 693ab3d..f1457be 100644 --- a/configure.ac +++ b/configure.ac @@ -541,7 +541,7 @@ if test -n "$WITH_OPENSSL"; then [AC_TRY_COMPILE([#include ],[;], [sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE=""; ], [sc_cv_have_openssl_ssl_h=no - if [ "$OPENSSL_BASE" ]; then + if test "$OPENSSL_BASE"; then Ds="$OPENSSL_BASE" else Ds="/sw /usr/local /opt/freeware /usr/sfw /usr/local/ssl" diff --git a/doc/socat.yo b/doc/socat.yo index 02a70c0..6a6619a 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -109,12 +109,15 @@ dit(bf(tt(-hh | -??))) dit(bf(tt(-hhh | -???))) Like -hh, plus a list of all available address option names. label(option_d)dit(bf(tt(-d))) - Without this option, only fatal and error messages are generated; applying - this option also prints warning messages. See link(DIAGNOSTICS)(DIAGNOSTICS) - for more information. -label(option_d_d)dit(bf(tt(-d -d))) Prints fatal, error, warning, and notice messages. -dit(bf(tt(-d -d -d))) Prints fatal, error, warning, notice, and info messages. -dit(bf(tt(-d -d -d -d))) Prints fatal, error, warning, notice, info, and debug + Without this option, only fatal, error, and warning messages are printed; + applying this option also prints notice messages. + See link(DIAGNOSTICS)(DIAGNOSTICS) for more information. +label(option_d0)dit(bf(tt(-d0))) + With this option, only fatal and error messages are printed; this restores + the behaviour of socat() up to version 1.7.4. +label(option_d_d)dit(bf(tt(-d -d | -dd | -d2))) Prints fatal, error, warning, and notice messages. +dit(bf(tt(-d -d -d | -ddd | -d3))) Prints fatal, error, warning, notice, and info messages. +dit(bf(tt(-d -d -d -d | -dddd | -d4))) Prints fatal, error, warning, notice, info, and debug messages. dit(bf(tt(-D))) Logs information about file descriptors before starting the transfer phase. diff --git a/error.c b/error.c index bb3f91d..863f4d8 100644 --- a/error.c +++ b/error.c @@ -45,7 +45,7 @@ static void _diag_exit(int status); struct diag_opts diagopts = - { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0, false, NULL, true } ; + { NULL, E_WARN, E_ERROR, 0, NULL, LOG_DAEMON, false, 0, false, NULL, true } ; static void msg2( #if HAVE_CLOCK_GETTIME @@ -194,7 +194,6 @@ void diag_set(char what, const char *arg) { case 'p': diagopts.progname = arg; openlog(diagopts.progname, LOG_PID, diagopts.logfacility); break; - case 'd': --diagopts.msglevel; break; case 'u': diagopts.micros = true; break; default: msg(E_ERROR, "unknown diagnostic option %c", what); } @@ -206,6 +205,9 @@ void diag_set_int(char what, int arg) { case 'D': diagopts.msglevel = arg; break; case 'e': diagopts.exitlevel = arg; break; case 'x': diagopts.exitstatus = arg; break; + case 'd': + diagopts.msglevel = arg; + break; case 'h': diagopts.withhostname = arg; if ((diagopts.hostname = getenv("HOSTNAME")) == NULL) { struct utsname ubuf; diff --git a/fdname.c b/fdname.c index d827a94..438490e 100644 --- a/fdname.c +++ b/fdname.c @@ -99,8 +99,8 @@ static int procgetfdname(int fd, char *filepath, size_t pathsize) { #endif "/%d", pid, fd); if ((len = Readlink(procpath, filepath, pathsize-1)) < 0) { - Warn4("readlink(\"%s\", %p, "F_Zu"): %s", - procpath, filepath, pathsize, strerror(errno)); + Notice4("readlink(\"%s\", %p, "F_Zu"): %s", + procpath, filepath, pathsize, strerror(errno)); len = 0; } filepath[len] = '\0'; @@ -260,7 +260,7 @@ int sockname(int fd, FILE *outfile, char style) { rc = Getsockopt(fd, SOL_SOCKET, SO_PROTOTYPE, &proto, &optlen); #endif if (rc < 0) { - Warn5("getsocktop(%d, SOL_SOCKET, " + Notice5("getsocktop(%d, SOL_SOCKET, " #ifdef SO_PROTOCOL "SO_PROTOCOL" #else diff --git a/socat.c b/socat.c index 664dc37..78c895c 100644 --- a/socat.c +++ b/socat.c @@ -93,6 +93,7 @@ int main(int argc, const char *argv[]) { double rto; int i, argc0, result; bool isdash = false; + int msglevel = 0; struct utsname ubuf; int lockrc; @@ -124,10 +125,32 @@ int main(int argc, const char *argv[]) { Exit(0); #endif /* WITH_HELP */ case 'd': - a = *arg1+1; + a = *arg1+2; + switch (*a) { + case 'd': + break; + case '-': case '0': case '1': case '2': case '3': case '4': + { + char *endptr; + msglevel = strtol(a, &endptr, 0); + if (endptr == a || *endptr) { + Error2("Invalid (trailing) character(s) \"%c\" in \"%s\"option", *a, *arg1); + } + diag_set_int('d', 4-msglevel); + } + break; + case '\0': + ++msglevel; + diag_set_int('d', 4-msglevel); + break; + default: socat_usage(stderr); + } + if (*a != 'd') break; + ++msglevel; while (*a) { if (*a == 'd') { - diag_set('d', NULL); + ++msglevel; + diag_set_int('d', 4-msglevel); } else { socat_usage(stderr); Exit(1); @@ -394,6 +417,7 @@ void socat_usage(FILE *fd) { fputs(" -hhh like -hh, plus a list of all available address option names\n", fd); #endif /* WITH_HELP */ fputs(" -d[ddd] increase verbosity (use up to 4 times; 2 are recommended)\n", fd); + fputs(" -d0|1|2|3|4 set verbosity level (0: Errors; 4 all including Debug)\n", fd); #if WITH_FILAN fputs(" -D analyze file descriptors before loop\n", fd); #endif diff --git a/test.sh b/test.sh index 44e6c7b..93ea5c8 100755 --- a/test.sh +++ b/test.sh @@ -6545,7 +6545,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" "$TEST" "" EXEC:"$OD_C" "$opts -u" esac N=$((N+1)) @@ -6554,7 +6554,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" "$TEST" EXEC:"$OD_C" "-" "$opts -U" esac N=$((N+1)) @@ -12336,7 +12336,7 @@ if [ $RLIMIT_NOFILE -gt 1024 ]; then RLIMIT_NOFILE="$(ulimit -n)" fi newport tcp4 -CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE" +CMD0="$TRACE $SOCAT -d0 $opts TCP-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE" CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT,bind=$SECONDADDR" CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT,bind=$LOCALHOST" printf "test $F_n $TEST... " $N @@ -12359,6 +12359,12 @@ if [ $rc2 -ne 0 ]; then listFAIL="$listFAIL $N" elif [ -f "$tdiff" -a ! -s "$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 + if [ "$VERBOSE" ]; then echo "$CMD2"; fi + if [ "$DEBUG" ]; then cat "${te}2" >&2; fi numOK=$((numOK+1)) else $PRINTF "$FAILED\n" @@ -15653,7 +15659,7 @@ N=$((N+1)) NAME=INTEGER_GARBAGE case "$TESTS" in *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*) -TEST="$NAME: Error on trailing garbabe" +TEST="$NAME: Error on trailing garbage" # Invoke Socat with pty and option ispeed=b19200. # When socat terminates with error the test succeeded if ! eval $NUMCOND; then :; else @@ -15993,7 +15999,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$TRACE $SOCAT $opts - EXEC:\"$FILAN -s\",stderr" +CMD="$TRACE $SOCAT $opts - EXEC:\"$FILAN -s\"" printf "test $F_n $TEST... " $N eval "$CMD" >"${tf}" 2>"${te}" # "door" is a special FD type on Solaris/SunOS @@ -16039,7 +16045,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$TRACE $SOCAT $opts -r $td/test$N.-r -R $td/test$N.-R - EXEC:\"$FILAN -s\",stderr" +CMD="$TRACE $SOCAT $opts -r $td/test$N.-r -R $td/test$N.-R - EXEC:\"$FILAN -s\"" printf "test $F_n $TEST... " $N eval "$CMD" >"${tf}" 2>"${te}" # "door" is a special FD type on Solaris/SunOS diff --git a/xio-listen.c b/xio-listen.c index 9cbf818..83a5f0b 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -306,7 +306,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl } while (true); applyopts_cloexec(ps, opts); if (Getpeername(ps, &pa->soa, &pas) < 0) { - Warn4("getpeername(%d, %p, {"F_socklen"}): %s", + Notice4("getpeername(%d, %p, {"F_socklen"}): %s", ps, pa, pas, strerror(errno)); pa = NULL; } diff --git a/xio-named.c b/xio-named.c index a9c306f..6e35d3e 100644 --- a/xio-named.c +++ b/xio-named.c @@ -59,9 +59,12 @@ int applyopts_named(const char *filename, struct opt *opts, unsigned int phase) break; case OPT_UNLINK_EARLY: case OPT_UNLINK: + xio_unlink(filename, E_ERROR); + break; case OPT_UNLINK_LATE: if (Unlink(filename) < 0) { if (errno == ENOENT) { + /* We have just created/opened it, that's - surprising! */ Warn2("unlink(\"%s\"): %s", filename, strerror(errno)); } else { Error2("unlink(\"%s\"): %s", filename, strerror(errno)); @@ -209,4 +212,25 @@ int _xioopen_open(const char *path, int rw, struct opt *opts) { return fd; } +/* Wrapper around Unlink() that handles the case of non existing file (ENOENT) + just as E_INFO. All other errors are handled with level. */ +int xio_unlink( + const char *filename, /* the file to be removed */ + int level) /* the severity level for other errors, e.g.E_ERROR */ +{ + int _errno; + + if (Unlink(filename) < 0) { + _errno = errno; + if (errno == ENOENT) { + Info2("unlink(\"%s\"): %s", filename, strerror(errno)); + } else { + Msg2(level, "unlink(\"%s\"): %s", filename, strerror(errno)); + errno = _errno; + return -1; + } + } + return 0; +} + #endif /* _WITH_NAMED */ diff --git a/xio-named.h b/xio-named.h index 167da7c..561d192 100644 --- a/xio-named.h +++ b/xio-named.h @@ -23,4 +23,6 @@ extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, bool *exists, struct opt *opts); extern int _xioopen_open(const char *path, int rw, struct opt *opts); +extern int xio_unlink(const char *pathname, int level); + #endif /* !defined(__xio_named_h_included) */ diff --git a/xio-pipe.c b/xio-pipe.c index 14e19f3..f8862a7 100644 --- a/xio-pipe.c +++ b/xio-pipe.c @@ -105,12 +105,7 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof if (opt_unlink_early) { if (Unlink(pipename) < 0) { - if (errno == ENOENT) { - Warn2("unlink(%s): %s", pipename, strerror(errno)); - } else { - Error2("unlink(%s): %s", pipename, strerror(errno)); - return STAT_RETRYLATER; - } + return STAT_RETRYLATER; } } diff --git a/xio-pty.c b/xio-pty.c index 88a8782..41058c7 100644 --- a/xio-pty.c +++ b/xio-pty.c @@ -149,9 +149,7 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl #endif /* HAVE_OPENPTY */ if (!retropt_string(opts, OPT_SYMBOLIC_LINK, &linkname)) { - if (Unlink(linkname) < 0 && errno != ENOENT) { - Error2("unlink(\"%s\"): %s", linkname, strerror(errno)); - } + xio_unlink(linkname, E_ERROR); if (Symlink(ptyname, linkname) < 0) { Error3("symlink(\"%s\", \"%s\"): %s", ptyname, linkname, strerror(errno)); diff --git a/xio-socket.c b/xio-socket.c index 8f14269..23dec0d 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1132,8 +1132,10 @@ void xiosigaction_hasread(int signum diag_in_handler = 0; errno = _errno; return; + } else if (pid < 0 && errno == EINTR) { + Info1("xiosigaction_hasread(): %s", strerror(errno)); } else if (pid < 0 && errno == ECHILD) { - Msg(wassig?E_INFO:E_WARN, + Msg(wassig?E_INFO:E_NOTICE, "waitpid(-1, {}, WNOHANG): "F_strerror); Info("xiosigaction_hasread() finished"); Debug("xiosigaction_hasread() ->"); diff --git a/xio-unix.c b/xio-unix.c index 683f5b5..7229de9 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -157,13 +157,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); - } - } + xio_unlink(name, E_ERROR); } else { struct stat buf; if (Lstat(name, &buf) == 0) { @@ -463,13 +457,7 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); - } - } + xio_unlink(name, E_ERROR); } else { struct stat buf; if (Lstat(name, &buf) == 0) { @@ -550,13 +538,7 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); - } - } + xio_unlink(name, E_ERROR); } else { struct stat buf; if (Lstat(name, &buf) == 0) { @@ -668,7 +650,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, if (errno != EPROTOTYPE || socktype != 0) break; if (needbind) - Unlink(us.un.sun_path); + xio_unlink(us.un.sun_path, E_ERROR); dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; socktype = SOCK_SEQPACKET; @@ -682,7 +664,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/) break; if (needbind) - Unlink(us.un.sun_path); + xio_unlink(us.un.sun_path, E_ERROR); dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; xfd->peersa = them; @@ -699,9 +681,8 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, if (result != 0) { Error2("UNIX-CLIENT:%s: %s", name, strerror(errno)); - if (needbind) { - Unlink(us.un.sun_path); - } + if (needbind) + xio_unlink(us.un.sun_path, E_ERROR); return result; } diff --git a/xioclose.c b/xioclose.c index 4c56d2a..fe3dd1f 100644 --- a/xioclose.c +++ b/xioclose.c @@ -88,7 +88,7 @@ int xioclose1(struct single *pipe) { } if (pipe->opt_unlink_close && pipe->unlink_close) { if (Unlink(pipe->unlink_close) < 0) { - Info2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno)); + Warn2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno)); } free(pipe->unlink_close); } diff --git a/xioshutdown.c b/xioshutdown.c index ed99e01..ae004a6 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -112,6 +112,9 @@ int xioshutdown(xiofile_t *sock, int how) { sock->stream.fd, how, strerror(errno)); } if ((sock->stream.flags&XIO_ACCMODE) == XIO_WRONLY) { + pid_t pid; + int level; + /* the child process might want to flush some data before terminating */ int status = 0; @@ -133,9 +136,14 @@ int xioshutdown(xiofile_t *sock, int how) { #else Alarm(1 /*! sock->stream.para.exec.waitdie */); #endif /* !HAVE_SETITIMER */ - if (Waitpid(sock->stream.para.exec.pid, &status, 0) < 0) { - Warn3("waitpid("F_pid", %p, 0): %s", - sock->stream.para.exec.pid, &status, strerror(errno)); + pid = Waitpid(sock->stream.para.exec.pid, &status, 0); + if (pid < 0) { + if (errno == EINTR) + level = E_INFO; + else + level = E_WARN; + Msg3(level, "waitpid("F_pid", %p, 0): %s", + sock->stream.para.exec.pid, &status, strerror(errno)); } Alarm(0); } diff --git a/xiosigchld.c b/xiosigchld.c index d09947f..ca88f63 100644 --- a/xiosigchld.c +++ b/xiosigchld.c @@ -92,8 +92,10 @@ void childdied(int signum) { diag_in_handler = 0; errno = _errno; return; + } else if (pid < 0 && errno == EINTR) { + Info1("childdied(): %s", strerror(errno)); } else if (pid < 0 && errno == ECHILD) { - Msg(wassig?E_INFO:E_WARN, + Msg(wassig?E_INFO:E_NOTICE, "waitpid(-1, {}, WNOHANG): "F_strerror); Info("childdied() finished"); diag_in_handler = 0;