diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-04-20 22:21:50 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-04-20 22:21:50 +0200 |
commit | 6445157bb93e59ca74e523be527f1664780575d7 (patch) | |
tree | ce7cba7644d34b155850d0d081838d7cb4e55283 /src/socket.c | |
parent | caf3f77f6a65edcd15b84e7182808380899c19cc (diff) |
POTD skeleton #18.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 75 |
1 files changed, 53 insertions, 22 deletions
diff --git a/src/socket.c b/src/socket.c index 7b16254..7fe5cbc 100644 --- a/src/socket.c +++ b/src/socket.c @@ -10,7 +10,7 @@ #include "socket.h" -static int socket_nonblock(const psocket *psock) +int socket_nonblock(const psocket *psock) { int flags; @@ -26,6 +26,7 @@ static int socket_nonblock(const psocket *psock) int socket_init_in(const char *addr, const char *port, struct addrinfo **results) { + int s; struct addrinfo hints; assert(addr || port); /* getaddrinfo wants either node or service */ @@ -35,17 +36,24 @@ int socket_init_in(const char *addr, hints.ai_socktype = SOCK_STREAM; /* TCP */ hints.ai_flags = AI_PASSIVE; /* all interfaces */ - return getaddrinfo(addr, port, &hints, results); + s = getaddrinfo(addr, port, &hints, results); + if (s) { + freeaddrinfo(*results); + *results = NULL; + } + + return s; } -int socket_bind_in(psocket *psock, struct addrinfo *results) +int socket_bind_in(psocket *psock, struct addrinfo **results) { - int fd = -1, rv, reuse_enable = 1; + int s = 1, fd = -1, rv, reuse_enable = 1; struct addrinfo *rp = NULL; - assert(psock && results); + assert(psock && results && *results); + psock->fd = -1; - for (rp = results; rp != NULL; rp = rp->ai_next) { + for (rp = *results; rp != NULL; rp = rp->ai_next) { fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (fd < 0) continue; @@ -56,7 +64,7 @@ int socket_bind_in(psocket *psock, struct addrinfo *results) } if (!rp) - return -1; + goto finalise; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_enable, sizeof(int)); psock->fd = fd; @@ -65,8 +73,13 @@ int socket_bind_in(psocket *psock, struct addrinfo *results) psock->family = rp->ai_family; psock->socktype = rp->ai_socktype; psock->protocol = rp->ai_protocol; - freeaddrinfo(results); - return socket_nonblock(psock); + s = socket_nonblock(psock); + +finalise: + freeaddrinfo(*results); + *results = NULL; + + return s; } int socket_listen_in(psocket *psock) @@ -81,27 +94,31 @@ int socket_accept_in(const psocket *psock, psocket *client_psock) int fd; assert(psock && client_psock); + client_psock->fd = -1; client_psock->addr_len = psock->addr_len; fd = accept(psock->fd, &client_psock->addr, &client_psock->addr_len); if (fd < 0) - return -1; - if (socket_nonblock(psock)) - return -2; + return 1; + if (socket_nonblock(psock)) { + close(fd); + return 1; + } client_psock->fd = fd; return 0; } -int socket_connect_in(psocket *psock, struct addrinfo *results) +int socket_connect_in(psocket *psock, struct addrinfo **results) { - int fd = -1, rv, reuse_enable = 1; + int s = 1, fd = -1, rv, reuse_enable = 1; struct addrinfo *rp = NULL; - assert(psock && results); + assert(psock && results && *results); + psock->fd = -1; - for (rp = results; rp != NULL; rp = rp->ai_next) { + for (rp = *results; rp != NULL; rp = rp->ai_next) { fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (fd < 0) continue; @@ -112,18 +129,22 @@ int socket_connect_in(psocket *psock, struct addrinfo *results) } if (!rp) - return -1; + goto finalise; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_enable, sizeof(int)); psock->fd = fd; psock->addr_len = rp->ai_addrlen; - psock->addr = *rp->ai_addr; + psock->addr = *(rp->ai_addr); psock->family = rp->ai_family; psock->socktype = rp->ai_socktype; psock->protocol = rp->ai_protocol; - freeaddrinfo(results); + s = socket_nonblock(psock); - return socket_nonblock(psock); +finalise: + freeaddrinfo(*results); + *results = NULL; + + return s; } int socket_addrtostr_in(const psocket *psock, @@ -154,7 +175,7 @@ int socket_reconnect_in(psocket *psock) if (psock->fd < 0) return -2; rv = connect(psock->fd, &psock->addr, psock->addr_len); - if (!rv) { + if (rv) { socket_close(psock); return -3; } @@ -164,7 +185,7 @@ int socket_reconnect_in(psocket *psock) return -4; } - return 0; + return socket_nonblock(psock); } int socket_close(psocket *psock) @@ -172,8 +193,18 @@ int socket_close(psocket *psock) int rv; assert(psock); + if (psock->fd < 0) + return 0; rv = close(psock->fd); psock->fd = -1; return rv; } + +void socket_clone(const psocket *src, psocket *dst) +{ + assert(src && dst); + + memcpy(dst, src, sizeof(*dst)); + dst->fd = -1; +} |