# HG changeset patch # User Timo Sirainen # Date 1222507226 -10800 # Node ID ec83f6dcb585f8174aa22d325f728d9a904c16df # Parent 2df7a88a545863d7cacf110c638c96bd095bef3c Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication. diff -r 2df7a88a5458 -r ec83f6dcb585 src/auth/main.c --- a/src/auth/main.c Wed Sep 24 23:33:59 2008 +0300 +++ b/src/auth/main.c Sat Sep 27 12:20:26 2008 +0300 @@ -101,7 +101,7 @@ unsigned int mask; uid_t uid; gid_t gid; - int fd, i; + int fd; path = getenv(env); if (path == NULL) @@ -117,23 +117,14 @@ } old_umask = umask(mask); - for (i = 0; i < 5; i++) { - fd = net_listen_unix(path, backlog); - if (fd != -1) - break; - - if (errno != EADDRINUSE) + fd = net_listen_unix_unlink_stale(path, backlog); + umask(old_umask); + if (fd == -1) { + if (errno == EADDRINUSE) + i_fatal("Socket already exists: %s", path); + else i_fatal("net_listen_unix(%s) failed: %m", path); - - /* see if it really exists */ - if (net_connect_unix(path) != -1 || errno != ECONNREFUSED) - i_fatal("Socket already exists: %s", path); - - /* delete and try again */ - if (unlink(path) < 0) - i_fatal("unlink(%s) failed: %m", path); } - umask(old_umask); user = getenv(t_strdup_printf("%s_USER", env)); group = getenv(t_strdup_printf("%s_GROUP", env)); diff -r 2df7a88a5458 -r ec83f6dcb585 src/dict/dict-server.c --- a/src/dict/dict-server.c Wed Sep 24 23:33:59 2008 +0300 +++ b/src/dict/dict-server.c Sat Sep 27 12:20:26 2008 +0300 @@ -521,27 +521,17 @@ 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) + server->fd = net_listen_unix_unlink_stale(path, 64); + if (server->fd == -1) { + if (errno == EADDRINUSE) + i_fatal("Socket already exists: %s", path); + else i_fatal("net_listen_unix(%s) failed: %m", path); - - /* see if it really exists */ - if (net_connect_unix(path) != -1 || errno != ECONNREFUSED) - i_fatal("Socket already exists: %s", path); - - /* delete and try again */ - if (unlink(path) < 0) - i_fatal("unlink(%s) failed: %m", path); } server->io = io_add(server->fd, IO_READ, diff -r 2df7a88a5458 -r ec83f6dcb585 src/lib/network.c --- a/src/lib/network.c Wed Sep 24 23:33:59 2008 +0300 +++ b/src/lib/network.c Sat Sep 27 12:20:26 2008 +0300 @@ -395,6 +395,33 @@ 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; diff -r 2df7a88a5458 -r ec83f6dcb585 src/lib/network.h --- a/src/lib/network.h Wed Sep 24 23:33:59 2008 +0300 +++ b/src/lib/network.h Sat Sep 27 12:20:26 2008 +0300 @@ -67,6 +67,10 @@ 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); diff -r 2df7a88a5458 -r ec83f6dcb585 src/lib/unix-socket-create.c --- a/src/lib/unix-socket-create.c Wed Sep 24 23:33:59 2008 +0300 +++ b/src/lib/unix-socket-create.c Sat Sep 27 12:20:26 2008 +0300 @@ -13,10 +13,8 @@ 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) { diff -r 2df7a88a5458 -r ec83f6dcb585 src/master/dict-process.c --- a/src/master/dict-process.c Wed Sep 24 23:33:59 2008 +0300 +++ b/src/master/dict-process.c Sat Sep 27 12:20:26 2008 +0300 @@ -114,37 +114,17 @@ 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);