]> Zhao Yanbai Git Server - minix.git/commitdiff
UDS: clean up source code
authorDavid van Moolenbroek <david@minix3.org>
Fri, 4 Oct 2013 14:46:18 +0000 (16:46 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:57 +0000 (09:04 +0100)
- move VFS calls to a separate source file;
- solve a few subtle bugs, mostly in error handling;
- simplify debug reporting code;
- make a few definitions more independent;
- restyle to something closer to KNF.

Change-Id: I7b0537adfccac8b92b5cc3e78dac9f5ce3c79f03

drivers/uds/Makefile
drivers/uds/ioc_uds.c
drivers/uds/uds.c
drivers/uds/uds.h
drivers/uds/vfs_uds.c [new file with mode: 0644]

index 8f339297d6a48746c3e57bf2e8f46eddc35df356..1348ec41bf83b41eab35db594d6c7d5758f113af 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the UNIX Domain Sockets driver (UDS)
 PROG=  uds
-SRCS=  uds.c ioc_uds.c
+SRCS=  uds.c ioc_uds.c vfs_uds.c
 
 DPADD+=        ${LIBCHARDRIVER} ${LIBSYS}
 LDADD+=        -lchardriver -lsys
index da6e28c1ec4ebe2fcfd55a6c6df22baf10fc1100..fe62a88e01830e66106397d3c6ac403da9070dc2 100644 (file)
  * The entry points into this file are...
  *
  *   uds_do_ioctl:           process an IOCTL request.
- *   uds_clear_fds:          calls put_filp for undelivered FDs.
+ *   uds_clear_fds:          calls vfs_put_filp for undelivered FDs.
  */
 
 #include "uds.h"
 
-/*
- * Check the permissions of a socket file.
- */
-static int
-check_perms(devminor_t minor, struct sockaddr_un *addr)
-{
-       int rc;
-       message vfs_m;
-       cp_grant_id_t grant_id;
-
-       grant_id = cpf_grant_direct(VFS_PROC_NR, (vir_bytes) addr->sun_path,
-                                       UNIX_PATH_MAX, CPF_READ | CPF_WRITE);
-
-       /* ask the VFS to verify the permissions */
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_CHECK_PERMS;
-       vfs_m.VFS_UDS_ENDPT = uds_fd_table[minor].owner;
-       vfs_m.VFS_UDS_GRANT = grant_id;
-       vfs_m.VFS_UDS_COUNT = UNIX_PATH_MAX;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       cpf_revoke(grant_id);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-
-               return EIO;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-       printf("(uds) Canonical Path => %s\n", addr->sun_path);
-#endif
-
-       return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
-}
-
-static filp_id_t
-verify_fd(endpoint_t ep, int fd)
-{
-       int rc;
-       message vfs_m;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) verify_fd(%d,%d) call_count=%d\n", ep, fd,
-                                                       ++call_count);
-#endif
-
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_VERIFY_FD;
-       vfs_m.VFS_UDS_ENDPT = ep;
-       vfs_m.VFS_UDS_FD = fd;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-               return NULL;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-#endif
-
-       return vfs_m.VFS_UDS_FILP;
-}
-
-static int
-set_filp(filp_id_t sfilp)
-{
-       int rc;
-       message vfs_m;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) set_filp(%p) call_count=%d\n", sfilp, ++call_count);
-#endif
-
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_SET_FILP;
-       vfs_m.VFS_UDS_FILP = sfilp;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-               return EIO;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-#endif
-       return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
-}
-
-static int
-copy_filp(endpoint_t to_ep, filp_id_t cfilp)
-{
-       int rc;
-       message vfs_m;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) copy_filp(%d, %p) call_count=%d\n",to_ep, cfilp,
-                                                       ++call_count);
-#endif
-
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_COPY_FILP;
-       vfs_m.VFS_UDS_ENDPT = to_ep;
-       vfs_m.VFS_UDS_FILP = cfilp;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-               return EIO;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-#endif
-       return vfs_m.m_type;
-}
-
-static int
-put_filp(filp_id_t pfilp)
-{
-       int rc;
-       message vfs_m;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) put_filp(%p) call_count=%d\n", pfilp, ++call_count);
-#endif
-
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_PUT_FILP;
-       vfs_m.VFS_UDS_FILP = pfilp;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-               return EIO;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-#endif
-       return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
-}
-
-static int
-cancel_fd(endpoint_t ep, int fd)
-{
-       int rc;
-       message vfs_m;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) cancel_fd(%d,%d) call_count=%d\n", ep, fd, ++call_count);
-#endif
-
-       memset(&vfs_m, '\0', sizeof(message));
-
-       vfs_m.m_type = VFS_UDS_CANCEL_FD;
-       vfs_m.VFS_UDS_ENDPT = ep;
-       vfs_m.VFS_UDS_FD = fd;
-
-       rc = sendrec(VFS_PROC_NR, &vfs_m);
-       if (OK != rc) {
-                printf("(uds) sendrec error... req_nr: %d err: %d\n",
-                       vfs_m.m_type, rc);
-               return EIO;
-       }
-
-#if DEBUG == 1
-       printf("(uds) VFS reply => %d\n", vfs_m.m_type);
-#endif
-       return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
-}
-
 static int
 perform_connection(devminor_t minorx, devminor_t minory,
        struct sockaddr_un *addr)
 {
-       /* there are several places were a connection is established. */
-       /* accept(2), connect(2), uds_status(2), socketpair(2)        */
-       /* This is a helper function to make sure it is done in the   */
-       /* same way in each place with the same validation checks.    */
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] perform_connection() call_count=%d\n", minorx,
-               ++call_count);
-#endif
-
-       /* only connection oriented types are acceptable and only like
-        * types can connect to each other
+       /*
+        * There are several places were a connection is established, the
+        * initiating call being one of accept(2), connect(2), socketpair(2).
         */
-       if ((uds_fd_table[minorx].type != SOCK_SEQPACKET &&
-               uds_fd_table[minorx].type != SOCK_STREAM) ||
-               uds_fd_table[minorx].type != uds_fd_table[minory].type) {
+       dprintf(("UDS: perform_connection(%d, %d)\n", minorx, minory));
 
-               /* sockets are not in a valid state */
+       /*
+        * Only connection-oriented types are acceptable and only equal
+        * types can connect to each other.
+        */
+       if ((uds_fd_table[minorx].type != SOCK_SEQPACKET &&
+           uds_fd_table[minorx].type != SOCK_STREAM) ||
+           uds_fd_table[minorx].type != uds_fd_table[minory].type)
                return EINVAL;
-       }
 
-       /* connect the pair of sockets */
+       /* Connect the pair of sockets. */
        uds_fd_table[minorx].peer = minory;
        uds_fd_table[minory].peer = minorx;
 
        /* Set the address of both sockets */
-       memcpy(&(uds_fd_table[minorx].addr), addr, sizeof(struct sockaddr_un));
-       memcpy(&(uds_fd_table[minory].addr), addr, sizeof(struct sockaddr_un));
+       memcpy(&uds_fd_table[minorx].addr, addr, sizeof(struct sockaddr_un));
+       memcpy(&uds_fd_table[minory].addr, addr, sizeof(struct sockaddr_un));
 
        return OK;
 }
@@ -245,12 +49,10 @@ do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc, i;
        struct sockaddr_un addr;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_accept() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_accept(%d)\n", minor));
 
-       /* Somewhat weird logic is used in this function, so here's an
+       /*
+        * Somewhat weird logic is used in this function, so here's an
         * overview... The minor number is the server's client socket
         * (the socket to be returned by accept()). The data waiting
         * for us in the IO Grant is the address that the server is
@@ -259,98 +61,73 @@ do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
         * connection or suspend and wait for a connect().
         */
 
-       if (uds_fd_table[minor].type != -1) {
-               /* this IOCTL must be called on a 'fresh' socket */
+       /* This IOCTL must be called on a 'fresh' socket. */
+       if (uds_fd_table[minor].type != -1)
                return EINVAL;
-       }
 
        /* Get the server's address */
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
-               sizeof(struct sockaddr_un));
-
-       if (rc != OK) {
-               return EIO;
-       }
-
-       /* locate server socket */
-       rc = -1; /* to trap error */
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
+           sizeof(struct sockaddr_un))) != OK)
+               return rc;
 
+       /* Locate the server socket. */
        for (i = 0; i < NR_FDS; i++) {
                if (uds_fd_table[i].addr.sun_family == AF_UNIX &&
-                               !strncmp(addr.sun_path,
-                               uds_fd_table[i].addr.sun_path,
-                               UNIX_PATH_MAX) &&
-                               uds_fd_table[i].listening == 1) {
-
-                       rc = 0;
+                   !strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path,
+                   UNIX_PATH_MAX) && uds_fd_table[i].listening == 1)
                        break;
-               }
        }
 
-       if (rc == -1) {
-               /* there is no server listening on addr. Maybe someone
-                * screwed up the ioctl()?
-                */
+       if (i == NR_FDS)
                return EINVAL;
-       }
 
        minorparent = i; /* parent */
 
-       /* we are the parent's child */
+       /* We are the parent's child. */
        uds_fd_table[minorparent].child = minor;
 
-       /* the peer has the same type as the parent. we need to be that
+       /*
+        * The peer has the same type as the parent. we need to be that
         * type too.
         */
        uds_fd_table[minor].type = uds_fd_table[minorparent].type;
 
-       /* locate peer to accept in the parent's backlog */
-       minorpeer = -1; /* to trap error */
+       /* Locate the peer to accept in the parent's backlog. */
+       minorpeer = -1;
        for (i = 0; i < uds_fd_table[minorparent].backlog_size; i++) {
                if (uds_fd_table[minorparent].backlog[i] != -1) {
                        minorpeer = uds_fd_table[minorparent].backlog[i];
                        uds_fd_table[minorparent].backlog[i] = -1;
-                       rc = 0;
                        break;
                }
        }
 
        if (minorpeer == -1) {
+               dprintf(("UDS: do_accept(%d): suspend\n", minor));
 
-#if DEBUG == 1
-               printf("(uds) [%d] {do_accept} suspend\n", minor);
-#endif
-
-               /* there are no peers in the backlog, suspend and wait
-                * for some to show up
+               /*
+                * There are no peers in the backlog, suspend and wait for one
+                * to show up.
                 */
                uds_fd_table[minor].suspended = UDS_SUSPENDED_ACCEPT;
 
                return EDONTREPLY;
        }
 
-#if DEBUG == 1
-       printf("(uds) [%d] connecting to %d -- parent is %d\n", minor,
-                                               minorpeer, minorparent);
-#endif
-
-       rc = perform_connection(minor, minorpeer, &addr);
-       if (rc != OK) {
-#if DEBUG == 1
-               printf("(uds) [%d] {do_accept} connection not performed\n",
-                                                               minor);
-#endif
+       dprintf(("UDS: connecting %d to %d -- parent is %d\n", minor,
+           minorpeer, minorparent));
+
+       if ((rc = perform_connection(minor, minorpeer, &addr)) != OK) {
+               dprintf(("UDS: do_accept(%d): connection failed\n", minor));
+
                return rc;
        }
 
        uds_fd_table[minorparent].child = -1;
 
-       /* if peer is blocked on connect() revive peer */
+       /* If the peer is blocked on connect(), revive the peer. */
        if (uds_fd_table[minorpeer].suspended) {
-#if DEBUG == 1
-               printf("(uds) [%d] {do_accept} revive %d\n", minor,
-                                                               minorpeer);
-#endif
+               dprintf(("UDS: do_accept(%d): revive %d\n", minor, minorpeer));
                uds_unsuspend(minorpeer);
        }
 
@@ -364,134 +141,96 @@ do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        struct sockaddr_un addr;
        int rc, i, j;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_connect() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_connect(%d)\n", minor));
 
-       /* only connection oriented sockets can connect */
+       /* Only connection oriented sockets can connect. */
        if (uds_fd_table[minor].type != SOCK_STREAM &&
-                       uds_fd_table[minor].type != SOCK_SEQPACKET) {
+           uds_fd_table[minor].type != SOCK_SEQPACKET)
                return EINVAL;
-       }
 
