Recently Written · git

sacc

Mirror of git://bitreich.org/sacc, the sacc gopher client from bitreich.org.

git clone https://github.com/equwal/sacc

Log | Files | Refs


commit dba0b8d682e77ac33fbdc6f75dee9ee9f08553f9
Hiltjo Posthuma <hiltjo@codemadness.org>
2018-12-25 20:44:18 +0100

mask signals while using connect(2) in connectto()

This makes sure connect(2) don't return a possible < 0 and errno = EINTR.

POSIX says for connect(2): "
[EINTR]         The connection attempt was interrupted by a signal.
                The attempt will continue asynchronously as if the
                socket was non-blocking."

This was reproducable by launching with st -e sacc bitreich.org . When sacc was
signaled with SIGWINCH while it was connecting the connect(2) would be handled
as a failure and the next interface was tried. This gave a vague message "no
route to host", because the next interfaces could fail.

 sacc.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/sacc.c b/sacc.c
index 7a68bb9..72e98fe 100644
--- a/sacc.c
+++ b/sacc.c
@@ -454,6 +454,7 @@ sendselector(int sock, const char *selector)
 static int
 connectto(const char *host, const char *port)
 {
+	sigset_t set, oset;
 	static const struct addrinfo hints = {
 	    .ai_family = AF_UNSPEC,
 	    .ai_socktype = SOCK_STREAM,
@@ -462,10 +463,13 @@ connectto(const char *host, const char *port)
 	struct addrinfo *addrs, *addr;
 	int sock, r;
 
+	sigfillset(&set);
+	sigprocmask(SIG_BLOCK, &set, &oset);
+
 	if (r = getaddrinfo(host, port, &hints, &addrs)) {
 		diag("Can't resolve hostname \"%s\": %s",
 		     host, gai_strerror(r));
-		return -1;
+		goto err;
 	}
 
 	for (addr = addrs; addr; addr = addr->ai_next) {
@@ -483,15 +487,20 @@ connectto(const char *host, const char *port)
 
 	if (sock < 0) {
 		diag("Can't open socket: %s", strerror(errno));
-		return -1;
+		goto err;
 	}
 	if (r < 0) {
 		diag("Can't connect to: %s:%s: %s",
 		     host, port, strerror(errno));
-		return -1;
+		goto err;
 	}
 
+	sigprocmask(SIG_SETMASK, &oset, NULL);
 	return sock;
+
+err:
+	sigprocmask(SIG_SETMASK, &oset, NULL);
+	return -1;
 }
 
 static int