service-listen.c revision 17f1cd4bc811e1ff7429d7fc45964fd2c119ea52
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "array.h"
#include "fd-set-nonblock.h"
#include "fd-close-on-exec.h"
#include "network.h"
#include "service.h"
#include "service-listen.h"
#include <unistd.h>
#include <fcntl.h>
static int service_unix_listener_listen(struct service_listener *l)
{
int fd, i;
for (i = 0;; i++) {
if (fd != -1)
break;
/* looks like the path doesn't exist. */
return 0;
}
if (errno != EADDRINUSE) {
return -1;
}
/* already in use - see if it really exists.
after 3 times just fail here. */
if (fd != -1)
return 0;
}
/* delete and try again */
return -1;
}
}
return -1;
}
}
return 1;
}
static int service_fifo_listener_listen(struct service_listener *l)
{
return -1;
}
if (fd == -1) {
return -1;
}
return -1;
}
}
return 1;
}
static int service_inet_listener_listen(struct service_listener *l)
{
int fd;
if (fd < 0) {
}
return 1;
}
{
struct service_listener *const *listeners;
unsigned int i, count;
for (i = 0; i < count; i++) {
continue;
case SERVICE_LISTENER_UNIX:
break;
case SERVICE_LISTENER_FIFO:
break;
case SERVICE_LISTENER_INET:
break;
}
}
return ret;
}
{
unsigned int i, count;
for (i = 0; i < count; i++) {
}
return ret;
}
const struct service_listener *l2)
{
return FALSE;
case SERVICE_LISTENER_UNIX:
case SERVICE_LISTENER_FIFO:
/* We could just keep using the same listener, but it's more
likely to cause problems if old process accepts a connection
before it knows that it should die. So just always unlink
return FALSE;
case SERVICE_LISTENER_INET:
return FALSE;
return FALSE;
return TRUE;
}
return FALSE;
}
struct service_list *old_service_list)
{
/* rescue anvil's UNIX socket listener */
break;
}
i_error("Can't change anvil's listeners on the fly");
return -1;
}
for (i = 0; i < new_count; i++) {
}
}
/* first create an arrays of all listeners to make things easier */
for (i = 0; i < count; i++)
for (i = 0; i < count; i++)
/* then start moving fds */
for (i = 0; i < new_count; i++) {
for (j = 0; j < old_count; j++) {
old_listeners[j])) {
break;
}
}
}
/* close what's left */
for (j = 0; j < old_count; j++) {
continue;
i_error("close(listener) failed: %m");
switch (old_listeners[j]->type) {
case SERVICE_LISTENER_UNIX:
case SERVICE_LISTENER_FIFO: {
const char *path =
break;
}
case SERVICE_LISTENER_INET:
break;
}
}
/* and let services_listen() deal with the remaining fds */
return services_listen(new_service_list);
}