-       if (uds_fd_table[minor].peer != -1) {
-               /* socket is already connected */
+       /* The socket must not be connected already. */
+       if (uds_fd_table[minor].peer != -1)
                return EISCONN;
-       }
 
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
-               sizeof(struct sockaddr_un));
-
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
+           sizeof(struct sockaddr_un))) != OK)
+               return rc;
 
-       rc = check_perms(minor, &addr);
-       if (rc != OK) {
-               /* permission denied, socket file doesn't exist, etc. */
+       if ((rc = vfs_check_perms(uds_fd_table[minor].owner, &addr)) != OK)
                return rc;
-       }
 
-       /* look for a socket of the same type that is listening on the
-        * address we want to connect to
+       /*
+        * Look for a socket of the same type that is listening on the
+        * address we want to connect to.
         */
        for (i = 0; i < NR_FDS; i++) {
-               if (uds_fd_table[minor].type == uds_fd_table[i].type &&
-                       uds_fd_table[i].listening &&
-                       uds_fd_table[i].addr.sun_family == AF_UNIX &&
-                       !strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path,
-                       UNIX_PATH_MAX)) {
-
-                       if ((child = uds_fd_table[i].child) != -1) {
-
-                               /* the server is blocked on accept(2) --
-                                * perform connection to the child
-                                */
-
-                               rc = perform_connection(minor, child, &addr);
-
-                               if (rc == OK) {
-                                       uds_fd_table[i].child = -1;
-
-#if DEBUG == 1
-               printf("(uds) [%d] {do_connect} revive %d\n", minor, child);
-#endif
-
-                                       /* wake the parent (server) */
-                                       uds_unsuspend(child);
-                               }
-
-                               return rc;
-                       } else {
-#if DEBUG == 1
-                               printf("(uds) [%d] adding to %d's backlog\n",
-                                                               minor, i);
-#endif
-
-                               /* tell the server were waiting to be served */
-
-                               /* look for a free slot in the backlog */
-                               rc = -1; /* to trap error */
-                               for (j = 0; j < uds_fd_table[i].backlog_size;
-                                       j++) {
-
-                                       if (uds_fd_table[i].backlog[j] == -1) {
-
-                                               uds_fd_table[i].backlog[j] =
-                                                       minor;
-
-                                               rc = 0;
-                                               break;
-                                       }
-                               }
-
-                               if (rc == -1) {
-                                       /* backlog is full */
-                                       break;
-                               }
-
-                               /* see if the server is blocked on select() */
-                               if (uds_fd_table[i].sel_ops & CDEV_OP_RD) {
-                                       /* if the server wants to know about
-                                        * data ready to read and it doesn't
-                                        * doesn't know about it already, then
-                                        * let the server know we have data for
-                                        * it.
-                                        */
-                                       chardriver_reply_select(
-                                               uds_fd_table[i].sel_endpt, i,
-                                               CDEV_OP_RD);
-
-                                       uds_fd_table[i].sel_ops &= ~CDEV_OP_RD;
-                               }
-
-                               /* we found our server */
-                               uds_fd_table[minor].peer = i;
-
-                               /* set the address */
-                               memcpy(&(uds_fd_table[minor].addr), &addr,
-                                       sizeof(struct sockaddr_un));
+               if (uds_fd_table[minor].type != uds_fd_table[i].type)
+                       continue;
+               if (!uds_fd_table[i].listening)
+                       continue;
+               if (uds_fd_table[i].addr.sun_family != AF_UNIX)
+                       continue;
+               if (strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path,
+                   UNIX_PATH_MAX))
+                       continue;
+
+               /* Found a matching socket. */
+               break;
+       }
 
-                               break;
-                       }
+       if (i == NR_FDS)
+               return ECONNREFUSED;
+
+       /* If the server is blocked on an accept, perform the connection. */
+       if ((child = uds_fd_table[i].child) != -1) {
+               rc = perform_connection(minor, child, &addr);
+
+               if (rc != OK)
+                       return rc;
+
+               uds_fd_table[i].child = -1;
+
+               dprintf(("UDS: do_connect(%d): revive %d\n", minor, child));
+
+               /* Wake up the accepting party. */
+               uds_unsuspend(child);
+
+               return OK;
+       }
+
+       dprintf(("UDS: adding %d to %d's backlog\n", minor, i));
+
+       /* Look for a free slot in the backlog. */
+       rc = -1;
+       for (j = 0; j < uds_fd_table[i].backlog_size; j++) {
+               if (uds_fd_table[i].backlog[j] == -1) {
+                       uds_fd_table[i].backlog[j] = minor;
+
+                       rc = 0;
+                       break;
                }
        }
 
-       if (uds_fd_table[minor].peer == -1) {
-               /* could not find another open socket listening on the
-                * specified address with room in the backlog
-                */
-               return ECONNREFUSED;
+       if (rc == -1)
+               return ECONNREFUSED;    /* backlog is full */
+
+       /* See if the server is blocked on select(). */
+       if (uds_fd_table[i].sel_ops & CDEV_OP_RD) {
+               /* Satisfy a read-type select on the server. */
+               chardriver_reply_select(uds_fd_table[i].sel_endpt, i,
+                   CDEV_OP_RD);
+
+               uds_fd_table[i].sel_ops &= ~CDEV_OP_RD;
        }
 
-#if DEBUG == 1
-       printf("(uds) [%d] {do_connect} suspend\n", minor);
-#endif
+       /* We found our server. */
+       uds_fd_table[minor].peer = i;
 
-       /* suspend until the server side completes the connection with accept()
-        */
+       memcpy(&uds_fd_table[minor].addr, &addr, sizeof(struct sockaddr_un));
+
+       dprintf(("UDS: do_connect(%d): suspend\n", minor));
 
+       /* Suspend until the server side accepts the connection. */
        uds_fd_table[minor].suspended = UDS_SUSPENDED_CONNECT;
 
        return EDONTREPLY;
@@ -503,72 +242,47 @@ do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc;
        int backlog_size;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_listen() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_listen(%d)\n", minor));
 
-       /* ensure the socket has a type and is bound */
+       /* Ensure the socket has a type and is bound. */
        if (uds_fd_table[minor].type == -1 ||
-               uds_fd_table[minor].addr.sun_family != AF_UNIX) {
-
-               /* probably trying to call listen() before bind() */
+           uds_fd_table[minor].addr.sun_family != AF_UNIX)
                return EINVAL;
-       }
 
-       /* the two supported types for listen(2) are SOCK_STREAM and
-        * SOCK_SEQPACKET
-        */
+       /* listen(2) supports only two socket types. */
        if (uds_fd_table[minor].type != SOCK_STREAM &&
-                       uds_fd_table[minor].type != SOCK_SEQPACKET) {
-
-               /* probably trying to call listen() with a SOCK_DGRAM */
+           uds_fd_table[minor].type != SOCK_SEQPACKET)
                return EOPNOTSUPP;
-       }
 
-       /* The POSIX standard doesn't say what to do if listen() has
-        * already been called. Well, there isn't an errno. we silently
+       /*
+        * The POSIX standard doesn't say what to do if listen() has
+        * already been called.  Well, there isn't an errno.  We silently
         * let it happen, but if listen() has already been called, we
-        * don't allow the backlog to shrink
+        * don't allow the backlog to shrink.
         */
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &backlog_size,
-               sizeof(int));
-
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &backlog_size,
+           sizeof(backlog_size))) != OK)
+               return rc;
 
        if (uds_fd_table[minor].listening == 0) {
+               /* Set the backlog size to a reasonable value. */
+               if (backlog_size <= 0 || backlog_size > UDS_SOMAXCONN)
+                       backlog_size = UDS_SOMAXCONN;
 
-               /* See if backlog_size is between 0 and UDS_SOMAXCONN */
-               if (backlog_size >= 0 && backlog_size < UDS_SOMAXCONN) {
-
-                       /* use the user provided backlog_size */
-                       uds_fd_table[minor].backlog_size = backlog_size;
-
-               } else {
-
-                       /* the user gave an invalid size, use
-                        * UDS_SOMAXCONN instead
-                        */
-                       uds_fd_table[minor].backlog_size = UDS_SOMAXCONN;
-               }
+               uds_fd_table[minor].backlog_size = backlog_size;
        } else {
-
-               /* See if the user is trying to expand the backlog_size */
+               /* Allow the user to expand the backlog size. */
                if (backlog_size > uds_fd_table[minor].backlog_size &&
-                       backlog_size < UDS_SOMAXCONN) {
-
-                       /* expand backlog_size */
+                   backlog_size < UDS_SOMAXCONN)
                        uds_fd_table[minor].backlog_size = backlog_size;
-               }
 
-               /* Don't let the user shrink the backlog_size (we might
-                * have clients waiting in those slots
+               /*
+                * Don't let the user shrink the backlog_size, as we might
+                * have clients waiting in those slots.
                 */
        }
 
-       /* perform listen(2) */
+       /* This socket is now listening. */
        uds_fd_table[minor].listening = 1;
 
        return OK;
@@ -577,45 +291,29 @@ do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 static int
 do_socket(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
+       int rc, type;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_socket() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_socket(%d)\n", minor));
 
-       /* see if this socket already has a type */
-       if (uds_fd_table[minor].type != -1) {
-               /* socket type can only be set once */
+       /* The socket type can only be set once. */
+       if (uds_fd_table[minor].type != -1)
                return EINVAL;
-       }
 
-       /* get the requested type */
-       rc = sys_safecopyfrom(endpt, grant, 0,
-               (vir_bytes) &uds_fd_table[minor].type, sizeof(int));
-
-       if (rc != OK) {
-               /* something went wrong and we couldn't get the type */
-               return EIO;
-       }
-
-       /* validate the type */
-       switch (uds_fd_table[minor].type) {
-               case SOCK_STREAM:
-               case SOCK_DGRAM:
-               case SOCK_SEQPACKET:
-                       /* the type is one of the 3 valid socket types */
-                       return OK;
-
-               default:
-                       /* if the type isn't one of the 3 valid socket
-                        * types, then it must be invalid.
-                        */
+       /* Get the requested type. */
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &type,
+           sizeof(type))) != OK)
+               return rc;
 
-                       /* set the type back to '-1' (no type set) */
-                       uds_fd_table[minor].type = -1;
+       /* Assign the type if it is valid only. */
+       switch (type) {
+       case SOCK_STREAM:
+       case SOCK_DGRAM:
+       case SOCK_SEQPACKET:
+               uds_fd_table[minor].type = type;
+               return OK;
 
-                       return EINVAL;
+       default:
+               return EINVAL;
        }
 }
 
