]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Fixed crashing on deinit when listening on fifos.
authorTimo Sirainen <tss@iki.fi>
Wed, 3 Jun 2009 21:08:26 +0000 (17:08 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 3 Jun 2009 21:08:26 +0000 (17:08 -0400)
--HG--
branch : HEAD

src/lib-master/master-service.c

index 4e5fd48cb6a0d523f5bdf8a9f3b76a49d02a30cf..3c4c20764aa31a8b7265b2ee2d3fc2b2d16a197d 100644 (file)
@@ -403,10 +403,8 @@ void master_service_anvil_send(struct master_service *service, const char *cmd)
 
 void master_service_client_connection_destroyed(struct master_service *service)
 {
-       if (service->listeners == NULL) {
-               /* we can listen again */
-               io_listeners_add(service);
-       }
+       /* we can listen again */
+       io_listeners_add(service);
 
        i_assert(service->total_available_count > 0);
 
@@ -487,9 +485,14 @@ static void master_service_listen(struct master_service_listener *l)
                        return;
                }
                /* it's not a socket. probably a fifo. use the "listener"
-                  as the connection fd */
+                  as the connection fd and stop the listener. */
+               io_remove(&l->io);
+               conn.fd = dup(l->fd);
+               if (conn.fd == -1) {
+                       i_error("dup() failed: %m");
+                       return;
+               }
                io_remove(&l->io);
-               conn.fd = l->fd;
        }
        conn.ssl = l->ssl;
        net_set_nonblock(conn.fd, TRUE);
@@ -500,7 +503,7 @@ static void master_service_listen(struct master_service_listener *l)
         l->service->callback(&conn);
 }
 
-static void io_listeners_add(struct master_service *service)
+static void io_listeners_init(struct master_service *service)
 {
        unsigned int i;
 
@@ -515,14 +518,29 @@ static void io_listeners_add(struct master_service *service)
 
                l->service = service;
                l->fd = MASTER_LISTEN_FD_FIRST + i;
-               l->io = io_add(MASTER_LISTEN_FD_FIRST + i, IO_READ,
-                              master_service_listen, l);
 
                if (i >= service->socket_count - service->ssl_socket_count)
                        l->ssl = TRUE;
        }
 }
 
+static void io_listeners_add(struct master_service *service)
+{
+       unsigned int i;
+
+       if (service->listeners == NULL)
+               io_listeners_init(service);
+
+       for (i = 0; i < service->socket_count; i++) {
+               struct master_service_listener *l = &service->listeners[i];
+
+               if (l->io == NULL) {
+                       l->io = io_add(MASTER_LISTEN_FD_FIRST + i, IO_READ,
+                                      master_service_listen, l);
+               }
+       }
+}
+
 static void io_listeners_remove(struct master_service *service)
 {
        unsigned int i;
@@ -532,7 +550,6 @@ static void io_listeners_remove(struct master_service *service)
                        if (service->listeners[i].io != NULL)
                                io_remove(&service->listeners[i].io);
                }
-               i_free_and_null(service->listeners);
        }
 }