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;