aboutsummaryrefslogtreecommitdiff
path: root/src/socket.c
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-04-20 22:21:50 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-04-20 22:21:50 +0200
commit6445157bb93e59ca74e523be527f1664780575d7 (patch)
treece7cba7644d34b155850d0d081838d7cb4e55283 /src/socket.c
parentcaf3f77f6a65edcd15b84e7182808380899c19cc (diff)
POTD skeleton #18.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c75
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;
+}