diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-03-07 21:44:54 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-03-07 21:44:54 -0800 |
commit | 17f693051c809f27dfcfb3115a9f889be64d3084 (patch) | |
tree | 99c272ccfb7be2114ec217f05799bf401bbabcc5 /socket.c | |
parent | b88a274b42bc32b043a31c8e10cdbd47d4efab11 (diff) | |
download | txr-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.c | 65 |
1 files changed, 42 insertions, 23 deletions
@@ -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; |