From c8c392050069f9a6b922ccd8ea8a4c71dda4a2c8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 14 Mar 2009 18:29:38 +0100 Subject: socket_util: added socket_bind_listen() Moved code from listen_add_address() (listen.c) to socket_util.c. --- src/socket_util.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src/socket_util.c') diff --git a/src/socket_util.c b/src/socket_util.c index 34111e90..d8a58f9a 100644 --- a/src/socket_util.c +++ b/src/socket_util.c @@ -20,17 +20,27 @@ #include "socket_util.h" #include "config.h" +#include +#include + #ifndef G_OS_WIN32 #include #include #else /* G_OS_WIN32 */ #include +#include #endif /* G_OS_WIN32 */ #ifdef HAVE_IPV6 #include #endif +static GQuark +listen_quark(void) +{ + return g_quark_from_static_string("listen"); +} + char * sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error) { @@ -79,3 +89,54 @@ sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error) return g_strconcat(host, ":", serv, NULL); } + +int +socket_bind_listen(int domain, int type, int protocol, + const struct sockaddr *address, size_t address_length, + int backlog, + GError **error) +{ + int fd, ret; + const int reuse = 1; +#ifdef HAVE_STRUCT_UCRED + int passcred = 1; +#endif + + fd = socket(domain, type, protocol); + if (fd < 0) { + g_set_error(error, listen_quark(), errno, + "Failed to create socket: %s", g_strerror(errno)); + return -1; + } + + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + &reuse, sizeof(reuse)); + if (ret < 0) { + g_set_error(error, listen_quark(), errno, + "setsockopt() failed: %s", g_strerror(errno)); + close(fd); + return -1; + } + + ret = bind(fd, address, address_length); + if (ret < 0) { + g_set_error(error, listen_quark(), errno, + "%s", strerror(errno)); + close(fd); + return -1; + } + + ret = listen(fd, backlog); + if (ret < 0) { + g_set_error(error, listen_quark(), errno, + "listen() failed: %s", g_strerror(errno)); + close(fd); + return -1; + } + +#ifdef HAVE_STRUCT_UCRED + setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &passcred, sizeof(passcred)); +#endif + + return fd; +} -- cgit v1.2.3