Split socket()'s type into two Rock fields (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 20 Jul 2015 14:17:57 +0000 (10:17 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 07:05:14 +0000 (03:05 -0400)
The type is overloaded in Linux to include options, such as
SOCK_NONBLOCK.  Previously, if anyone was trying to open a
SOCK_NONBLOCK socket, the type detection should fail.

Rebuild glibc.

tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.h
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socket.c

index 2139958..52200d9 100644 (file)
@@ -71,7 +71,8 @@ int accept(int fd, __SOCKADDR_ARG addr, socklen_t * __restrict alen)
                         * our lcfd for the data file fd.  even if it fails, sock_data will
                         * close our lcfd for us.  when it succeeds, it'll open the data file
                         * before closing lcfd, which will keep the converstation alive. */
-                       nfd = _sock_data(lcfd, net, r->domain, r->stype, r->protocol, &nr);
+                       nfd = _sock_data(lcfd, net, r->domain, r->stype | r->sopts,
+                                        r->protocol, &nr);
                        if (nfd < 0)
                                return -1;
 
index 77bbfa7..cbe12fe 100644 (file)
@@ -177,7 +177,7 @@ Rock *_sock_newrock(int fd)
 /* For a ctlfd and a few other settings, it opens and returns the corresponding
  * datafd.  This will close cfd for you. */
 int
-_sock_data(int cfd, char *net, int domain, int stype, int protocol, Rock ** rp)
+_sock_data(int cfd, char *net, int domain, int type, int protocol, Rock ** rp)
 {
        int n, fd;
        Rock *r;
@@ -215,7 +215,8 @@ _sock_data(int cfd, char *net, int domain, int stype, int protocol, Rock ** rp)
        memset(&r->raddr, 0, sizeof(r->raddr));
        memset(&r->addr, 0, sizeof(r->addr));
        r->domain = domain;
-       r->stype = stype;
+       r->stype = _sock_strip_opts(type);
+       r->sopts = _sock_get_opts(type);
        r->protocol = protocol;
        strcpy(r->ctl, name);
        return fd;
@@ -257,3 +258,14 @@ Rock *udp_sock_get_rock(int fd)
        else
                return 0;
 }
+
+/* In Linux, socket options are multiplexed in the socket type. */
+int _sock_strip_opts(int type)
+{
+       return type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
+}
+
+int _sock_get_opts(int type)
+{
+       return type & (SOCK_NONBLOCK | SOCK_CLOEXEC);
+}
index 77e2151..a6ca8bd 100644 (file)
@@ -43,7 +43,8 @@ struct Rock {
        unsigned long dev;                      /* inode & dev of data file */
        unsigned long inode;            /* ... */
        int domain;                                     /* from socket call */
-       int stype;                                      /* ... */
+       int stype;                                      /* socket type, from socket()'s type field */
+       int sopts;                                      /* socket options, from socket()'s type field */
        int protocol;                           /* ... */
        struct sockaddr addr;           /* address from bind */
        int reserved;                           /* use a priveledged port # (< 1024) */
@@ -60,6 +61,8 @@ extern int _sock_data(int, char *, int, int, int, Rock **);
 extern int _sock_ipattr(const char *);
 extern void _sock_ingetaddr(Rock *, struct sockaddr_in *, socklen_t *,
                                                        const char *);
+extern int _sock_strip_opts(int type);
+extern int _sock_get_opts(int type);
 
 extern void _syserrno(void);
 
index e2acd6f..e109365 100644 (file)
@@ -26,7 +26,7 @@
 /* Create a new socket of type TYPE in domain DOMAIN, using
    protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
    Returns a file descriptor for the new socket, or -1 for errors.  */
-int __socket(int domain, int stype, int protocol)
+int __socket(int domain, int type, int protocol)
 {
        Rock *r;
        int cfd, fd, n;
@@ -37,7 +37,7 @@ int __socket(int domain, int stype, int protocol)
        switch (domain) {
                case PF_INET:
                        /* get a free network directory */
-                       switch (stype) {
+                       switch (_sock_strip_opts(type)) {
                                case SOCK_DGRAM:
                                        net = "udp";
                                        cfd = open("/net/udp/clone", O_RDWR);
@@ -63,14 +63,15 @@ int __socket(int domain, int stype, int protocol)
                        if (cfd < 0) {
                                return -1;
                        }
-                       return _sock_data(cfd, net, domain, stype, protocol, 0);
+                       return _sock_data(cfd, net, domain, type, protocol, 0);
                case PF_UNIX:
                        if (pipe(pfd) < 0) {
                                return -1;
                        }
                        r = _sock_newrock(pfd[0]);
                        r->domain = domain;
-                       r->stype = stype;
+                       r->stype = _sock_strip_opts(type);
+                       r->sopts = _sock_get_opts(type);
                        r->protocol = protocol;
                        r->other = pfd[1];
                        return pfd[0];