@@ -625,58 +323,42 @@ do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        struct sockaddr_un addr;
        int rc, i;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_bind() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_bind(%d)\n", minor));
 
+       /* If the type hasn't been set by do_socket() yet, OR an attempt
+        * to re-bind() a non-SOCK_DGRAM socket is made, fail the call.
+        */
        if ((uds_fd_table[minor].type == -1) ||
-               (uds_fd_table[minor].addr.sun_family == AF_UNIX &&
-               uds_fd_table[minor].type != SOCK_DGRAM)) {
-
-               /* the type hasn't been set by do_socket() yet OR attempting
-                * to re-bind() a non-SOCK_DGRAM socket
-                */
+           (uds_fd_table[minor].addr.sun_family == AF_UNIX &&
+           uds_fd_table[minor].type != SOCK_DGRAM))
                return EINVAL;
-       }
-
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
-               sizeof(struct sockaddr_un));
 
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
+           sizeof(struct sockaddr_un))) != OK)
+               return rc;
 
-       /* do some basic sanity checks on the address */
-       if (addr.sun_family != AF_UNIX) {
-               /* bad family */
+       /* Do some basic sanity checks on the address. */
+       if (addr.sun_family != AF_UNIX)
                return EAFNOSUPPORT;
-       }
 
-       if (addr.sun_path[0] == '\0') {
-               /* bad address */
+       if (addr.sun_path[0] == '\0')
                return ENOENT;
-       }
 
-       rc = check_perms(minor, &addr);
-       if (rc != OK) {
-               /* permission denied, socket file doesn't exist, etc. */
+       if ((rc = vfs_check_perms(uds_fd_table[minor].owner, &addr)) != OK)
                return rc;
-       }
 
-       /* make sure the address isn't already in use by another socket. */
+       /* Make sure the address isn't already in use by another socket. */
        for (i = 0; i < NR_FDS; i++) {
-               if ((uds_fd_table[i].addr.sun_family == AF_UNIX) &&
-                       !strncmp(addr.sun_path,
-                       uds_fd_table[i].addr.sun_path, UNIX_PATH_MAX)) {
-
-                       /* another socket is bound to this sun_path */
+               if (uds_fd_table[i].addr.sun_family == AF_UNIX &&
+                   !strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path,
+                   UNIX_PATH_MAX)) {
+                       /* Another socket is bound to this sun_path. */
                        return EADDRINUSE;
                }
        }
 
-       /* looks good, perform the bind() */
-       memcpy(&(uds_fd_table[minor].addr), &addr, sizeof(struct sockaddr_un));
+       /* Looks good, perform the bind(). */
+       memcpy(&uds_fd_table[minor].addr, &addr, sizeof(struct sockaddr_un));
 
        return OK;
 }
@@ -684,59 +366,39 @@ do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 static int
 do_getsockname(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
+       dprintf(("UDS: do_getsockname(%d)\n", minor));
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getsockname() call_count=%d\n", minor,
-               ++call_count);
-#endif
-
-       /* Unconditionally send the address we have assigned to this socket.
-        * The POSIX standard doesn't say what to do if the address
-        * hasn't been set. If the address isn't currently set, then
-        * the user will get NULL bytes. Note: libc depends on this
-        * behavior.
+       /*
+        * Unconditionally send the address we have assigned to this socket.
+        * The POSIX standard doesn't say what to do if the address hasn't been
+        * set.  If the address isn't currently set, then the user will get
+        * NULL bytes.  Note: libc depends on this behavior.
         */
-       rc = sys_safecopyto(endpt, grant, 0,
-               (vir_bytes) &uds_fd_table[minor].addr,
-               sizeof(struct sockaddr_un));
-
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0,
+           (vir_bytes) &uds_fd_table[minor].addr, sizeof(struct sockaddr_un));
 }
 
 static int
 do_getpeername(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
+       int rc, peer_minor;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getpeername() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_getpeername(%d)\n", minor));
 
-       /* check that the socket is connected with a valid peer */
+       /* Check that the socket is connected with a valid peer. */
        if (uds_fd_table[minor].peer != -1) {
-               int peer_minor;
-
                peer_minor = uds_fd_table[minor].peer;
 
-               /* copy the address from the peer */
-               rc = sys_safecopyto(endpt, grant, 0,
-                       (vir_bytes) &uds_fd_table[peer_minor].addr,
-                       sizeof(struct sockaddr_un));
-
-               return rc ? EIO : OK;
-       } else {
-               if (uds_fd_table[minor].err == ECONNRESET) {
-                       uds_fd_table[minor].err = 0;
+               /* Copy the address from the peer. */
+               return sys_safecopyto(endpt, grant, 0,
+                   (vir_bytes) &uds_fd_table[peer_minor].addr,
+                   sizeof(struct sockaddr_un));
+       } else if (uds_fd_table[minor].err == ECONNRESET) {
+               uds_fd_table[minor].err = 0;
 
-                       return ECONNRESET;
-               } else {
-                       return ENOTCONN;
-               }
-       }
+               return ECONNRESET;
+       } else
+               return ENOTCONN;
 }
 
 static int
@@ -744,54 +406,41 @@ do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
        int rc, how;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_shutdown() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_shutdown(%d)\n", minor));
 
+       /* The socket must be connection oriented. */
        if (uds_fd_table[minor].type != SOCK_STREAM &&
-                       uds_fd_table[minor].type != SOCK_SEQPACKET) {
-
-               /* socket must be a connection oriented socket */
+           uds_fd_table[minor].type != SOCK_SEQPACKET)
                return EINVAL;
-       }
 
        if (uds_fd_table[minor].peer == -1) {
-               /* shutdown(2) is only valid for connected sockets */
-               if (uds_fd_table[minor].err == ECONNRESET) {
+               /* shutdown(2) is only valid for connected sockets. */
+               if (uds_fd_table[minor].err == ECONNRESET)
                        return ECONNRESET;
-               } else {
+               else
                        return ENOTCONN;
-               }
        }
 
-       /* get the 'how' parameter from the process */
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &how, sizeof(int));
-
-       if (rc != OK) {
-               return EIO;
-       }
+       /* Get the 'how' parameter from the caller. */
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &how,
+           sizeof(how))) != OK)
+               return rc;
 
        switch (how) {
-               case SHUT_RD:
-                       /* take away read permission */
-                       uds_fd_table[minor].mode &= ~R_BIT;
-                       break;
+       case SHUT_RD:           /* Take away read permission. */
+               uds_fd_table[minor].mode &= ~UDS_R;
+               break;
 
-               case SHUT_WR:
-                       /* take away write permission */
-                       uds_fd_table[minor].mode &= ~W_BIT;
-                       break;
+       case SHUT_WR:           /* Take away write permission. */
+               uds_fd_table[minor].mode &= ~UDS_W;
+               break;
 
-               case SHUT_RDWR:
-                       /* completely shutdown */
-                       uds_fd_table[minor].mode = 0;
-                       break;
+       case SHUT_RDWR:         /* Shut down completely. */
+               uds_fd_table[minor].mode = 0;
+               break;
 
-               default:
-                       /* the 'how' parameter is invalid */
-                       return EINVAL;
+       default:
+               return EINVAL;
        }
 
        return OK;
@@ -805,33 +454,20 @@ do_socketpair(devminor_t minorx, endpoint_t endpt, cp_grant_id_t grant)
        devminor_t minory;
        struct sockaddr_un addr;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_socketpair() call_count=%d\n", minorx,
-               ++call_count);
-#endif
-
-       /* ioctl argument is the minor number of the second socket */
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &minorin,
-               sizeof(dev_t));
+       dprintf(("UDS: do_socketpair(%d)\n", minorx));
 
-       if (rc != OK) {
-               return EIO;
-       }
+       /* The ioctl argument is the minor number of the second socket. */
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &minorin,
+           sizeof(minorin))) != OK)
+               return rc;
 
        minory = minor(minorin);
 
-#if DEBUG == 1
-       printf("socketpair() %d - %d\n", minorx, minory);
-#endif
+       dprintf(("UDS: socketpair(%d, %d,)\n", minorx, minory));
 
-       /* security check - both sockets must have the same endpoint (owner) */
-       if (uds_fd_table[minorx].owner != uds_fd_table[minory].owner) {
-               /* we won't allow you to magically connect your socket to
-                * someone elses socket
-                */
+       /* Security check: both sockets must have the same owner endpoint. */
+       if (uds_fd_table[minorx].owner != uds_fd_table[minory].owner)
                return EPERM;
-       }
 
        addr.sun_family = AF_UNIX;
        addr.sun_path[0] = 'X';
@@ -845,23 +481,14 @@ do_getsockopt_sotype(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
        int rc;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getsockopt_sotype() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_getsockopt_sotype(%d)\n", minor));
 
-       if (uds_fd_table[minor].type == -1) {
-               /* the type hasn't been set yet. instead of returning an
-                * invalid type, we fail with EINVAL
-                */
+       /* If the type hasn't been set yet, we fail the call. */
+       if (uds_fd_table[minor].type == -1)
                return EINVAL;
-       }
 
-       rc = sys_safecopyto(endpt, grant, 0,
-               (vir_bytes) &uds_fd_table[minor].type, sizeof(int));
-
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0,
+           (vir_bytes) &uds_fd_table[minor].type, sizeof(int));
 }
 
 static int
@@ -871,54 +498,36 @@ do_getsockopt_peercred(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc;
        struct uucred cred;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getsockopt_peercred() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_getsockopt_peercred(%d)\n", minor));
 
        if (uds_fd_table[minor].peer == -1) {
-
                if (uds_fd_table[minor].err == ECONNRESET) {
                        uds_fd_table[minor].err = 0;
 
                        return ECONNRESET;
-               } else {
+               } else
                        return ENOTCONN;
-               }
        }
 
        peer_minor = uds_fd_table[minor].peer;
 
-       /* obtain the peer's credentials */
-       rc = getnucred(uds_fd_table[peer_minor].owner, &cred);
-       if (rc == -1) {
-               /* likely error: invalid endpoint / proc doesn't exist */
-               return errno;
-       }
-
-       rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &cred,
-               sizeof(struct uucred));
+       /* Obtain the peer's credentials and copy them out. */
+       if ((rc = getnucred(uds_fd_table[peer_minor].owner, &cred)) < 0)
+               return -errno;
 
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0, (vir_bytes) &cred,
+           sizeof(struct uucred));
 }
 
 static int
 do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
-       size_t sndbuf = PIPE_BUF;
+       size_t sndbuf = UDS_BUF;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getsockopt_sndbuf() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_getsockopt_sndbuf(%d)\n", minor));
 
-       rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &sndbuf,
-               sizeof(size_t));
-
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0, (vir_bytes) &sndbuf,
+           sizeof(sndbuf));
 }
 
 static int
@@ -927,46 +536,29 @@ do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc;
        size_t sndbuf;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", minor,
-               ++call_count);
-#endif
-
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &sndbuf,
-               sizeof(size_t));
+       dprintf(("UDS: do_setsockopt_sndbuf(%d)\n", minor));
 
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &sndbuf,
+           sizeof(sndbuf))) != OK)
+               return rc;
 
