diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2011-10-04 08:34:35 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2011-10-04 08:34:35 +0000 |
commit | 2cec946c0ba6f35dcb74e2da92353821e8b12132 (patch) | |
tree | 5db0fd32177c0b961a363df09750ba5d0a65b98b | |
parent | 22d59143b24c68530a21ef23cc3558ea72dab438 (diff) |
change -w to apply to the connection as well. manpage bit from jmc@
nicm@ ok.
-rw-r--r-- | usr.bin/nc/nc.1 | 8 | ||||
-rw-r--r-- | usr.bin/nc/netcat.c | 42 |
2 files changed, 44 insertions, 6 deletions
diff --git a/usr.bin/nc/nc.1 b/usr.bin/nc/nc.1 index 6a1538cb456..d249aa18b11 100644 --- a/usr.bin/nc/nc.1 +++ b/usr.bin/nc/nc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.58 2011/09/17 14:10:05 haesbaert Exp $ +.\" $OpenBSD: nc.1,v 1.59 2011/10/04 08:34:34 fgsch Exp $ .\" .\" Copyright (c) 1996 David Sacerdote .\" All rights reserved. @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: September 17 2011 $ +.Dd $Mdocdate: October 4 2011 $ .Dt NC 1 .Os .Sh NAME @@ -210,9 +210,9 @@ Have .Nm give more verbose output. .It Fl w Ar timeout -If a connection and stdin are idle for more than +Connections which cannot be established or are idle timeout after .Ar timeout -seconds, then the connection is silently closed. +seconds. The .Fl w flag has no effect on the diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c index 952bfb7dda0..7880c7f452a 100644 --- a/usr.bin/nc/netcat.c +++ b/usr.bin/nc/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.102 2011/09/17 14:10:05 haesbaert Exp $ */ +/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * @@ -98,6 +98,7 @@ void help(void); int local_listen(char *, char *, struct addrinfo); void readwrite(int); int remote_connect(const char *, const char *, struct addrinfo); +int timeout_connect(int, const struct sockaddr *, socklen_t); int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); int udptest(int); @@ -590,7 +591,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) set_common_sockopts(s); - if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) + if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; else if (vflag) warn("connect to %s port %s (%s) failed", host, port, @@ -605,6 +606,43 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) return (s); } +int +timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct pollfd pfd; + socklen_t optlen; + int flags, optval; + int ret; + + if (timeout != -1) { + flags = fcntl(s, F_GETFL, 0); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) + err(1, "set non-blocking mode"); + } + + if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { + pfd.fd = s; + pfd.events = POLLOUT; + if ((ret = poll(&pfd, 1, timeout)) == 1) { + optlen = sizeof(optval); + if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, + &optval, &optlen)) == 0) { + errno = optval; + ret = optval == 0 ? 0 : -1; + } + } else if (ret == 0) { + errno = ETIMEDOUT; + ret = -1; + } else + err(1, "poll failed"); + } + + if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) + err(1, "restoring flags"); + + return (ret); +} + /* * local_listen() * Returns a socket listening on a local port, binds to specified source |