diff --git a/CHANGES b/CHANGES index 4baba3c..ecd8445 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +new features: + new address options shut-none, shut-down, and shut-close allow to + control socat's half close behaviour + ####################### V 1.7.0.1: corrections: diff --git a/doc/socat.yo b/doc/socat.yo index e06a908..870a87e 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1481,6 +1481,15 @@ label(OPTION_END_CLOSE)dit(bf(tt(end-close))) Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process. With this option, it will just close the file descriptors. +label(OPTION_SHUT_NONE)dit(bf(tt(shut-none))) + Changes the (address dependent) method of shutting down the write part of a + connection to not do anything. +label(OPTION_SHUT_DOWN)dit(bf(tt(shut-down))) + Changes the (address dependent) method of shutting down the write part of a + connection to tt(shutdown\(fd, SHUT_WR)). Is only useful with sockets. +label(OPTION_SHUT_CLOSE)dit(bf(tt(shut-close))) + Changes the (address dependent) method of shutting down the write part of a + connection to tt(close\(fd)). label(OPTION_IOCTL_VOID)dit(bf(tt(ioctl-void=))) Calls tt(ioctl()) with the request value as second argument and NULL as third argument. This option allows to utilize ioctls that are not diff --git a/xio-fd.c b/xio-fd.c index 53d6415..504babd 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -1,5 +1,5 @@ /* source: xio-fd.c */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains common file descriptor related option definitions */ @@ -75,6 +75,9 @@ const struct optdesc opt_cool_write = { "cool-write", "coolwrite", OPT_COOL_WRIT /* control closing of connections */ const struct optdesc opt_end_close = { "end-close", "close", OPT_END_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoend, END_CLOSE }; +const struct optdesc opt_shut_none = { "shut-none", NULL, OPT_SHUT_NONE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_NONE }; +const struct optdesc opt_shut_down = { "shut-down", NULL, OPT_SHUT_DOWN, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_DOWN }; +const struct optdesc opt_shut_close= { "shut-close", NULL, OPT_SHUT_CLOSE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_CLOSE }; /****** generic ioctl() options ******/ const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; diff --git a/xio-fd.h b/xio-fd.h index d664212..87a3d24 100644 --- a/xio-fd.h +++ b/xio-fd.h @@ -1,5 +1,5 @@ /* source: xio-fd.h */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_fd_h_included @@ -42,6 +42,9 @@ extern const struct optdesc opt_f_setlk_wr; extern const struct optdesc opt_f_setlkw_wr; extern const struct optdesc opt_cool_write; extern const struct optdesc opt_end_close; +extern const struct optdesc opt_shut_none; +extern const struct optdesc opt_shut_down; +extern const struct optdesc opt_shut_close; extern const struct optdesc opt_streams_i_push; #endif /* !defined(__xio_fd_h_included) */ diff --git a/xio.h b/xio.h index 8bc17ca..be7e46f 100644 --- a/xio.h +++ b/xio.h @@ -1,5 +1,5 @@ /* source: xio.h */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_h_included @@ -146,6 +146,12 @@ typedef struct single { bool opt_unlink_close; /* option unlink_close */ char *unlink_close; /* name of a symlink or unix socket to be removed */ int dtype; + enum { + XIOSHUT_UNSPEC, /* fall back to old (up to 1.7.0.0) behaviour */ + XIOSHUT_NONE, /* do nothing on shutdown */ + XIOSHUT_CLOSE, /* close the FD */ + XIOSHUT_DOWN /* shutdown() */ + } howtoshut; enum { END_UNSPEC, /* after init, when no end-close... option */ END_NONE, /* no action */ diff --git a/xioopts.c b/xioopts.c index a5578ee..67127c9 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1,5 +1,5 @@ /* source: xioopts.c */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for address options handling */ @@ -1313,6 +1313,9 @@ const struct optname optionnames[] = { IF_SOCKET ("setsockopt-string", &opt_setsockopt_string) IF_ANY ("setuid", &opt_setuid) IF_ANY ("setuid-early", &opt_setuid_early) + IF_ANY ("shut-close", &opt_shut_close) + IF_ANY ("shut-down", &opt_shut_down) + IF_ANY ("shut-none", &opt_shut_none) #if WITH_EXEC || WITH_SYSTEM IF_ANY ("sid", &opt_setsid) #endif diff --git a/xioopts.h b/xioopts.h index db61752..613ea24 100644 --- a/xioopts.h +++ b/xioopts.h @@ -1,5 +1,5 @@ /* source: xioopts.h */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioopts_h_included @@ -590,6 +590,9 @@ enum e_optcode { OPT_SETSOCKOPT_STRING, OPT_SETUID, OPT_SETUID_EARLY, + OPT_SHUT_CLOSE, + OPT_SHUT_DOWN, + OPT_SHUT_NONE, OPT_SIGHUP, OPT_SIGINT, OPT_SIGQUIT, diff --git a/xioshutdown.c b/xioshutdown.c index 30d3adf..a66bba5 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -1,5 +1,5 @@ /* source: xioshutdown.c */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended shutdown function */ @@ -31,9 +31,29 @@ int xioshutdown(xiofile_t *sock, int how) { if ((how+1)&2) { result |= xioshutdown((xiofile_t *)sock->dual.stream[1], 1); } + return result; + } + + switch (sock->stream.howtoshut) { + case XIOSHUT_NONE: + return 0; + case XIOSHUT_CLOSE: + if (Close(sock->stream.fd) < 0) { + Info2("close(%d): %s", + sock->stream.fd, strerror(errno)); + } + return 0; + case XIOSHUT_DOWN: + if ((result = Shutdown(sock->stream.fd, how)) < 0) { + Info3("shutdown(%d, %d): %s", + sock->stream.fd, how, strerror(errno)); + } + return 0; + default: ; + } #if WITH_OPENSSL - } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_OPENSSL) { + if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_OPENSSL) { sycSSL_shutdown (sock->stream.para.openssl.ssl); /*! what about half/full close? */ #endif /* WITH_OPENSSL */