diff options
author | Max Kellermann <max@duempel.org> | 2009-03-14 18:29:38 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-03-14 18:29:38 +0100 |
commit | c8c392050069f9a6b922ccd8ea8a4c71dda4a2c8 (patch) | |
tree | 37aedc11cd4fc5a7a77fe7e0cb93835a33e2520b /src | |
parent | dccb973cfef9664644e4945fbddedb3eee8c215b (diff) | |
download | mpd-c8c392050069f9a6b922ccd8ea8a4c71dda4a2c8.tar.gz mpd-c8c392050069f9a6b922ccd8ea8a4c71dda4a2c8.tar.xz mpd-c8c392050069f9a6b922ccd8ea8a4c71dda4a2c8.zip |
socket_util: added socket_bind_listen()
Moved code from listen_add_address() (listen.c) to socket_util.c.
Diffstat (limited to 'src')
-rw-r--r-- | src/listen.c | 45 | ||||
-rw-r--r-- | src/socket_util.c | 61 | ||||
-rw-r--r-- | src/socket_util.h | 20 |
3 files changed, 85 insertions, 41 deletions
diff --git a/src/listen.c b/src/listen.c index 4b0326264..e4d8ea796 100644 --- a/src/listen.c +++ b/src/listen.c @@ -18,6 +18,7 @@ */ #include "listen.h" +#include "socket_util.h" #include "client.h" #include "conf.h" #include "utils.h" @@ -45,8 +46,6 @@ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "listen" -#define ALLOW_REUSE 1 - #define DEFAULT_PORT 6600 struct listen_socket { @@ -73,49 +72,13 @@ static bool listen_add_address(int pf, const struct sockaddr *addrp, socklen_t addrlen, GError **error) { - int fd, ret; - const int reuse = ALLOW_REUSE; -#ifdef HAVE_STRUCT_UCRED - int passcred = 1; -#endif + int fd; struct listen_socket *ls; GIOChannel *channel; - fd = socket(pf, SOCK_STREAM, 0); - if (fd < 0) { - g_set_error(error, listen_quark(), errno, - "Failed to create socket: %s", strerror(errno)); + fd = socket_bind_listen(pf, SOCK_STREAM, 0, addrp, addrlen, 5, error); + if (fd < 0) return false; - } - - ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - &reuse, sizeof(reuse)); - if (ret < 0) { - g_set_error(error, listen_quark(), errno, - "setsockopt() failed: %s", strerror(errno)); - close(fd); - return false; - } - - ret = bind(fd, addrp, addrlen); - if (ret < 0) { - g_set_error(error, listen_quark(), errno, - "%s", strerror(errno)); - close(fd); - return false; - } - - ret = listen(fd, 5); - if (ret < 0) { - g_set_error(error, listen_quark(), errno, - "listen() failed: %s", strerror(errno)); - close(fd); - return false; - } - -#ifdef HAVE_STRUCT_UCRED - setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &passcred, sizeof(passcred)); -#endif ls = g_new(struct listen_socket, 1); ls->fd = fd; diff --git a/src/socket_util.c b/src/socket_util.c index 34111e90c..d8a58f9ad 100644 --- a/src/socket_util.c +++ b/src/socket_util.c @@ -20,17 +20,27 @@ #include "socket_util.h" #include "config.h" +#include <errno.h> +#include <unistd.h> + #ifndef G_OS_WIN32 #include <sys/socket.h> #include <netdb.h> #else /* G_OS_WIN32 */ #include <ws2tcpip.h> +#include <winsock.h> #endif /* G_OS_WIN32 */ #ifdef HAVE_IPV6 #include <string.h> #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; +} diff --git a/src/socket_util.h b/src/socket_util.h index b54897b99..dc129df40 100644 --- a/src/socket_util.h +++ b/src/socket_util.h @@ -43,4 +43,24 @@ struct sockaddr; char * sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error); +/** + * Creates a socket listening on the specified address. This is a + * shortcut for socket(), bind() and listen(). + * + * @param domain the socket domain, e.g. PF_INET6 + * @param type the socket type, e.g. SOCK_STREAM + * @param protocol the protocol, usually 0 to let the kernel choose + * @param address the address to listen on + * @param address_length the size of #address + * @param backlog the backlog parameter for the listen() system call + * @param error location to store the error occuring, or NULL to + * ignore errors + * @return the socket file descriptor or -1 on error + */ +int +socket_bind_listen(int domain, int type, int protocol, + const struct sockaddr *address, size_t address_length, + int backlog, + GError **error); + #endif |