-       if (sndbuf > PIPE_BUF) {
-               /* The send buffer is limited to 32K at the moment. */
+       /* The send buffer is limited to 32KB at the moment. */
+       if (sndbuf > UDS_BUF)
                return ENOSYS;
-       }
 
-       /* There is no way to reduce the send buffer, do we have to
-        * let this call fail for smaller buffers?
-        */
+       /* FIXME: actually shrink the buffer. */
        return OK;
 }
 
 static int
 do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
-       size_t rcvbuf = PIPE_BUF;
+       size_t rcvbuf = UDS_BUF;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_getsockopt_rcvbuf() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_getsockopt_rcvbuf(%d)\n", minor));
 
-       rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &rcvbuf,
-               sizeof(size_t));
-
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0, (vir_bytes) &rcvbuf,
+           sizeof(rcvbuf));
 }
 
 static int
@@ -975,27 +567,17 @@ do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc;
        size_t rcvbuf;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", minor,
-               ++call_count);
-#endif
-
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &rcvbuf,
-               sizeof(size_t));
+       dprintf(("UDS: do_setsockopt_rcvbuf(%d)\n", minor));
 
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &rcvbuf,
+           sizeof(rcvbuf))) != OK)
+               return rc;
 
-       if (rcvbuf > PIPE_BUF) {
-               /* The send buffer is limited to 32K at the moment. */
+       /* The receive buffer is limited to 32KB at the moment. */
+       if (rcvbuf > UDS_BUF)
                return ENOSYS;
-       }
 
-       /* There is no way to reduce the send buffer, do we have to
-        * let this call fail for smaller buffers?
-        */
+       /* FIXME: actually shrink the buffer. */
        return OK;
 }
 
@@ -1005,36 +587,24 @@ do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int rc;
        struct sockaddr_un addr;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_sendto() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_sendto(%d)\n", minor));
 
-       if (uds_fd_table[minor].type != SOCK_DGRAM) {
-               /* This IOCTL is only for SOCK_DGRAM sockets */
+       /* This IOCTL is only for SOCK_DGRAM sockets. */
+       if (uds_fd_table[minor].type != SOCK_DGRAM)
                return EINVAL;
-       }
-
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
-               sizeof(struct sockaddr_un));
 
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr,
+           sizeof(struct sockaddr_un))) != OK)
+               return rc;
 
-       /* do some basic sanity checks on the address */
-       if (addr.sun_family != AF_UNIX || addr.sun_path[0] == '\0') {
-               /* bad address */
+       /* Do some basic sanity checks on the address. */
+       if (addr.sun_family != AF_UNIX || addr.sun_path[0] == '\0')
                return EINVAL;
-       }
 
-       rc = check_perms(minor, &addr);
-       if (rc != OK) {
+       if ((rc = vfs_check_perms(uds_fd_table[minor].owner, &addr)) != OK)
                return rc;
-       }
 
-       memcpy(&(uds_fd_table[minor].target), &addr,
-                                       sizeof(struct sockaddr_un));
+       memcpy(&uds_fd_table[minor].target, &addr, sizeof(struct sockaddr_un));
 
        return OK;
 }
@@ -1042,78 +612,57 @@ do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 static int
 do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
-       int rc;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_recvfrom() call_count=%d\n", minor,
-               ++call_count);
-#endif
+       dprintf(("UDS: do_recvfrom(%d)\n", minor));
 
-       rc = sys_safecopyto(endpt, grant, 0,
-               (vir_bytes) &uds_fd_table[minor].source,
-               sizeof(struct sockaddr_un));
-
-       return rc ? EIO : OK;
+       return sys_safecopyto(endpt, grant, 0,
+           (vir_bytes) &uds_fd_table[minor].source,
+           sizeof(struct sockaddr_un));
 }
 
 static int
 msg_control_read(struct msg_control *msg_ctrl, struct ancillary *data,
        devminor_t minor)
 {
-       int rc;
+       int i, rc, nfds, totalfds;
        struct msghdr msghdr;
        struct cmsghdr *cmsg = NULL;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] msg_control_read() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: msg_control_read(%d)\n", minor));
 
-       data->nfiledes = 0;
+       /* Obtain this socket's credentials. */
+       if ((rc = getnucred(uds_fd_table[minor].owner, &data->cred)) < 0)
+               return -errno;
+
+       dprintf(("UDS: minor=%d cred={%d,%d,%d}\n", minor, data->cred.pid,
+           data->cred.uid, data->cred.gid));
+
+       totalfds = data->nfiledes;
 
        memset(&msghdr, '\0', sizeof(struct msghdr));
        msghdr.msg_control = msg_ctrl->msg_control;
        msghdr.msg_controllen = msg_ctrl->msg_controllen;
 
-       for(cmsg = CMSG_FIRSTHDR(&msghdr); cmsg != NULL;
-                                       cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
-
-               if (cmsg->cmsg_level == SOL_SOCKET &&
-                                       cmsg->cmsg_type == SCM_RIGHTS) {
-
-                       int i;
-                       int nfds =
-                               MIN((cmsg->cmsg_len-CMSG_LEN(0))/sizeof(int),
-                                                               OPEN_MAX);
-
-                       for (i = 0; i < nfds; i++) {
-                               if (data->nfiledes == OPEN_MAX) {
-                                       return EOVERFLOW;
-                               }
-
-                               data->fds[data->nfiledes] =
-                                       ((int *) CMSG_DATA(cmsg))[i];
-#if DEBUG == 1
-                               printf("(uds) [%d] fd[%d]=%d\n", minor,
-                               data->nfiledes, data->fds[data->nfiledes]);
-#endif
-                               data->nfiledes++;
-                       }
+       for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg != NULL;
+           cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
+               if (cmsg->cmsg_level != SOL_SOCKET ||
+                   cmsg->cmsg_type != SCM_RIGHTS)
+                       continue;
+
+               nfds = MIN((cmsg->cmsg_len-CMSG_LEN(0))/sizeof(int), OPEN_MAX);
+
+               for (i = 0; i < nfds; i++) {
+                       if (totalfds == OPEN_MAX)
+                               return EOVERFLOW;
+
+                       data->fds[totalfds] = ((int *) CMSG_DATA(cmsg))[i];
+                       dprintf(("UDS: minor=%d fd[%d]=%d\n", minor, totalfds,
+                           data->fds[totalfds]));
+                       totalfds++;
                }
        }
 
-       /* obtain this socket's credentials */
-       rc = getnucred(uds_fd_table[minor].owner, &(data->cred));
-       if (rc == -1) {
-               return errno;
-       }
-#if DEBUG == 1
-       printf("(uds) [%d] cred={%d,%d,%d}\n", minor,
-               data->cred.pid, data->cred.uid,
-               data->cred.gid);
-#endif
+       data->nfiledes = totalfds;
+
        return OK;
 }
 
@@ -1122,29 +671,20 @@ send_fds(devminor_t minor, struct ancillary *data)
 {
        int rc, i, j;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] send_fds() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: send_fds(%d)\n", minor));
 
-       /* verify the file descriptors and get their filps. */
+       /* Verify the file descriptors and get their filps. */
        for (i = 0; i < data->nfiledes; i++) {
-               data->filps[i] = verify_fd(uds_fd_table[minor].owner,
-                                               data->fds[i]);
-
-               if (data->filps[i] == NULL) {
-                       return EINVAL;
-               }
+               if ((rc = vfs_verify_fd(uds_fd_table[minor].owner,
+                   data->fds[i], &data->filps[i])) != OK)
+                       return rc;
        }
 
-       /* set them as in-flight */
+       /* Set them as in-flight. */
        for (i = 0; i < data->nfiledes; i++) {
-               rc = set_filp(data->filps[i]);
-               if (rc != OK) {
-                       /* revert set_filp() calls */
-                       for (j = i; j >= 0; j--) {
-                               put_filp(data->filps[j]);
-                       }
+               if ((rc = vfs_set_filp(data->filps[i])) != OK) {
+                       for (j = i - 1; j >= 0; j--)
+                               vfs_put_filp(data->filps[j]);   /* revert */
                        return rc;
                }
        }
@@ -1153,27 +693,22 @@ send_fds(devminor_t minor, struct ancillary *data)
 }
 
 /*
- * This function calls put_filp() for all of the FDs in data.
- * This is used when a Unix Domain Socket is closed and there
- * exists references to file descriptors that haven't been received
- * with recvmsg().
+ * This function calls put_filp() for all of the FDs in data.  This is used
+ * when a Unix Domain Socket is closed and there exists references to file
+ * descriptors that haven't been received with recvmsg().
  */
 int
 uds_clear_fds(devminor_t minor, struct ancillary *data)
 {
        int i;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_clear_fds() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: uds_clear_fds(%d)\n", minor));
 
        for (i = 0; i < data->nfiledes; i++) {
-               put_filp(data->filps[i]);
-#if DEBUG == 1
-               printf("(uds) uds_clear_fds() => %d\n", data->fds[i]);
-#endif
+               dprintf(("UDS: uds_clear_fds() => %d\n", data->fds[i]));
+
+               vfs_put_filp(data->filps[i]);
+
                data->fds[i] = -1;
                data->filps[i] = NULL;
        }
@@ -1192,11 +727,7 @@ recv_fds(devminor_t minor, struct ancillary *data,
        struct cmsghdr *cmsg;
        endpoint_t to_ep;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] recv_fds() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: recv_fds(%d)\n", minor));
 
        msghdr.msg_control = msg_ctrl->msg_control;
        msghdr.msg_controllen = msg_ctrl->msg_controllen;
@@ -1208,28 +739,27 @@ recv_fds(devminor_t minor, struct ancillary *data,
 
        to_ep = uds_fd_table[minor].owner;
 
-       /* copy to the target endpoint */
+       /* Copy to the target endpoint. */
        for (i = 0; i < data->nfiledes; i++) {
-               rc = copy_filp(to_ep, data->filps[i]);
-               if (rc < 0) {
-                       /* revert set_filp() calls */
-                       for (j = 0; j < data->nfiledes; j++) {
-                               put_filp(data->filps[j]);
-                       }
-                       /* revert copy_filp() calls */
-                       for (j = i; j >= 0; j--) {
-                               cancel_fd(to_ep, data->fds[j]);
-                       }
+               if ((rc = vfs_copy_filp(to_ep, data->filps[i])) < 0) {
+                       /* Revert vfs_set_filp() calls. */
+                       for (j = 0; j < data->nfiledes; j++)
+                               vfs_put_filp(data->filps[j]);
+
+                       /* Revert vfs_copy_filp() calls. */
+                       for (j = i - 1; j >= 0; j--)
+                               vfs_cancel_fd(to_ep, data->fds[j]);
+
                        return rc;
                }
                data->fds[i] = rc; /* data->fds[i] now has the new FD */
        }
 
        for (i = 0; i < data->nfiledes; i++) {
-               put_filp(data->filps[i]);
-#if DEBUG == 1
-               printf("(uds) recv_fds() => %d\n", data->fds[i]);
-#endif
+               vfs_put_filp(data->filps[i]);
+
+               dprintf(("UDS: recv_fds() => %d\n", data->fds[i]));
+
                ((int *)CMSG_DATA(cmsg))[i] = data->fds[i];
                data->fds[i] = -1;
                data->filps[i] = NULL;
@@ -1247,24 +777,19 @@ recv_cred(devminor_t minor, struct ancillary *data,
        struct msghdr msghdr;
        struct cmsghdr *cmsg;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] recv_cred() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: recv_cred(%d)\n", minor));
 
        msghdr.msg_control = msg_ctrl->msg_control;
        msghdr.msg_controllen = msg_ctrl->msg_controllen;
 
        cmsg = CMSG_FIRSTHDR(&msghdr);
-       if (cmsg->cmsg_len > 0) {
+       if (cmsg->cmsg_len > 0)
                cmsg = CMSG_NXTHDR(&msghdr, cmsg);
-       }
 
        cmsg->cmsg_len = CMSG_LEN(sizeof(struct uucred));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_CREDENTIALS;
-       memcpy(CMSG_DATA(cmsg), &(data->cred), sizeof(struct uucred));
+       memcpy(CMSG_DATA(cmsg), &data->cred, sizeof(struct uucred));
 
        return OK;
 }
@@ -1275,67 +800,54 @@ do_sendmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
        int peer, rc, i;
        struct msg_control msg_ctrl;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_sendmsg() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: do_sendmsg(%d)\n", minor));
 
        memset(&msg_ctrl, '\0', sizeof(struct msg_control));
 
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl,
-               sizeof(struct msg_control));
-
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl,
+           sizeof(struct msg_control))) != OK)
+               return rc;
 
