unsigned int mask;
uid_t uid;
gid_t gid;
- int fd, i;
+ int fd;
path = getenv(env);
if (path == NULL)
}
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));
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,
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;
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);
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) {
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);