Print warning messages per default; new options -d0..-d4

This commit is contained in:
Gerhard Rieger 2023-06-14 11:14:46 +02:00
parent dc777a00bb
commit 557f299b82
17 changed files with 115 additions and 62 deletions

View file

@ -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:

View file

@ -541,7 +541,7 @@ if test -n "$WITH_OPENSSL"; then
[AC_TRY_COMPILE([#include <openssl/ssl.h>],[;],
[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"

View file

@ -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.

View file

@ -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;

View file

@ -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

28
socat.c
View file

@ -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

18
test.sh
View file

@ -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

View file

@ -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;
}

View file

@ -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 */

View file

@ -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) */

View file

@ -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;
}
}

View file

@ -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));

View file

@ -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() ->");

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;