-       /* locate peer */
+       /* Locate the peer. */
        peer = -1;
        if (uds_fd_table[minor].type == SOCK_DGRAM) {
                if (uds_fd_table[minor].target.sun_path[0] == '\0' ||
-                       uds_fd_table[minor].target.sun_family != AF_UNIX) {
-
+                   uds_fd_table[minor].target.sun_family != AF_UNIX)
                        return EDESTADDRREQ;
-               }
 
                for (i = 0; i < NR_FDS; i++) {
-
-                       /* look for a SOCK_DGRAM socket that is bound on
-                        * the target address
+                       /*
+                        * Look for a SOCK_DGRAM socket that is bound on the
+                        * target address.
                         */
                        if (uds_fd_table[i].type == SOCK_DGRAM &&
-                               uds_fd_table[i].addr.sun_family == AF_UNIX &&
-                               !strncmp(uds_fd_table[minor].target.sun_path,
-                               uds_fd_table[i].addr.sun_path, UNIX_PATH_MAX)){
-
+                           uds_fd_table[i].addr.sun_family == AF_UNIX &&
+                           !strncmp(uds_fd_table[minor].target.sun_path,
+                           uds_fd_table[i].addr.sun_path, UNIX_PATH_MAX)) {
                                peer = i;
                                break;
                        }
                }
 
-               if (peer == -1) {
+               if (peer == -1)
                        return ENOENT;
-               }
        } else {
                peer = uds_fd_table[minor].peer;
-               if (peer == -1) {
+               if (peer == -1)
                        return ENOTCONN;
-               }
        }
 
-#if DEBUG == 1
-       printf("(uds) [%d] sendmsg() -- peer=%d\n", minor, peer);
-#endif
-       /* note: it's possible that there is already some file
-        * descriptors in ancillary_data if the peer didn't call
-        * recvmsg() yet. That's okay. The receiver will
-        * get the current file descriptors plus the new ones.
+       dprintf(("UDS: sendmsg(%d) -- peer=%d\n", minor, peer));
+
+       /*
+        * Note: it's possible that there is already some file descriptors in
+        * ancillary_data if the peer didn't call recvmsg() yet.  That's okay.
+        * The receiver will get the current file descriptors plus the new
+        * ones.
         */
-       rc = msg_control_read(&msg_ctrl, &uds_fd_table[peer].ancillary_data,
-                                                               minor);
-       if (rc != OK) {
+       if ((rc = msg_control_read(&msg_ctrl,
+           &uds_fd_table[peer].ancillary_data, minor)) != OK)
                return rc;
-       }
 
        return send_fds(minor, &uds_fd_table[peer].ancillary_data);
 }
@@ -1345,64 +857,53 @@ do_recvmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
 {
        int rc;
        struct msg_control msg_ctrl;
-       socklen_t controllen_avail = 0;
-       socklen_t controllen_needed = 0;
-       socklen_t controllen_desired = 0;
-
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] do_sendmsg() call_count=%d\n", minor, ++call_count);
-       printf("(uds) [%d] CREDENTIALS {pid:%d,uid:%d,gid:%d}\n", minor,
-                               uds_fd_table[minor].ancillary_data.cred.pid,
-                               uds_fd_table[minor].ancillary_data.cred.uid,
-                               uds_fd_table[minor].ancillary_data.cred.gid);
-#endif
+       socklen_t clen_avail = 0;
+       socklen_t clen_needed = 0;
+       socklen_t clen_desired = 0;
+
+       dprintf(("UDS: do_recvmsg(%d)\n", minor));
+       dprintf(("UDS: minor=%d credentials={pid:%d,uid:%d,gid:%d}\n", minor,
+           uds_fd_table[minor].ancillary_data.cred.pid,
+           uds_fd_table[minor].ancillary_data.cred.uid,
+           uds_fd_table[minor].ancillary_data.cred.gid));
 
        memset(&msg_ctrl, '\0', sizeof(struct msg_control));
 
-       /* get the msg_control from the user, it will include the
+       /*
+        * Get the msg_control from the user.  It will include the
         * amount of space the user has allocated for control data.
         */
-       rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl,
-               sizeof(struct msg_control));
-
-       if (rc != OK) {
-               return EIO;
-       }
+       if ((rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl,
+           sizeof(struct msg_control))) != OK)
+               return rc;
 
-       controllen_avail = MIN(msg_ctrl.msg_controllen, MSG_CONTROL_MAX);
+       clen_avail = MIN(msg_ctrl.msg_controllen, MSG_CONTROL_MAX);
 
        if (uds_fd_table[minor].ancillary_data.nfiledes > 0) {
-               controllen_needed = CMSG_LEN(sizeof(int) *
-                               (uds_fd_table[minor].ancillary_data.nfiledes));
+               clen_needed = CMSG_LEN(sizeof(int) *
+                   uds_fd_table[minor].ancillary_data.nfiledes);
        }
 
        /* if there is room we also include credentials */
-       controllen_desired = controllen_needed +
-                               CMSG_LEN(sizeof(struct uucred));
+       clen_desired = clen_needed + CMSG_LEN(sizeof(struct uucred));
 
-       if (controllen_needed > controllen_avail) {
+       if (clen_needed > clen_avail)
                return EOVERFLOW;
-       }
 
        rc = recv_fds(minor, &uds_fd_table[minor].ancillary_data, &msg_ctrl);
-       if (rc != OK) {
+       if (rc != OK)
                return rc;
-       }
 
-       if (controllen_desired <= controllen_avail) {
+       if (clen_desired <= clen_avail) {
                rc = recv_cred(minor, &uds_fd_table[minor].ancillary_data,
-                                                               &msg_ctrl);
-               if (rc != OK) {
+                   &msg_ctrl);
+               if (rc != OK)
                        return rc;
-               }
        }
 
-       /* send the user the control data */
-       rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &msg_ctrl,
-               sizeof(struct msg_control));
-
-       return rc ? EIO : OK;
+       /* Send the control data to the user. */
+       return sys_safecopyto(endpt, grant, 0, (vir_bytes) &msg_ctrl,
+           sizeof(struct msg_control));
 }
 
 int
