summaryrefslogtreecommitdiffstats
path: root/socket.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-07 21:44:54 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-03-07 21:44:54 -0800
commit17f693051c809f27dfcfb3115a9f889be64d3084 (patch)
tree99c272ccfb7be2114ec217f05799bf401bbabcc5 /socket.c
parentb88a274b42bc32b043a31c8e10cdbd47d4efab11 (diff)
downloadtxr-17f693051c809f27dfcfb3115a9f889be64d3084.tar.gz
txr-17f693051c809f27dfcfb3115a9f889be64d3084.tar.bz2
txr-17f693051c809f27dfcfb3115a9f889be64d3084.zip
Diagnose operations on closed socket.
* socket.c (sock_bind, sock_connect, sock_listen, sock_accept): If the socket is closed, throw an error.
Diffstat (limited to 'socket.c')
-rw-r--r--socket.c65
1 files changed, 42 insertions, 23 deletions
diff --git a/socket.c b/socket.c
index e04c222c..eb9c917c 100644
--- a/socket.c
+++ b/socket.c
@@ -621,52 +621,67 @@ static_def(struct strm_ops dgram_strm_ops =
static val sock_bind(val sock, val sockaddr)
{
- int sfd = c_num(stream_fd(sock));
- val family = sock_family(sock);
- struct sockaddr_storage sa;
- socklen_t salen;
- int reuse = 1;
+ val sfd = stream_fd(sock);
- (void) setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
+ if (sfd) {
+ int fd = c_num(sfd);
+ val family = sock_family(sock);
+ struct sockaddr_storage sa;
+ socklen_t salen;
+ int reuse = 1;
- sockaddr_in(sockaddr, family, &sa, &salen);
+ (void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
- if (bind(sfd, coerce(struct sockaddr *, &sa), salen) != 0)
- uw_throwf(socket_error_s, lit("sock-bind failed: ~d/~s"),
- num(errno), string_utf8(strerror(errno)), nao);
+ sockaddr_in(sockaddr, family, &sa, &salen);
- stream_set_prop(sock, addr_k, sockaddr);
- return t;
+ if (bind(fd, coerce(struct sockaddr *, &sa), salen) != 0)
+ uw_throwf(socket_error_s, lit("sock-bind failed: ~d/~s"),
+ num(errno), string_utf8(strerror(errno)), nao);
+
+ stream_set_prop(sock, addr_k, sockaddr);
+ return t;
+ }
+
+ uw_throwf(socket_error_s, lit("sock-bind: cannot bind ~s"), sock, nao);
}
static val sock_connect(val sock, val sockaddr)
{
val sfd = stream_fd(sock);
- val family = sock_family(sock);
- struct sockaddr_storage sa;
- socklen_t salen;
- sockaddr_in(sockaddr, family, &sa, &salen);
+ if (sfd) {
+ val family = sock_family(sock);
+ struct sockaddr_storage sa;
+ socklen_t salen;
- if (connect(c_num(sfd), coerce(struct sockaddr *, &sa), salen) != 0)
- uw_throwf(socket_error_s, lit("sock-connect ~s to addr ~s: ~d/~s"),
- sock, sockaddr, num(errno), string_utf8(strerror(errno)), nao);
+ sockaddr_in(sockaddr, family, &sa, &salen);
- sock_set_peer(sock, sockaddr);
+ if (connect(c_num(sfd), coerce(struct sockaddr *, &sa), salen) != 0)
+ uw_throwf(socket_error_s, lit("sock-connect ~s to addr ~s: ~d/~s"),
+ sock, sockaddr, num(errno), string_utf8(strerror(errno)), nao);
- return t;
+ sock_set_peer(sock, sockaddr);
+
+ return t;
+ }
+
+ uw_throwf(socket_error_s, lit("sock-connect: cannot connect ~s"), sock, nao);
}
static val sock_listen(val sock, val backlog)
{
+ val sfd = stream_fd(sock);
+
+ if (!sfd)
+ uw_throwf(socket_error_s, lit("sock-listen: cannot listen on ~s"),
+ sock, nao);
+
if (sock_type(sock) == num_fast(SOCK_DGRAM)) {
if (sock_peer(sock)) {
errno = EISCONN;
goto failed;
}
} else {
- val sfd = stream_fd(sock);
-
if (listen(c_num(sfd), c_num(default_arg(backlog, num_fast(16)))))
goto failed;
}
@@ -686,6 +701,10 @@ static val sock_accept(val sock, val mode_str)
socklen_t salen = sizeof sa;
val peer = nil;
+ if (!sfd)
+ uw_throwf(socket_error_s, lit("sock-accept: cannot accept on ~s"),
+ sock, nao);
+
if (type == num_fast(SOCK_DGRAM)) {
ssize_t nbytes = -1;
const int dgram_size = 65536;