summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-11-23 16:49:22 -0500
committerJune McEnroe <june@causal.agency>2020-11-23 17:11:02 -0500
commit83dcb6f4856198b92431a0281922f26f0734ff56 (patch)
tree58392d12252615aead511c7f96157057b24120f9
parentClean up main loop loops (diff)
downloadpounce-83dcb6f4856198b92431a0281922f26f0734ff56.tar.gz
pounce-83dcb6f4856198b92431a0281922f26f0734ff56.zip
Unlink existing UNIX socket if it can't be connected to 2.1
I think this emulates SO_REUSEADDR, which for some reason doesn't work
on PF_UNIX. If the socket exists, check if connect(2) works, rather than
clobbering the socket being used by a still-running instance.
Diffstat (limited to '')
-rw-r--r--local.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/local.c b/local.c
index 21e7cb1..ff879c8 100644
--- a/local.c
+++ b/local.c
@@ -158,21 +158,37 @@ static void unixUnlink(void) {
 	if (error) warn("unlinkat");
 }
 
-size_t localUnix(int fds[], size_t cap, const char *path) {
-	if (!cap) return 0;
-
-	int sock = socket(PF_UNIX, SOCK_STREAM, 0);
-	if (sock < 0) err(EX_OSERR, "socket");
-
+static int unixBind(int sock, const char *path) {
 	struct sockaddr_un addr = { .sun_family = AF_UNIX };
-	int len = snprintf(
-		addr.sun_path, sizeof(addr.sun_path), "%s", path
-	);
+	int len = snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
 	if ((size_t)len >= sizeof(addr.sun_path)) {
 		errx(EX_CONFIG, "path too long: %s", path);
 	}
 
 	int error = bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr));
+	if (!error || errno != EADDRINUSE) return error;
+
+	int check = socket(PF_UNIX, SOCK_STREAM, 0);
+	if (check < 0) err(EX_OSERR, "socket");
+
+	error = connect(check, (struct sockaddr *)&addr, SUN_LEN(&addr));
+	close(check);
+	if (!error) {
+		errno = EADDRINUSE;
+		return -1;
+	}
+
+	unlink(path);
+	return bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr));
+}
+
+size_t localUnix(int fds[], size_t cap, const char *path) {
+	if (!cap) return 0;
+
+	int sock = socket(PF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0) err(EX_OSERR, "socket");
+
+	int error = unixBind(sock, path);
 	if (error) err(EX_UNAVAILABLE, "%s", path);
 
 	char dir[PATH_MAX] = ".";
@@ -227,8 +243,8 @@ int localAccept(struct tls **client, int bind) {
 
 	if (unix) {
 		int sent = recvfd(fd);
-		if (sent < 0) err(EX_IOERR, "recvfd");
 		close(fd);
+		if (sent < 0) return sent;
 		fd = sent;
 	}
 
ject'>Support monochromatic terminalsJune McEnroe Oops, division by zero! 2020-02-11Add .gz to chroot-man scriptJune McEnroe 2020-02-11Add -R restricted flagJune McEnroe 2020-02-11Add chroot targetJune McEnroe 2020-02-11Exit focus and paste modes on err exitJune McEnroe 2020-02-11Add startup GPLv3 note and URLJune McEnroe I am a degenerate. 2020-02-11Make sure -D_GNU_SOURCE ends up in CFLAGS on LinuxJune McEnroe 2020-02-11Add note about setting PKG_CONFIG_PATHJune McEnroe 2020-02-11Rename query ID on nick changeJune McEnroe 2020-02-11Call completeClear when closing a windowJune McEnroe 2020-02-11Don't insert color codes for non-mentionsJune McEnroe 2020-02-11Take first two words in colorMentionsJune McEnroe This lets phrases like "hi june" get colored, but still doesn't get carried away. 2020-02-11Use time_t for save signatureJune McEnroe It's actually more likely to be 64-bit than size_t anyway, and it eliminates some helper functions. Also don't error when reading an empty save file. 2020-02-11Set self.nick to * initiallyJune McEnroe Allows removing a bunch of checks that self.nick is set, and it's what the server usually calls you before registration. Never highlight notices as mentions. 2020-02-11Define ColorCap instead of hardcoding 100June McEnroe 2020-02-11Move hash to top of chat.hJune McEnroe 2020-02-11Move base64 out of chat.hJune McEnroe 2020-02-11Move XDG_SUBDIR out of chat.hJune McEnroe 2020-02-11Fix whois idle unit calculationJune McEnroe Rookie mistake. 2020-02-11Cast towupper to wchar_tJune McEnroe For some reason it takes and returns wint_t... 2020-02-11Cast set but unused variables to voidJune McEnroe 2020-02-11Declare strlcatJune McEnroe 2020-02-11Check if VDSUSP existsJune McEnroe 2020-02-11Fix completeReplace iterationJune McEnroe 2020-02-11Use pkg(8) to configure on FreeBSDJune McEnroe 2020-02-11Remove legacy codeJune McEnroe 2020-02-11Add INSTALLING section to READMEJune McEnroe