@@ -1411,132 +912,133 @@ uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
 {
        int rc;
 
-       switch (request) {      /* Handle the ioctl(2) command */
+       switch (request) {
        case NWIOSUDSCONN:
-               /* connect to a listening socket -- connect() */
+               /* Connect to a listening socket -- connect(). */
                rc = do_connect(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSACCEPT:
-               /* accept an incoming connection -- accept() */
+               /* Accept an incoming connection -- accept(). */
                rc = do_accept(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSBLOG:
-               /* set the backlog_size and put the socket into the listening
-                * state -- listen()
+               /*
+                * Set the backlog_size and put the socket into the listening
+                * state -- listen().
                 */
                rc = do_listen(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSTYPE:
-               /* set the type for this socket (i.e. SOCK_STREAM, SOCK_DGRAM,
-                * etc) -- socket()
-                */
+               /* Set the SOCK_ type for this socket -- socket(). */
                rc = do_socket(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSADDR:
-               /* set the address for this socket -- bind() */
+               /* Set the address for this socket -- bind(). */
                rc = do_bind(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSADDR:
-               /* get the address for this socket -- getsockname() */
+               /* Get the address for this socket -- getsockname(). */
                rc = do_getsockname(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSPADDR:
-               /* get the address for the peer -- getpeername() */
+               /* Get the address for the peer -- getpeername(). */
                rc = do_getpeername(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSSHUT:
-               /* shutdown a socket for reading, writing, or both --
-                * shutdown()
+               /*
+                * Shut down a socket for reading, writing, or both --
+                * shutdown().
                 */
                rc = do_shutdown(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSPAIR:
-               /* connect two sockets -- socketpair() */
+               /* Connect two sockets -- socketpair(). */
                rc = do_socketpair(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSSOTYPE:
-               /* get socket type -- getsockopt(SO_TYPE) */
+               /* Get socket type -- getsockopt(SO_TYPE). */
                rc = do_getsockopt_sotype(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSPEERCRED:
-               /* get peer endpoint -- getsockopt(SO_PEERCRED) */
+               /* Get peer endpoint -- getsockopt(SO_PEERCRED). */
                rc = do_getsockopt_peercred(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSTADDR:
-               /* set target address -- sendto() */
+               /* Set target address -- sendto(). */
                rc = do_sendto(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSFADDR:
-               /* get from address -- recvfrom() */
+               /* Get from address -- recvfrom(). */
                rc = do_recvfrom(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSSNDBUF:
-               /* get the send buffer size -- getsockopt(SO_SNDBUF) */
+               /* Get the send buffer size -- getsockopt(SO_SNDBUF). */
                rc = do_getsockopt_sndbuf(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSSNDBUF:
-               /* set the send buffer size -- setsockopt(SO_SNDBUF) */
+               /* Set the send buffer size -- setsockopt(SO_SNDBUF). */
                rc = do_setsockopt_sndbuf(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSRCVBUF:
-               /* get the send buffer size -- getsockopt(SO_SNDBUF) */
+               /* Get the send buffer size -- getsockopt(SO_SNDBUF). */
                rc = do_getsockopt_rcvbuf(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSRCVBUF:
-               /* set the send buffer size -- setsockopt(SO_SNDBUF) */
+               /* Set the send buffer size -- setsockopt(SO_SNDBUF). */
                rc = do_setsockopt_rcvbuf(minor, endpt, grant);
 
                break;
 
        case NWIOSUDSCTRL:
-               /* set the control data -- sendmsg() */
+               /* Set the control data -- sendmsg(). */
                rc = do_sendmsg(minor, endpt, grant);
 
                break;
 
        case NWIOGUDSCTRL:
-               /* set the control data -- recvmsg() */
+               /* Set the control data -- recvmsg(). */
                rc = do_recvmsg(minor, endpt, grant);
 
                break;
 
        default:
-               /* the IOCTL command is not valid for /dev/uds -- this happens
-                * a lot and is normal. a lot of libc functions determine the
-                * socket type with IOCTLs. Any not for us simply get an ENOTTY
-                * response.
+               /*
+                * The IOCTL command is not valid for /dev/uds -- this happens
+                * a lot and is normal.  A lot of libc functions determine the
+                * socket type with IOCTLs.  Any unrecognized requests simply
+                * get an ENOTTY response.
                 */
 
                rc = ENOTTY;
index b5163be6733a4e64b403794671a1fd18f43894f7..191eb1fd567423af54bb395f0abb2ff053b4749d 100644 (file)
@@ -50,32 +50,23 @@ uds_open(devminor_t UNUSED(orig_minor), int access,
        endpoint_t user_endpt)
 {
        devminor_t minor;
-       int i;
        char *buf;
+       int i;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [-] uds_open() call_count=%d\n", ++call_count);
-       printf("Endpoint: 0x%x\n", user_endpt);
-#endif
+       dprintf(("UDS: uds_open() from %d\n", user_endpt));
 
        /*
         * Find a slot in the descriptor table for the new descriptor.
         * The index of the descriptor in the table will be returned.
         * Subsequent calls to read/write/close/ioctl/etc will use this
-        * minor number. The minor number must be different from the
-        * the /dev/uds device's minor number (currently 0).
+        * minor number.  The minor number must be different from the
+        * the /dev/uds device's minor number (0).
         */
-       minor = -1; /* to trap error */
-
-       for (i = 1; i < NR_FDS; i++) {
-               if (uds_fd_table[i].state == UDS_FREE) {
-                       minor = i;
+       for (minor = 1; minor < NR_FDS; minor++)
+               if (uds_fd_table[minor].state == UDS_FREE)
                        break;
-               }
-       }
 
-       if (minor == -1)
+       if (minor == NR_FDS)
                return ENFILE;
 
        /*
@@ -84,69 +75,40 @@ uds_open(devminor_t UNUSED(orig_minor), int access,
         * in use.  We use mmap instead of malloc to allow the memory to be
         * actually freed later.
         */
-       if ((buf = minix_mmap(NULL, PIPE_BUF, PROT_READ | PROT_WRITE,
+       if ((buf = minix_mmap(NULL, UDS_BUF, PROT_READ | PROT_WRITE,
            MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
                return ENOMEM;
 
-       /* mark this one as 'in use' so that it doesn't get assigned to
-        * another socket
+       /*
+        * Allocate the socket, and set its initial parameters.
         */
        uds_fd_table[minor].state = UDS_INUSE;
-
-       /* set the socket owner */
        uds_fd_table[minor].owner = user_endpt;
-
-       /* setup select(2) framework */
        uds_fd_table[minor].sel_endpt = NONE;
        uds_fd_table[minor].sel_ops = 0;
        uds_fd_table[minor].buf = buf;
        uds_fd_table[minor].pos = 0;
-
-       /* the PIPE is initially empty */
        uds_fd_table[minor].size = 0;
-
-       /* the default for a new socket is to allow reading and writing.
-        * shutdown(2) will remove one or both flags.
-        */
-       uds_fd_table[minor].mode = R_BIT | W_BIT;
-
-       /* In libc socket(2) sets this to the actual value later with the
-        * NWIOSUDSTYPE ioctl().
-        */
+       uds_fd_table[minor].mode = UDS_R | UDS_W;
        uds_fd_table[minor].type = -1;
 
-       /* Clear the backlog by setting each entry to -1 */
-       for (i = 0; i < UDS_SOMAXCONN; i++) {
-               /* initially no connections are pending */
+       for (i = 0; i < UDS_SOMAXCONN; i++)
                uds_fd_table[minor].backlog[i] = -1;
-       }
+       uds_fd_table[minor].backlog_size = UDS_SOMAXCONN;
 
-       memset(&uds_fd_table[minor].ancillary_data, '\0', sizeof(struct
-                                                               ancillary));
-       for (i = 0; i < OPEN_MAX; i++) {
+       memset(&uds_fd_table[minor].ancillary_data, '\0',
+           sizeof(struct ancillary));
+       for (i = 0; i < OPEN_MAX; i++)
                uds_fd_table[minor].ancillary_data.fds[i] = -1;
-       }
 
-       /* default the size to UDS_SOMAXCONN */
-       uds_fd_table[minor].backlog_size = UDS_SOMAXCONN;
-
-       /* the socket isn't listening for incoming connections until
-        * listen(2) is called
-        */
        uds_fd_table[minor].listening = 0;
-
-       /* initially the socket is not connected to a peer */
        uds_fd_table[minor].peer = -1;
-
-       /* there isn't a child waiting to be accept(2)'d */
        uds_fd_table[minor].child = -1;
 
-       /* initially the socket is not bound or listening on an address */
-       memset(&(uds_fd_table[minor].addr), '\0', sizeof(struct sockaddr_un));
-       memset(&(uds_fd_table[minor].source), '\0', sizeof(struct sockaddr_un));
-       memset(&(uds_fd_table[minor].target), '\0', sizeof(struct sockaddr_un));
+       memset(&uds_fd_table[minor].addr, '\0', sizeof(struct sockaddr_un));
+       memset(&uds_fd_table[minor].source, '\0', sizeof(struct sockaddr_un));
+       memset(&uds_fd_table[minor].target, '\0', sizeof(struct sockaddr_un));
 
-       /* Initially the socket isn't suspended. */
        uds_fd_table[minor].suspended = UDS_NOT_SUSPENDED;
 
        return CDEV_CLONED | minor;
@@ -157,41 +119,32 @@ uds_close(devminor_t minor)
 {
        int peer;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_close() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_close(%d)\n", minor));
 
        if (minor < 0 || minor >= NR_FDS) return ENXIO;
 
-       if (uds_fd_table[minor].state != UDS_INUSE) {
-               /* attempted to close a socket that hasn't been opened --
-                * something is very wrong :(
-                */
+       if (uds_fd_table[minor].state != UDS_INUSE)
                return EINVAL;
-       }
 
-       /* if the socket is connected, disconnect it */
+       /* If the socket is connected, disconnect it. */
        if (uds_fd_table[minor].peer != -1) {
                peer = uds_fd_table[minor].peer;
 
-               /* set peer of this peer to -1 */
                uds_fd_table[peer].peer = -1;
 
-               /* error to pass to peer */
+               /* The error to pass to the peer. */
                uds_fd_table[peer].err = ECONNRESET;
 
-               /* if peer was blocked on I/O revive peer */
+               /* If the peer was blocked on I/O, revive it. */
                if (uds_fd_table[peer].suspended != UDS_NOT_SUSPENDED)
                        uds_unsuspend(peer);
        }
 
-       if (uds_fd_table[minor].ancillary_data.nfiledes > 0) {
+       if (uds_fd_table[minor].ancillary_data.nfiledes > 0)
                uds_clear_fds(minor, &uds_fd_table[minor].ancillary_data);
-       }
 
        /* Release the memory for the ring buffer. */
-       minix_munmap(uds_fd_table[minor].buf, PIPE_BUF);
+       minix_munmap(uds_fd_table[minor].buf, UDS_BUF);
 
        /* Set the socket back to its original UDS_FREE state. */
        memset(&uds_fd_table[minor], '\0', sizeof(uds_fd_t));
@@ -211,33 +164,25 @@ uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
        unsigned int ready_ops;
        int i, bytes, watch;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_select() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_select(%d)\n", minor));
 
        if (minor < 0 || minor >= NR_FDS) return ENXIO;
 
-       if (uds_fd_table[minor].state != UDS_INUSE) {
-               /* attempted to select on a socket that hasn't been opened --
-                * something is very wrong :(
-                */
+       if (uds_fd_table[minor].state != UDS_INUSE)
                return EINVAL;
-       }
 
        watch = (ops & CDEV_NOTIFY);
        ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
 
        ready_ops = 0;
 
-       /* check if there is data available to read */
+       /* Check if there is data available to read. */
        if (ops & CDEV_OP_RD) {
                bytes = uds_perform_read(minor, NONE, GRANT_INVALID, 1, 1);
                if (bytes > 0) {
-                       /* there is data in the pipe for us to read */
-                       ready_ops |= CDEV_OP_RD;
+                       ready_ops |= CDEV_OP_RD;        /* data available */
                } else if (uds_fd_table[minor].listening == 1) {
-                       /* check for pending connections */
+                       /* Check for pending connections. */
                        for (i = 0; i < uds_fd_table[minor].backlog_size; i++)
                        {
                                if (uds_fd_table[minor].backlog[i] != -1) {
@@ -246,22 +191,19 @@ uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
                                }
                        }
                } else if (bytes != SUSPEND) {
-                       ready_ops |= CDEV_OP_RD;
+                       ready_ops |= CDEV_OP_RD;        /* error */
                }
        }
 
-       /* check if we can write without blocking */
+       /* Check if we can write without blocking. */
        if (ops & CDEV_OP_WR) {
                bytes = uds_perform_write(minor, NONE, GRANT_INVALID, 1, 1);
-               if (bytes != 0 && bytes != SUSPEND) {
-                       /* There is room to write or there is an error
-                        * condition.
-                        */
+               if (bytes != 0 && bytes != SUSPEND)
                        ready_ops |= CDEV_OP_WR;
-               }
        }
 
-       /* If not all requested ops were ready, and the caller requests to be
+       /*
+        * If not all requested ops were ready, and the caller requests to be
         * notified about changes, we add the remaining ops to the saved set.
         */
        ops &= ~ready_ops;
@@ -280,64 +222,50 @@ uds_perform_read(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
        size_t pos, subsize;
        int r, peer;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_perform_read() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: uds_perform_read(%d)\n", minor));
 
        peer = uds_fd_table[minor].peer;
 
-       /* skip reads and writes of 0 (or less!) bytes */
-       if (size <= 0) {
+       /* Skip reads of zero bytes. */
+       if (size == 0)
                return 0;
-       }
 
-       /* check if we are allowed to read */
-       if (!(uds_fd_table[minor].mode & R_BIT)) {
-               /* socket is shutdown for reading */
+       /* Check if the socket isn't shut down for reads. */
+       if (!(uds_fd_table[minor].mode & UDS_R))
                return EPIPE;
-       }
 
        if (uds_fd_table[minor].size == 0) {
                if (peer == -1) {
-                       /* We're not connected. That's only a problem when this
-                        * socket is connection oriented. */
+                       /*
+                        * We're not connected. That's only a problem when this
+                        * socket is connection oriented.
+                        */
                        if (uds_fd_table[minor].type == SOCK_STREAM ||
                            uds_fd_table[minor].type == SOCK_SEQPACKET) {
                                if (uds_fd_table[minor].err == ECONNRESET) {
                                        if (!pretend)
                                                uds_fd_table[minor].err = 0;
                                        return ECONNRESET;
-                               } else {
+                               } else
                                        return ENOTCONN;
-                               }
                        }
                }
 
-               /* Check if process is reading from a closed pipe */
-               if (peer != -1 && !(uds_fd_table[peer].mode & W_BIT) &&
-                       uds_fd_table[minor].size == 0) {
+               /* Check if process is reading from a closed pipe. */
+               if (peer != -1 && !(uds_fd_table[peer].mode & UDS_W) &&
+                   uds_fd_table[minor].size == 0)
                        return 0;
-               }
 
-               if (pretend) {
+               if (pretend)
                        return SUSPEND;
-               }
 
-               /* maybe a process is blocked waiting to write? if
-                * needed revive the writer
-                */
                if (peer != -1 &&
                        uds_fd_table[peer].suspended == UDS_SUSPENDED_WRITE)
-                       uds_unsuspend(peer);
+                       panic("writer blocked on empty socket");
 
-#if DEBUG == 1
-               printf("(uds) [%d] suspending read request\n", minor);
-#endif
-               /* Process is reading from an empty pipe,
-                * suspend it so some bytes can be written
-                */
+               dprintf(("UDS: suspending read request on %d\n", minor));
+
+               /* Process is reading from an empty pipe.  Suspend it. */
                return EDONTREPLY;
        }
 
@@ -351,7 +279,7 @@ uds_perform_read(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
        /* Get the data from the tail of the ring buffer. */
        pos = uds_fd_table[minor].pos;
 
-       subsize = PIPE_BUF - pos;
+       subsize = UDS_BUF - pos;
        if (subsize > size)
                subsize = size;
 
@@ -367,35 +295,27 @@ uds_perform_read(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
        }
 
        /* Advance the buffer tail. */
-       uds_fd_table[minor].pos = (pos + size) % PIPE_BUF;
+       uds_fd_table[minor].pos = (pos + size) % UDS_BUF;
        uds_fd_table[minor].size -= size;
 
-       /* if we have 0 unread bytes, move the data pointer back to the
-        * start of the buffer
-        */
-       if (uds_fd_table[minor].size == 0) {
+       /* Reset position if the buffer is empty (it may save a copy call). */
+       if (uds_fd_table[minor].size == 0)
                uds_fd_table[minor].pos = 0;
-       }
 
-       /* maybe a big write was waiting for us to read some data, if
-        * needed revive the writer
-        */
+       /* See if we can wake up a blocked writer. */
        if (peer != -1 && uds_fd_table[peer].suspended == UDS_SUSPENDED_WRITE)
                uds_unsuspend(peer);
 
-       /* see if peer is blocked on select() and a write is possible (from
-        * peer to minor); if the peer wants to know about write being possible
-        * and it doesn't know about it already, then let the peer know.
-        */
+       /* See if we can satisfy an ongoing select. */
        if (peer != -1 && (uds_fd_table[peer].sel_ops & CDEV_OP_WR) &&
-           size > 0) {
-               /* a write on peer is possible now */
+           uds_fd_table[minor].size < UDS_BUF) {
+               /* A write on the peer is possible now. */
                chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
-                       CDEV_OP_WR);
+                   CDEV_OP_WR);
                uds_fd_table[peer].sel_ops &= ~CDEV_OP_WR;
        }
 
-       return size; /* return number of bytes read */
+       return size; /* number of bytes read */
 }
 
 static ssize_t
@@ -405,120 +325,104 @@ uds_perform_write(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
        size_t subsize, pos;
        int i, r, peer;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_perform_write() call_count=%d\n", minor,
-                                                       ++call_count);
-#endif
+       dprintf(("UDS: uds_perform_write(%d)\n", minor));
 
        /* Skip writes of zero bytes. */
        if (size == 0)
                return 0;
 
-       /* check if we are allowed to write */
-       if (!(uds_fd_table[minor].mode & W_BIT)) {
-               /* socket is shutdown for writing */
+       /* Check if the socket isn't shut down for writes. */
+       if (!(uds_fd_table[minor].mode & UDS_W))
                return EPIPE;
-       }
 
-       if (size > PIPE_BUF) {
-               /* message is too big to ever write to the PIPE */
+       /* We cannot handle input beyond the buffer size. */
+       if (size > UDS_BUF)
                return EMSGSIZE;
-       }
 
        if (uds_fd_table[minor].type == SOCK_STREAM ||
-                       uds_fd_table[minor].type == SOCK_SEQPACKET) {
-               /* if we're writing with a connection oriented socket,
-                * then it needs a peer to write to
+           uds_fd_table[minor].type == SOCK_SEQPACKET) {
+               /*
+                * If we're writing to a connection-oriented socket,
+                * then it needs a peer to write to.
                 */
-               if (uds_fd_table[minor].peer == -1) {
-                       if (uds_fd_table[minor].err == ECONNRESET) {
+               peer = uds_fd_table[minor].peer;
 
-                               uds_fd_table[minor].err = 0;
+               if (peer == -1) {
+                       if (uds_fd_table[minor].err == ECONNRESET) {
+                               if (!pretend)
+                                       uds_fd_table[minor].err = 0;
                                return ECONNRESET;
-                       } else {
+                       } else
                                return ENOTCONN;
-                       }
-               } else {
-                       peer = uds_fd_table[minor].peer;
                }
        } else /* uds_fd_table[minor].type == SOCK_DGRAM */ {
                peer = -1;
 
-               /* locate the "peer" we want to write to */
+               /* Locate the "peer" we want to write to. */
                for (i = 0; i < NR_FDS; i++) {
-
-                       /* look for a SOCK_DGRAM socket that is bound on
-                        * the target address
+                       /*
+                        * Look for a SOCK_DGRAM socket that is bound on
+                        * the target address.
                         */
                        if (uds_fd_table[i].type == SOCK_DGRAM &&
-                               uds_fd_table[i].addr.sun_family == AF_UNIX &&
-                               !strncmp(uds_fd_table[minor].target.sun_path,
-                               uds_fd_table[i].addr.sun_path, UNIX_PATH_MAX)) {
-
+                           uds_fd_table[i].addr.sun_family == AF_UNIX &&
+                           !strncmp(uds_fd_table[minor].target.sun_path,
+                           uds_fd_table[i].addr.sun_path, UNIX_PATH_MAX)) {
                                peer = i;
                                break;
                        }
                }
-       }
 
-       if (peer == -1) {
-               if (pretend)
-                       return SUSPEND;
+               if (peer == -1) {
+                       if (pretend)
+                               return SUSPEND;
 
-               return ENOENT;
+                       return ENOENT;
+               }
        }
 
-       /* check if we write to a closed pipe */
-       if (!(uds_fd_table[peer].mode & R_BIT)) {
+       /* Check if we write to a closed pipe. */
+       if (!(uds_fd_table[peer].mode & UDS_R))
                return EPIPE;
-       }
 
-       /* we have to preserve the boundary for DGRAM. if there's
-        * already a packet waiting, discard it silently and pretend
-        * it was written.
+       /*
+        * We have to preserve the boundary for DGRAM.  If there's already a
+        * packet waiting, discard it silently and pretend it was written.
         */
-       if(uds_fd_table[minor].type == SOCK_DGRAM &&
-               uds_fd_table[peer].size > 0) {
+       if (uds_fd_table[minor].type == SOCK_DGRAM &&
+           uds_fd_table[peer].size > 0)
                return size;
-       }
 
        /*
         * Check if the ring buffer is already full, and if the SEQPACKET
         * message wouldn't write to an empty buffer.
         */
-       if (uds_fd_table[peer].size == PIPE_BUF ||
+       if (uds_fd_table[peer].size == UDS_BUF ||
            (uds_fd_table[minor].type == SOCK_SEQPACKET &&
            uds_fd_table[peer].size > 0)) {
-               if (pretend) {
+               if (pretend)
                        return SUSPEND;
-               }
 
-               /* if needed revive the reader */
                if (uds_fd_table[peer].suspended == UDS_SUSPENDED_READ)
-                       uds_unsuspend(peer);
+                       panic("reader blocked on full socket");
 
-#if DEBUG == 1
-               printf("(uds) [%d] suspending write request\n", minor);
-#endif
+               dprintf(("UDS: suspending write request on %d\n", minor));
 
-               /* Process is reading from an empty pipe,
-                * suspend it so some bytes can be written
-                */
+               /* Process is reading from an empty pipe.  Suspend it. */
                return EDONTREPLY;
        }
 
        /* How much can we add to the ring buffer? */
-       if (size > PIPE_BUF - uds_fd_table[peer].size)
-               size = PIPE_BUF - uds_fd_table[peer].size;
+       if (size > UDS_BUF - uds_fd_table[peer].size)
+               size = UDS_BUF - uds_fd_table[peer].size;
 
        if (pretend)
                return size;
 
        /* Put the data at the head of the ring buffer. */
-       pos = (uds_fd_table[peer].pos + uds_fd_table[peer].size) % PIPE_BUF;
+       pos = (uds_fd_table[peer].pos + uds_fd_table[peer].size) % UDS_BUF;
 
-       subsize = PIPE_BUF - pos;
+       subsize = UDS_BUF - pos;
        if (subsize > size)
                subsize = size;
 
@@ -535,28 +439,25 @@ uds_perform_write(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
        /* Advance the buffer head. */
        uds_fd_table[peer].size += size;
 
-       /* fill in the source address to be returned by recvfrom & recvmsg */
-       if (uds_fd_table[minor].type == SOCK_DGRAM) {
+       /* Fill in the source address to be returned by recvfrom, recvmsg. */
+       if (uds_fd_table[minor].type == SOCK_DGRAM)
                memcpy(&uds_fd_table[peer].source, &uds_fd_table[minor].addr,
-                                               sizeof(struct sockaddr_un));
-       }
+                   sizeof(struct sockaddr_un));
 
-       /* revive peer that was waiting for us to write */
+       /* See if we can wake up a blocked reader. */
        if (uds_fd_table[peer].suspended == UDS_SUSPENDED_READ)
                uds_unsuspend(peer);
 
-       /* see if peer is blocked on select(); if the peer wants to know about
-        * data ready to read and it doesn't know about it already, then let
-        * the peer know we have data for it.
-        */
-       if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) && size > 0) {
-               /* a read on peer is possible now */
+       /* See if we can satisfy an ongoing select. */
+       if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) &&
+           uds_fd_table[peer].size > 0) {
+               /* A read on the peer is possible now. */
                chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
-                       CDEV_OP_RD);
+                   CDEV_OP_RD);
                uds_fd_table[peer].sel_ops &= ~CDEV_OP_RD;
        }
 
-       return size; /* return number of bytes written */
+       return size; /* number of bytes written */
 }
 
 static ssize_t
@@ -565,19 +466,12 @@ uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
 {
        ssize_t rc;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_read() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_read(%d)\n", minor));
 
        if (minor < 0 || minor >= NR_FDS) return ENXIO;
 
-       if (uds_fd_table[minor].state != UDS_INUSE) {
-               /* attempted to read from a socket that hasn't been opened --
-                * something is very wrong :(
-                */
+       if (uds_fd_table[minor].state != UDS_INUSE)
                return EINVAL;
-       }
 
        rc = uds_perform_read(minor, endpt, grant, size, 0);
 
@@ -606,19 +500,12 @@ uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
 {
        ssize_t rc;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_write() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_write(%d)\n", minor));
 
        if (minor < 0 || minor >= NR_FDS) return ENXIO;
 
-       if (uds_fd_table[minor].state != UDS_INUSE) {
-               /* attempted to write to a socket that hasn't been opened --
-                * something is very wrong :(
-                */
+       if (uds_fd_table[minor].state != UDS_INUSE)
                return EINVAL;
-       }
 
        rc = uds_perform_write(minor, endpt, grant, size, 0);
 
@@ -647,24 +534,17 @@ uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
 {
        int rc;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_ioctl() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_ioctl(%d, %lu)\n", minor, request));
 
        if (minor < 0 || minor >= NR_FDS) return ENXIO;
 
-       if (uds_fd_table[minor].state != UDS_INUSE) {
-               /* attempted to perform I/O control on a socket that hasn't
-                * been opened -- something is very wrong :(
-                */
+       if (uds_fd_table[minor].state != UDS_INUSE)
                return EINVAL;
-       }
 
-       /* update the owner endpoint */
+       /* Update the owner endpoint. */
        uds_fd_table[minor].owner = user_endpt;
 
-       /* let the UDS subsystem handle the actual request */
+       /* Let the UDS ioctl subsystem handle the actual request. */
        rc = uds_do_ioctl(minor, request, endpt, grant);
 
        /* If the call couldn't complete, suspend the caller. */
@@ -699,7 +579,7 @@ uds_unsuspend(devminor_t minor)
        switch (fdp->suspended) {
        case UDS_SUSPENDED_READ:
                r = uds_perform_read(minor, fdp->susp_endpt, fdp->susp_grant,
-                       fdp->susp_size, 0);
+                   fdp->susp_size, 0);
 
                if (r == EDONTREPLY)
                        return;
@@ -708,7 +588,7 @@ uds_unsuspend(devminor_t minor)
 
        case UDS_SUSPENDED_WRITE:
                r = uds_perform_write(minor, fdp->susp_endpt, fdp->susp_grant,
-                       fdp->susp_size, 0);
+                   fdp->susp_size, 0);
 
                if (r == EDONTREPLY)
                        return;
@@ -717,7 +597,8 @@ uds_unsuspend(devminor_t minor)
 
        case UDS_SUSPENDED_CONNECT:
        case UDS_SUSPENDED_ACCEPT:
-               /* In both cases, the caller already set up the connection.
+               /*
+                * In both cases, the caller already set up the connection.
                 * The only thing to do here is unblock.
                 */
                r = OK;
@@ -739,10 +620,7 @@ uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
        uds_fd_t *fdp;
        int i, j;
 
-#if DEBUG == 1
-       static int call_count = 0;
-       printf("(uds) [%d] uds_cancel() call_count=%d\n", minor, ++call_count);
-#endif
+       dprintf(("UDS: uds_cancel(%d)\n", minor));
 
        if (minor < 0 || minor >= NR_FDS) return EDONTREPLY;
 
@@ -755,48 +633,41 @@ uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
 
        /* Make sure the cancel request is for a request we're hanging on. */
        if (fdp->suspended == UDS_NOT_SUSPENDED || fdp->susp_endpt != endpt ||
-                       fdp->susp_id != id) {
+           fdp->susp_id != id)
                return EDONTREPLY;      /* this happens. */
-       }
 
-       /* The system call was cancelled, so the socket is not suspended
+       /*
+        * The system call was cancelled, so the socket is not suspended
         * anymore.
         */
        switch (fdp->suspended) {
        case UDS_SUSPENDED_ACCEPT:      /* accept() */
-               /* partial accept() only changes
-                * uds_fd_table[minorparent].child
-                */
-               for (i = 0; i < NR_FDS; i++) {
-                       if (uds_fd_table[i].child == minor) {
+               /* A partial accept() only sets the server's child. */
+               for (i = 0; i < NR_FDS; i++)
+                       if (uds_fd_table[i].child == minor)
                                uds_fd_table[i].child = -1;
-                       }
-               }
 
                break;
 
        case UDS_SUSPENDED_CONNECT:     /* connect() */
-               /* partial connect() sets addr and adds minor to server backlog
+               /*
+                * A partial connect() sets the address and adds the minor to
+                * the server backlog.
                 */
-
                for (i = 0; i < NR_FDS; i++) {
-                       /* find a socket that is in use. */
                        if (uds_fd_table[i].state != UDS_INUSE)
                                continue;
 
-                       /* see if minor is in the backlog */
+                       /* Remove the minor from the backlog of any server. */
                        for (j = 0; j < uds_fd_table[i].backlog_size; j++) {
-                               if (uds_fd_table[i].backlog[j] == minor) {
-
-                                       /* remove from backlog */
+                               if (uds_fd_table[i].backlog[j] == minor)
                                        uds_fd_table[i].backlog[j] = -1;
-                               }
                        }
                }
 
-               /* clear the address */
-               memset(&(uds_fd_table[minor].addr), '\0',
-                       sizeof(struct sockaddr_un));
+               /* Clear the address. */
+               memset(&uds_fd_table[minor].addr, '\0',
+                   sizeof(struct sockaddr_un));
 
                break;
 
index 4b9c720af7b32a8e874da822deea698a2e7361ad..202259970a86389ee57697ae9f4a85105a0a8d62 100644 (file)
 /* Connection backlog size for incoming connections. */
 #define UDS_SOMAXCONN  64
 
+/* Maximum UDS socket buffer size. */
+#define UDS_BUF                PIPE_BUF
+
 /* Output debugging information? */
 #define DEBUG          0
 
+#if DEBUG
+#define dprintf(x)     printf x
+#else
+#define dprintf(x)
+#endif
+
 typedef void* filp_id_t;
 
 /* ancillary data to be sent */
@@ -29,6 +38,9 @@ struct ancillary {
        struct uucred cred;
 };
 
+#define UDS_R  0x1
+#define UDS_W  0x2
+
 /*
  * Internal State Information for a socket descriptor.
  */
@@ -61,9 +73,9 @@ struct uds_fd {
        size_t size;                    /* size of used part of ring buffer */
 
        /* control read/write, set by uds_open() and shutdown(2).
-        * Can be set to R_BIT|W_BIT, R_BIT, W_BIT, or 0
+        * Can be set to UDS_R|UDS_W, UDS_R, UDS_W, or 0
         * for read and write, read only, write only, or neither.
-        * default is R_BIT|W_BIT.
+        * default is UDS_R|UDS_W.
         */
        int mode;
 
@@ -179,12 +191,20 @@ EXTERN uds_fd_t uds_fd_table[NR_FDS];
 
 /* Function prototypes. */
 
-/* dev_uds.c */
-void uds_unsuspend(devminor_t minor);
-
-/* uds.c */
+/* ioc_uds.c */
 int uds_clear_fds(devminor_t minor, struct ancillary *data);
 int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
        cp_grant_id_t grant);
 
+/* uds.c */
+void uds_unsuspend(devminor_t minor);
+
+/* vfs_uds.c */
+int vfs_check_perms(endpoint_t ep, struct sockaddr_un *addr);
+int vfs_verify_fd(endpoint_t ep, int fd, filp_id_t *filp);
+int vfs_set_filp(filp_id_t sfilp);
+int vfs_copy_filp(endpoint_t to_ep, filp_id_t cfilp);
+int vfs_put_filp(filp_id_t pfilp);
+int vfs_cancel_fd(endpoint_t ep, int fd);
+
 #endif /* !__UDS_UDS_H */
diff --git a/drivers/uds/vfs_uds.c b/drivers/uds/vfs_uds.c
new file mode 100644 (file)
index 0000000..7c8748e
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Unix Domain Sockets Implementation (PF_UNIX, PF_LOCAL)
+ * This code provides communication stubs for backcalls to VFS.
+ */
+
+#include "uds.h"
+
+/*
+ * Check the permissions of a socket file.
+ */
+int
+vfs_check_perms(endpoint_t ep, struct sockaddr_un *addr)
+{
+       int rc;
+       message m;
+       cp_grant_id_t grant_id;
+
+       dprintf(("UDS: vfs_check_perms(%d)\n", ep));
+
+       grant_id = cpf_grant_direct(VFS_PROC_NR, (vir_bytes) addr->sun_path,
+           UNIX_PATH_MAX, CPF_READ | CPF_WRITE);
+
+       /* Ask VFS to verify the permissions. */
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_CHECK_PERMS;
+       m.VFS_UDS_ENDPT = ep;
+       m.VFS_UDS_GRANT = grant_id;
+       m.VFS_UDS_COUNT = UNIX_PATH_MAX;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       cpf_revoke(grant_id);
+
+       dprintf(("UDS: VFS reply => %d, \"%s\"\n", m.m_type,
+           addr->sun_path));
+
+       return m.m_type; /* reply code: OK, ELOOP, etc. */
+}
+
+/*
+ * Verify whether the given file descriptor is valid for the given process, and
+ * obtain a filp object identifier upon success.
+ */
+int
+vfs_verify_fd(endpoint_t ep, int fd, filp_id_t *filp)
+{
+       int rc;
+       message m;
+
+       dprintf(("UDS: vfs_verify_fd(%d, %d)\n", ep, fd));
+
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_VERIFY_FD;
+       m.VFS_UDS_ENDPT = ep;
+       m.VFS_UDS_FD = fd;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       dprintf(("UDS: VFS reply => %d, %p\n", m.m_type, m.VFS_UDS_FILP));
+
+       if (m.m_type != OK)
+               return m.m_type;
+
+       *filp = m.VFS_UDS_FILP;
+       return OK;
+}
+
+/*
+ * Mark a filp object as in flight, that is, in use by UDS.
+ */
+int
+vfs_set_filp(filp_id_t sfilp)
+{
+       int rc;
+       message m;
+
+       dprintf(("UDS: set_filp(%p)\n", sfilp));
+
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_SET_FILP;
+       m.VFS_UDS_FILP = sfilp;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       dprintf(("UDS: VFS reply => %d\n", m.m_type));
+
+       return m.m_type; /* reply code: OK, ELOOP, etc. */
+}
+
+/*
+ * Copy a filp object into a process, yielding a file descriptor.
+ */
+int
+vfs_copy_filp(endpoint_t to_ep, filp_id_t cfilp)
+{
+       int rc;
+       message m;
+
+       dprintf(("UDS: vfs_copy_filp(%d, %p)\n", to_ep, cfilp));
+
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_COPY_FILP;
+       m.VFS_UDS_ENDPT = to_ep;
+       m.VFS_UDS_FILP = cfilp;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       dprintf(("UDS: VFS reply => %d\n", m.m_type));
+
+       return m.m_type;
+}
+
+/*
+ * Mark a filp object as no longer in flight.
+ */
+int
+vfs_put_filp(filp_id_t pfilp)
+{
+       int rc;
+       message m;
+
+       dprintf(("UDS: vfs_put_filp(%p)\n", pfilp));
+
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_PUT_FILP;
+       m.VFS_UDS_FILP = pfilp;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       dprintf(("UDS: VFS reply => %d\n", m.m_type));
+
+       return m.m_type; /* reply code: OK, ELOOP, etc. */
+}
+
+/*
+ * Undo creation of a file descriptor in a process.
+ */
+int
+vfs_cancel_fd(endpoint_t ep, int fd)
+{
+       int rc;
+       message m;
+
+       dprintf(("UDS: vfs_cancel_fd(%d,%d)\n", ep, fd));
+
+       memset(&m, '\0', sizeof(message));
+
+       m.m_type = VFS_UDS_CANCEL_FD;
+       m.VFS_UDS_ENDPT = ep;
+       m.VFS_UDS_FD = fd;
+
+       if ((rc = sendrec(VFS_PROC_NR, &m)) != OK)
+                panic("error sending to VFS: %d\n", rc);
+
+       dprintf(("UDS: VFS reply => %d\n", m.m_type));
+
+       return m.m_type; /* reply code: OK, ELOOP, etc. */
+}