changeset 5432:2b4fa90860dd HEAD

Before unlinking auth sockets at startup, try connecting to them first to see if there's anyone listening (another Dovecot process). If there is, kill ourself.
author Timo Sirainen <tss@iki.fi>
date Mon, 26 Mar 2007 22:23:45 +0300
parents 712409f6d4d3
children 6f5ff9a7554f
files src/master/main.c src/master/master-settings.c
diffstat 2 files changed, 21 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/master/main.c	Mon Mar 26 19:59:06 2007 +0300
+++ b/src/master/main.c	Mon Mar 26 22:23:45 2007 +0300
@@ -56,7 +56,7 @@
 
 struct ioloop *ioloop;
 struct hash_table *pids;
-int null_fd, inetd_login_fd;
+int null_fd = -1, inetd_login_fd;
 uid_t master_uid;
 char program_path[PATH_MAX];
 char ssl_manual_key_password[100];
--- a/src/master/master-settings.c	Mon Mar 26 19:59:06 2007 +0300
+++ b/src/master/master-settings.c	Mon Mar 26 22:23:45 2007 +0300
@@ -494,10 +494,27 @@
 		if (lstat(str_c(str), &st) < 0) {
 			if (errno != ENOENT)
 				i_error("lstat(%s) failed: %m", str_c(str));
-		} else if (S_ISSOCK(st.st_mode)) {
-			if (unlink(str_c(str)) < 0 && errno != ENOENT)
-				i_error("unlink(%s) failed: %m", str_c(str));
+			continue;
 		}
+		if (!S_ISSOCK(st.st_mode))
+			continue;
+
+		/* try to avoid unlinking sockets if someone's already
+		   listening in them. do this only at startup, because
+		   when SIGHUPing a child process might catch the new
+		   connection before it notices that it's supposed
+		   to die. null_fd == -1 check is a bit kludgy, but works.. */
+		if (null_fd == -1) {
+			int fd = net_connect_unix(str_c(str));
+			if (fd != -1 || errno != ECONNREFUSED) {
+				i_fatal("Dovecot is already running? "
+					"Socket already exists: %s",
+					str_c(str));
+			}
+		}
+
+		if (unlink(str_c(str)) < 0 && errno != ENOENT)
+			i_error("unlink(%s) failed: %m", str_c(str));
 	}
 	(void)closedir(dirp);
 }