diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-04-18 11:01:56 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-04-18 11:01:56 -0400 |
commit | 5eef60aa1a6ac9e174708f19a154ce9660589b6d (patch) | |
tree | 649e238dc905b7071efc9e4a06b61bcb286ee8a0 /src/server/addr.c | |
parent | fix makefile (diff) | |
download | wrapper-main.tar.gz wrapper-main.tar.bz2 wrapper-main.zip |
Diffstat (limited to 'src/server/addr.c')
-rw-r--r-- | src/server/addr.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/server/addr.c b/src/server/addr.c index c83b216..494b694 100644 --- a/src/server/addr.c +++ b/src/server/addr.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> @@ -159,8 +160,30 @@ int32_t write_udp_socket(UdpSocket* socket, void* buffer, uint16_t len, SocketAd ); } +static int get_socket_error(int fd) { + int err = 1; + socklen_t len = sizeof err; + if (-1 == getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &len)) + return 0; + if (err) + errno = err; + return err; +} + +static int close_socket(int fd) { + if (fd >= 0) { + get_socket_error(fd); // first clear any errors, which can cause close to fail + if (shutdown(fd, SHUT_RDWR) < 0) // secondly, terminate the 'reliable' delivery + if (errno != ENOTCONN && errno != EINVAL) // SGI causes EINVAL + perror("shutdown"); + if (close(fd) < 0) // finally call close() + perror("close"); + } + return 0; +} + int32_t close_udp_socket(UdpSocket* socket) { - return close(socket->sockfd); + return close_socket(socket->sockfd); } int32_t create_tcp_socket(AddrType type, TcpSocket* sock) { @@ -204,7 +227,7 @@ int32_t accept_tcp_socket(TcpSocket* socket, TcpStream* stream) { } int32_t close_tcp_socket(TcpSocket* socket) { - return close(socket->sockfd); + return close_socket(socket->sockfd); } int32_t connect_tcp_stream(SocketAddr* servaddr, TcpStream* stream) { @@ -222,7 +245,7 @@ int32_t connect_tcp_stream(SocketAddr* servaddr, TcpStream* stream) { } int32_t read_tcp_stream(TcpStream* stream, void* buffer, uint16_t len) { - return recv(stream->streamfd, buffer, len, 0); + return recv(stream->streamfd, buffer, len, MSG_WAITALL); } int32_t write_tcp_stream(TcpStream* stream, void* buffer, uint16_t len) { @@ -230,5 +253,5 @@ int32_t write_tcp_stream(TcpStream* stream, void* buffer, uint16_t len) { } int32_t close_tcp_stream(TcpStream* stream) { - return close(stream->streamfd); + return close_socket(stream->streamfd); } |