]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
authorTimo Sirainen <tss@iki.fi>
Sat, 27 Sep 2008 09:20:26 +0000 (12:20 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 27 Sep 2008 09:20:26 +0000 (12:20 +0300)
--HG--
branch : HEAD

src/auth/main.c
src/dict/dict-server.c
src/lib/network.c
src/lib/network.h
src/lib/unix-socket-create.c
src/master/dict-process.c

index 6ac13ebda9dfafd9a99f48a9c2c46d2358e5bff1..a9b4872b95eb7645bc30089d498da6cbc29fc65e 100644 (file)
@@ -101,7 +101,7 @@ static int create_unix_listener(const char *env, int backlog)
        unsigned int mask;
        uid_t uid;
        gid_t gid;
-       int fd, i;
+       int fd;
 
        path = getenv(env);
        if (path == NULL)
@@ -117,23 +117,14 @@ static int create_unix_listener(const char *env, int backlog)
        }
 
        old_umask = umask(mask);
-       for (i = 0; i < 5; i++) {
-               fd = net_listen_unix(path, backlog);
-               if (fd != -1)
-                       break;
-
-               if (errno != EADDRINUSE)
-                       i_fatal("net_listen_unix(%s) failed: %m", path);
-
-               /* see if it really exists */
-               if (net_connect_unix(path) != -1 || errno != ECONNREFUSED)
+       fd = net_listen_unix_unlink_stale(path, backlog);
+       umask(old_umask);
+       if (fd == -1) {
+               if (errno == EADDRINUSE)
                        i_fatal("Socket already exists: %s", path);
-
-               /* delete and try again */
-               if (unlink(path) < 0)
-                       i_fatal("unlink(%s) failed: %m", path);
+               else
+                       i_fatal("net_listen_unix(%s) failed: %m", path);
        }
-       umask(old_umask);
 
        user = getenv(t_strdup_printf("%s_USER", env));
        group = getenv(t_strdup_printf("%s_GROUP", env));
index ca2bd56d5dc6ef99add50db5ce21086dc8cd3b28..2ac889fc85ec828ee5c1b051e74f0a5e4142e877 100644 (file)
@@ -521,27 +521,17 @@ static void dict_server_listener_accept(struct dict_server *server)
 struct dict_server *dict_server_init(const char *path, int fd)
 {
        struct dict_server *server;
-       int i= 0;
 
        server = i_new(struct dict_server, 1);
        server->path = i_strdup(path);
        server->fd = fd;
 
-       while (server->fd == -1) {
-               server->fd = net_listen_unix(path, 64);
-               if (server->fd != -1)
-                       break;
-
-               if (errno != EADDRINUSE || ++i == 2)
-                       i_fatal("net_listen_unix(%s) failed: %m", path);
-
-               /* see if it really exists */
-               if (net_connect_unix(path) != -1 || errno != ECONNREFUSED)
+       server->fd = net_listen_unix_unlink_stale(path, 64);
+       if (server->fd == -1) {
+               if (errno == EADDRINUSE)
                        i_fatal("Socket already exists: %s", path);
-
-               /* delete and try again */
-               if (unlink(path) < 0)
-                       i_fatal("unlink(%s) failed: %m", path);
+               else
+                       i_fatal("net_listen_unix(%s) failed: %m", path);
        }
 
        server->io = io_add(server->fd, IO_READ,
index 33617e9a4951b89ea479fbe35efbc25064db250e..577ab0114c62e31de93ba72bf7fdb4b3537b656b 100644 (file)
@@ -395,6 +395,33 @@ int net_listen_unix(const char *path, int backlog)
        return -1;
 }
 
+int net_listen_unix_unlink_stale(const char *path, int backlog)
+{
+       unsigned int i = 0;
+       int fd;
+
+       while ((fd = net_listen_unix(path, backlog)) == -1) {
+               if (errno != EADDRINUSE || ++i == 2)
+                       return -1;
+
+               /* see if it really exists */
+               fd = net_connect_unix(path);
+               if (fd != -1 || errno != ECONNREFUSED) {
+                       if (fd != -1) (void)close(fd);
+                       errno = EADDRINUSE;
+                       return -1;
+               }
+
+               /* delete and try again */
+               if (unlink(path) < 0 && errno != ENOENT) {
+                       i_error("unlink(%s) failed: %m", path);
+                       errno = EADDRINUSE;
+                       return -1;
+               }
+       }
+       return fd;
+}
+
 int net_accept(int fd, struct ip_addr *addr, unsigned int *port)
 {
        union sockaddr_union so;
index a72a685a50d9f92f6a6b0f11bdd9d66051f357b9..e4623d9bcef5da986953e00e802fad7d4b0204ec 100644 (file)
@@ -67,6 +67,10 @@ void net_get_ip_any6(struct ip_addr *ip);
 int net_listen(const struct ip_addr *my_ip, unsigned int *port, int backlog);
 /* Listen for connections on an UNIX socket */
 int net_listen_unix(const char *path, int backlog);
+/* Like net_listen_unix(), but if socket already exists, try to connect to it.
+   If it fails with ECONNREFUSED, unlink the socket and try creating it
+   again. */
+int net_listen_unix_unlink_stale(const char *path, int backlog);
 /* Accept a connection on a socket. Returns -1 if the connection got closed,
    -2 for other failures */
 int net_accept(int fd, struct ip_addr *addr, unsigned int *port);
index 1108ef83a7a349318a243c335c7de66b4ae38035..2d9e0ade09523122bc84d3be453a45cf0a649c44 100644 (file)
@@ -13,10 +13,8 @@ int unix_socket_create(const char *path, int mode,
        mode_t old_umask;
        int fd;
 
-       (void)unlink(path);
-
        old_umask = umask(0777 ^ mode);
-       fd = net_listen_unix(path, backlog);
+       fd = net_listen_unix_unlink_stale(path, backlog);
        umask(old_umask);
 
        if (fd < 0) {
index 3fec00cd8a74d569fa18affe4da0dc3a671c9f00..b85050b17f024b9d26b528dca203d860584549a2 100644 (file)
@@ -114,37 +114,17 @@ static void dict_process_listen_input(struct dict_process *process)
 static int dict_process_listen(struct dict_process *process)
 {
        mode_t old_umask;
-       int fd, i = 0;
-
-       for (;;) {
-               old_umask = umask(0);
-               process->fd = net_listen_unix(process->path, 64);
-               umask(old_umask);
-
-               if (process->fd != -1)
-                       break;
-
-               if (errno != EADDRINUSE || ++i == 2) {
-                       i_error("net_listen_unix(%s) failed: %m",
-                               process->path);
-                       return -1;
-               }
-
-               /* see if it really exists */
-               fd = net_connect_unix(process->path);
-               if (fd != -1 || errno != ECONNREFUSED) {
-                       if (fd != -1) (void)close(fd);
+
+       old_umask = umask(0);
+       process->fd = net_listen_unix_unlink_stale(process->path, 64);
+       umask(old_umask);
+       if (process->fd == -1) {
+               if (errno == EADDRINUSE)
                        i_error("Socket already exists: %s", process->path);
-                       return -1;
-               }
-
-               /* delete and try again */
-               if (unlink(process->path) < 0 && errno != ENOENT) {
-                       i_error("unlink(%s) failed: %m", process->path);
-                       return -1;
-               }
+               else
+                       i_error("net_listen_unix(%s) failed: %m", process->path);
+               return -1;
        }
-
        fd_close_on_exec(process->fd, TRUE);
        process->io = io_add(process->fd, IO_READ,
                             dict_process_listen_input, process);