From 332916804abc0addbb14ae523c8aab4622b8a3ba Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 18 Dec 2013 11:15:54 +0100 Subject: [PATCH] frontend: Clean up UNIX sockets when closing a listener. --- src/frontend/sock.c | 87 +++++++++++++++++++++++++----------------- t/frontend/sock_test.c | 4 +- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/frontend/sock.c b/src/frontend/sock.c index 27aa1c5..ce4c07c 100644 --- a/src/frontend/sock.c +++ b/src/frontend/sock.c @@ -68,6 +68,7 @@ typedef struct { const char *prefix; int (*opener)(listener_t *); + void (*closer)(listener_t *); } fe_listener_impl_t; struct sdb_fe_socket { @@ -121,6 +122,20 @@ open_unix_sock(listener_t *listener) return 0; } /* open_unix_sock */ +static void +close_unix_sock(listener_t *listener) +{ + assert(listener); + if (! listener->address) + return; + + if (listener->sock_fd >= 0) + close(listener->sock_fd); + listener->sock_fd = -1; + + unlink(listener->address + strlen("unix:")); +} /* close_unix_sock */ + /* * private variables */ @@ -131,13 +146,46 @@ enum { LISTENER_UNIXSOCK = 0, }; static fe_listener_impl_t listener_impls[] = { - { LISTENER_UNIXSOCK, "unix", open_unix_sock }, + { LISTENER_UNIXSOCK, "unix", open_unix_sock, close_unix_sock }, }; /* * private helper functions */ +static int +listener_listen(listener_t *listener) +{ + assert(listener); + + /* try to reopen */ + if (listener->sock_fd < 0) + if (listener_impls[listener->type].opener(listener)) + return -1; + assert(listener->sock_fd >= 0); + + if (listen(listener->sock_fd, /* backlog = */ 32)) { + char buf[1024]; + sdb_log(SDB_LOG_ERR, "frontend: Failed to listen on socket %s: %s", + listener->address, sdb_strerror(errno, buf, sizeof(buf))); + return -1; + } + return 0; +} /* listener_listen */ + +static void +listener_close(listener_t *listener) +{ + assert(listener); + + if (listener_impls[listener->type].closer) + listener_impls[listener->type].closer(listener); + + if (listener->sock_fd >= 0) + close(listener->sock_fd); + listener->sock_fd = -1; +} /* listener_close */ + static int get_type(const char *address) { @@ -169,12 +217,11 @@ listener_destroy(listener_t *listener) if (! listener) return; - if (listener->sock_fd >= 0) - close(listener->sock_fd); - listener->sock_fd = -1; + listener_close(listener); if (listener->address) free(listener->address); + listener->address = NULL; } /* listener_destroy */ static listener_t * @@ -223,38 +270,6 @@ listener_create(sdb_fe_socket_t *sock, const char *address) return listener; } /* listener_create */ -static int -listener_listen(listener_t *listener) -{ - assert(listener); - - /* try to reopen */ - if (listener->sock_fd < 0) - if (listener_impls[listener->type].opener(listener)) - return -1; - assert(listener->sock_fd >= 0); - - if (listen(listener->sock_fd, /* backlog = */ 32)) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "frontend: Failed to listen on socket %s: %s", - listener->address, sdb_strerror(errno, buf, sizeof(buf))); - return -1; - } - return 0; -} /* listener_listen */ - -static void -listener_close(listener_t *listener) -{ - assert(listener); - - if (listener->sock_fd < 0) - return; - - close(listener->sock_fd); - listener->sock_fd = -1; -} /* listener_close */ - static void socket_close(sdb_fe_socket_t *sock) { diff --git a/t/frontend/sock_test.c b/t/frontend/sock_test.c index 5579e36..36e7445 100644 --- a/t/frontend/sock_test.c +++ b/t/frontend/sock_test.c @@ -128,7 +128,9 @@ START_TEST(test_listen_and_serve) loop.do_loop = 0; pthread_join(thr, NULL); - unlink(tmp_file); + fail_unless(access(tmp_file, F_OK), + "sdb_fe_sock_listen_and_serve() did not clean up " + "socket %s", tmp_file); /* should do nothing and not report errors */ check = sdb_fe_sock_listen_and_serve(sock, &loop); -- 2.30.2