net: rock: Read the connection status for getsockopt() (XCC) Once a non-blocking connect() activates, either via select or epoll, applications check if the connect() succeeded or not with getsockopt(). See man 2 connect for more details. Rebuild glibc. Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c index 536e1bd..47fbaae 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c
@@ -4,9 +4,53 @@ #include <errno.h> #include <sys/socket.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include <sys/plan9_helpers.h> +static int sol_socket_error_gso(Rock *r, void *optval, socklen_t *optlen) +{ + char buf[Ctlsize]; + int fd, ret; + char *p; + + _sock_get_conv_filename(r, "status", buf); + fd = open(buf, O_RDONLY); + if (fd < 0) + return -1; + ret = read(fd, buf, sizeof(buf)); + close(fd); + if (ret < 0) + return -1; + p = strchr(buf, ' '); + if (!p) + return -1; + *p = 0; + /* The first word in a connected TCP conv status file is 'Established'. For + * UDP it is 'Open'. + * + * For now, we'll default to no socket error, and only set the error if we + * know we aren't Established/Open. If we want, we can parse the different + * string values, like Established, Syn_sent, and return custom error + * messages. But just ECONNREFUSED is fine for now. */ + ret = 0; + switch (r->stype) { + case SOCK_DGRAM: + if (strcmp(buf, "Open")) + ret = ECONNREFUSED; + break; + case SOCK_STREAM: + if (strcmp(buf, "Established")) + ret = ECONNREFUSED; + break; + } + *(int*)optval = ret; + *optlen = 4; + return 0; +} + static int sol_socket_gso(Rock *r, int optname, void *optval, socklen_t *optlen) { switch (optname) { @@ -19,9 +63,7 @@ *optlen = 4; break; case (SO_ERROR): - *(int*)optval = 0; - *optlen = 4; - break; + return sol_socket_error_gso(r, optval, optlen); default: __set_errno(ENOPROTOOPT); return -1;