unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob c5bd3611baaf64509477d04a6e5b3daacbffde87 3617 bytes (raw)
name: gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 
This patch is based on db2b1d9a8d4644ef892f47d84606ee96598d23fb
of http://anonscm.debian.org/cgit/collab-maint/netcat-openbsd.git

From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:43:56 +0800
Subject: connect timeout

---
 netcat.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/netcat.c b/netcat.c
index 9b2def2..f3cc8c1 100644
--- a/netcat.c
+++ b/netcat.c
@@ -106,6 +106,10 @@
 #define PORT_MAX_LEN	6
 #define UNIX_DG_TMP_SOCKET_SIZE	19

+#define CONNECTION_SUCCESS 0
+#define CONNECTION_FAILED 1
+#define CONNECTION_TIMEOUT 2
+
 /* Command Line Options */
 int	dflag;					/* detached, no stdin */
 unsigned int iflag;				/* Interval Flag */
@@ -151,6 +155,9 @@ void	set_common_sockopts(int);
 int	map_tos(char *, int *);
 void	usage(int);

+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+        socklen_t salen, int ctimeout);
+
 int
 main(int argc, char *argv[])
 {
@@ -651,11 +658,14 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)

 		set_common_sockopts(s);

-		if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
+                if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
 			break;
-		else if (vflag)
+		else if (vflag && error == CONNECTION_FAILED)
 			warn("connect to %s port %s (%s) failed", host, port,
 			    uflag ? "udp" : "tcp");
+                else if (vflag && error == CONNECTION_TIMEOUT)
+                    warn("connect to %s port %s (%s) timed out", host, port,
+                            uflag ? "udp" : "tcp");

 		close(s);
 		s = -1;
@@ -703,6 +713,69 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
 	return (ret);
 }

+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+		                socklen_t salen, int ctimeout)
+{
+	int err;
+	struct timeval tv, *tvp = NULL;
+	fd_set connect_fdset;
+	socklen_t len;
+	int orig_flags;
+
+	orig_flags = fcntl(fd, F_GETFL, 0);
+	if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0 ) {
+		warn("can't set O_NONBLOCK - timeout not available");
+		if (connect(fd, sa, salen) == 0)
+			return CONNECTION_SUCCESS;
+		else
+			return CONNECTION_FAILED;
+	}
+
+	/* set connect timeout */
+	if (ctimeout > 0) {
+		tv.tv_sec = (time_t)ctimeout/1000;
+		tv.tv_usec = 0;
+		tvp = &tv;
+	}
+
+	/* attempt the connection */
+	err = connect(fd, sa, salen);
+	if (err != 0 && errno == EINPROGRESS) {
+		/* connection is proceeding
+		 * it is complete (or failed) when select returns */
+
+		/* initialize connect_fdset */
+		FD_ZERO(&connect_fdset);
+		FD_SET(fd, &connect_fdset);
+
+		/* call select */
+		do {
+			err = select(fd + 1, NULL, &connect_fdset,
+				     NULL, tvp);
+		} while (err < 0 && errno == EINTR);
+
+		/* select error */
+		if (err < 0)
+			errx(1,"select error: %s", strerror(errno));
+		/* we have reached a timeout */
+		if (err == 0)
+			return CONNECTION_TIMEOUT;
+		/* select returned successfully, but we must test socket
+		 * error for result */
+		len = sizeof(err);
+		if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
+			errx(1, "getsockopt error: %s", strerror(errno));
+		/* setup errno according to the result returned by
+		 * getsockopt */
+		if (err != 0)
+			errno = err;
+	}
+
+	/* return aborted if an error occured, and valid otherwise */
+	fcntl(fd, F_SETFL, orig_flags);
+	return (err != 0)? CONNECTION_FAILED : CONNECTION_SUCCESS;
+}
+
 /*
  * local_listen()
  * Returns a socket listening on a local port, binds to specified source
--

debug log:

solving c5bd361 ...
found c5bd361 in https://yhetil.org/guix-devel/20160622110046.GA12755@shadowwalker/

applying [1/1] https://yhetil.org/guix-devel/20160622110046.GA12755@shadowwalker/
diff --git a/gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch b/gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch
new file mode 100644
index 0000000..c5bd361

1:45: space before tab in indent.
 		set_common_sockopts(s);
1:49: space before tab in indent.
 			break;
1:52: space before tab in indent.
 			warn("connect to %s port %s (%s) failed", host, port,
1:53: space before tab in indent.
 			    uflag ? "udp" : "tcp");
1:58: space before tab in indent.
 		close(s);
Checking patch gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch...
Applied patch gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch cleanly.
warning: squelched 2 whitespace errors
warning: 7 lines add whitespace errors.

skipping https://yhetil.org/guix-devel/20160622110046.GA12755@shadowwalker/ for c5bd361
index at:
100644 c5bd3611baaf64509477d04a6e5b3daacbffde87	gnu/packages/patches/netcat-openbsd-0002-connect-timeout.patch

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).