net: Fixup socket shims use of O_NONBLOCK (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 31 Mar 2016 17:09:19 +0000 (13:09 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 5 Apr 2016 19:42:18 +0000 (15:42 -0400)
Chans are now nonblocking, not conversations.  We find out about the desire
for SOCK_NONBLOCK from socket()'s type argument.  We save that in the
Rock's sopts, and we check it whenever we open a chan *for that socket*
(but not for new accepts).

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
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/socket.c

index 55bd84d..a57f204 100644 (file)
@@ -39,6 +39,7 @@ int accept(int fd, __SOCKADDR_ARG addr, socklen_t * __restrict alen)
        char *p;
        const char *net = 0;
        char listen[Ctlsize];
+       int open_flags = O_RDWR;
 
        r = _sock_findrock(fd, 0);
        if (r == 0) {
@@ -57,25 +58,29 @@ int accept(int fd, __SOCKADDR_ARG addr, socklen_t * __restrict alen)
                                        break;
                        }
                        /* at this point, our FD is for the data file.  we need to open the
-                        * listen file.  The line is stored in r->ctl (e.g. /net/tcp/666/ctl) */
+                        * listen file.  The line is stored in r->ctl (e.g.
+                        * /net/tcp/666/ctl) */
                        strcpy(listen, r->ctl);
                        p = strrchr(listen, '/');
                        if (p == 0)
                                return -1;
                        strcpy(p + 1, "listen");
-
-                       lcfd = open(listen, O_RDWR);
+                       open_flags |= (r->sopts & SOCK_NONBLOCK ? O_NONBLOCK : 0);
+                       lcfd = open(listen, open_flags);
                        if (lcfd < 0)
                                return -1;
-                       /* at this point, we have a new conversation, and lcfd is its ctl fd.
-                        * nfd will be the FD for that conv's data file.  sock_data will trade
-                        * 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.
+                       /* at this point, we have a new conversation, and lcfd is its ctl
+                        * fd.  nfd will be the FD for that conv's data file.  sock_data
+                        * will trade 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.
                         *
-                        * Note, we pass the listen socket's stype, but not it's sopts.  If
-                        * we implement something like accept4, that's where those sopts
-                        * (e.g. O_CLOEXEC, O_NONBLOCK) will come from. */
+                        * Note, we pass the listen socket's stype, but not it's sopts.  The
+                        * sopts (e.g. SOCK_NONBLOCK) apply to the original socket, not to
+                        * the new one.  If we want to do something like accept4(), we'll
+                        * want to pass the sopts for the *new* socket in stype.  (Both the
+                        * listen socket and the new socket have the same stype). */
                        nfd = _sock_data(lcfd, net, r->domain, r->stype, r->protocol, &nr);
                        if (nfd < 0)
                                return -1;
index b35070b..64ff26a 100644 (file)
@@ -199,13 +199,13 @@ void _sock_fd_closed(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, const char *net, int domain, int type, int protocol,
                Rock **rp)
 {
        int n, fd;
        Rock *r;
        char name[Ctlsize];
+       int open_flags = O_RDWR;
 
        /* get the data file name */
        n = read(cfd, name, sizeof(name) - 1);
@@ -219,7 +219,8 @@ int _sock_data(int cfd, const char *net, int domain, int type, int protocol,
        snprintf(name, sizeof name, "/net/%s/%d/data", net, n);
 
        /* open data file */
-       fd = open(name, O_RDWR);
+       open_flags |= (type & SOCK_NONBLOCK ? O_NONBLOCK : 0);
+       fd = open(name, open_flags);
        close(cfd);     /* close this no matter what */
        if (fd < 0) {
                errno = ENOBUFS;
index 2d0ef88..d49c4ee 100644 (file)
@@ -32,7 +32,6 @@ int __socket(int domain, int type, int protocol)
 {
        Rock *r;
        int cfd, n;
-       int open_flags = O_RDWR;
        int pfd[2];
        const char *net;
        char msg[128];
@@ -42,12 +41,11 @@ int __socket(int domain, int type, int protocol)
 
        switch (domain) {
                case PF_INET:
-                       open_flags |= (type & SOCK_NONBLOCK ? O_NONBLOCK : 0);
                        /* get a free network directory */
                        switch (_sock_strip_opts(type)) {
                                case SOCK_DGRAM:
                                        net = "udp";
-                                       cfd = open("/net/udp/clone", open_flags);
+                                       cfd = open("/net/udp/clone", O_RDWR);
                                        /* All BSD UDP sockets are in 'headers' mode, where each
                                         * packet has the remote addr:port, local addr:port and
                                         * other info. */
@@ -66,7 +64,7 @@ int __socket(int domain, int type, int protocol)
                                        break;
                                case SOCK_STREAM:
                                        net = "tcp";
-                                       cfd = open("/net/tcp/clone", open_flags);
+                                       cfd = open("/net/tcp/clone", O_RDWR);
                                        break;
                                default:
                                        errno = EPROTONOSUPPORT;