From 42e20ed2784d4a34bbc87f63e4e4d7c0db29ac3b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 21 Jun 2024 12:45:06 +0200 Subject: [PATCH] -T 0 now means 0.0s instead of no timeout --- CHANGES | 4 ++++ doc/socat.yo | 6 ++++-- socat.c | 22 ++++++++++++---------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 0280e7c..a1b42a9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@  +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. + Testing: test.sh: lots of corrections and improvements diff --git a/doc/socat.yo b/doc/socat.yo index 7266dfd..bf60b42 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -197,9 +197,11 @@ label(option_t)dit(bf(tt(-t))tt()) the timeout interval the read part gives EOF, socat terminates without awaiting the timeout. label(option_T)dit(bf(tt(-T))tt()) - Total inactivity timeout: when socat is already in the transfer loop and + Total inactivity timeout: when socat() is already in the transfer loop and nothing has happened for [link(timeval)(TYPE_TIMEVAL)] seconds - (no data arrived, no interrupt occurred...) then it terminates. + (no data arrived, no interrupt occurred...) then it terminates. Up to + version 1.8.0.0 "0" meant infinite"; since version 1.8.0.1 "0" means 0 + and values <0 mean infinite.nl() Useful with protocols like UDP that cannot transfer EOF. label(option_u)dit(bf(tt(-u))) Uses unidirectional mode. The first address is only used for reading, and the diff --git a/socat.c b/socat.c index e98ecc2..f5d4393 100644 --- a/socat.c +++ b/socat.c @@ -45,7 +45,7 @@ struct socat_opts { false, /* verbhex */ {1,0}, /* pollintv */ {0,500000}, /* closwait */ - {0,0}, /* total_timeout */ + {0,1000000}, /* total_timeout (this invalid default means no timeout)*/ 0, /* debug */ 0, /* strictopts */ 's', /* logopt */ @@ -274,9 +274,14 @@ int main(int argc, const char *argv[]) { } } rto = Strtod(a, (char **)&a, "-T"); - socat_opts.total_timeout.tv_sec = rto; - socat_opts.total_timeout.tv_usec = - (rto-socat_opts.total_timeout.tv_sec) * 1000000; + if (rto < 0) { + socat_opts.total_timeout.tv_sec = 0; /* infinite */ + socat_opts.total_timeout.tv_usec = 1000000; /* by invalid */ + } else { + socat_opts.total_timeout.tv_sec = rto; + socat_opts.total_timeout.tv_usec = + (rto-socat_opts.total_timeout.tv_sec) * 1000000; + } break; case 'u': if (arg1[0][2]) { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); } socat_opts.lefttoright = true; break; @@ -992,8 +997,7 @@ int _socat(void) { /* for ignoreeof */ if (polling) { if (!wasaction) { - if (socat_opts.total_timeout.tv_sec != 0 || - socat_opts.total_timeout.tv_usec != 0) { + 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; @@ -1017,8 +1021,7 @@ int _socat(void) { /* there is a ignoreeof poll timeout, use it */ timeout = socat_opts.pollintv; to = &timeout; - } else if (socat_opts.total_timeout.tv_sec != 0 || - socat_opts.total_timeout.tv_usec != 0) { + } else if (socat_opts.total_timeout.tv_usec < 1000000) { /* there might occur a total inactivity timeout */ timeout = socat_opts.total_timeout; to = &timeout; @@ -1134,8 +1137,7 @@ int _socat(void) { } else if (polling && wasaction) { wasaction = 0; - } else if (socat_opts.total_timeout.tv_sec != 0 || - socat_opts.total_timeout.tv_usec != 0) { + } else if (socat_opts.total_timeout.tv_usec < 1000000) { /* there was a total inactivity timeout */ Notice("inactivity timeout triggered"); free(buff);