add definition for ability to produce a backtrace
[unix-history] / usr / src / sys / kern / uipc_usrreq.c
index c046d67..e9ab81d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)uipc_usrreq.c       7.38 (Berkeley) %G%
+ *     @(#)uipc_usrreq.c       8.9 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -33,6 +33,7 @@ struct        sockaddr sun_noname = { sizeof(sun_noname), AF_UNIX };
 ino_t  unp_ino;                        /* prototype for fake inode numbers */
 
 /*ARGSUSED*/
 ino_t  unp_ino;                        /* prototype for fake inode numbers */
 
 /*ARGSUSED*/
+int
 uipc_usrreq(so, req, m, nam, control)
        struct socket *so;
        int req;
 uipc_usrreq(so, req, m, nam, control)
        struct socket *so;
        int req;
@@ -285,6 +286,7 @@ u_long      unpdg_recvspace = 4*1024;
 
 int    unp_rights;                     /* file descriptors in flight */
 
 
 int    unp_rights;                     /* file descriptors in flight */
 
+int
 unp_attach(so)
        struct socket *so;
 {
 unp_attach(so)
        struct socket *so;
 {
@@ -318,6 +320,7 @@ unp_attach(so)
        return (0);
 }
 
        return (0);
 }
 
+void
 unp_detach(unp)
        register struct unpcb *unp;
 {
 unp_detach(unp)
        register struct unpcb *unp;
 {
@@ -335,10 +338,20 @@ unp_detach(unp)
        unp->unp_socket->so_pcb = 0;
        m_freem(unp->unp_addr);
        (void) m_free(dtom(unp));
        unp->unp_socket->so_pcb = 0;
        m_freem(unp->unp_addr);
        (void) m_free(dtom(unp));
-       if (unp_rights)
+       if (unp_rights) {
+               /*
+                * Normally the receive buffer is flushed later,
+                * in sofree, but if our receive buffer holds references
+                * to descriptors that are now garbage, we will dispose
+                * of those descriptor references after the garbage collector
+                * gets them (resulting in a "panic: closef: count < 0").
+                */
+               sorflush(unp->unp_socket);
                unp_gc();
                unp_gc();
+       }
 }
 
 }
 
+int
 unp_bind(unp, nam, p)
        struct unpcb *unp;
        struct mbuf *nam;
 unp_bind(unp, nam, p)
        struct unpcb *unp;
        struct mbuf *nam;
@@ -351,7 +364,7 @@ unp_bind(unp, nam, p)
        struct nameidata nd;
 
        NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE,
        struct nameidata nd;
 
        NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE,
-               soun->sun_path, p);
+           soun->sun_path, p);
        if (unp->unp_vnode != NULL)
                return (EINVAL);
        if (nam->m_len == MLEN) {
        if (unp->unp_vnode != NULL)
                return (EINVAL);
        if (nam->m_len == MLEN) {
@@ -374,18 +387,19 @@ unp_bind(unp, nam, p)
        }
        VATTR_NULL(&vattr);
        vattr.va_type = VSOCK;
        }
        VATTR_NULL(&vattr);
        vattr.va_type = VSOCK;
-       vattr.va_mode = 0777;
-       LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+       vattr.va_mode = ACCESSPERMS;
+       VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
        if (error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr))
                return (error);
        vp = nd.ni_vp;
        vp->v_socket = unp->unp_socket;
        unp->unp_vnode = vp;
        unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL);
        if (error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr))
                return (error);
        vp = nd.ni_vp;
        vp->v_socket = unp->unp_socket;
        unp->unp_vnode = vp;
        unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL);
-       VOP_UNLOCK(vp);
+       VOP_UNLOCK(vp, 0, p);
        return (0);
 }
 
        return (0);
 }
 
+int
 unp_connect(so, nam, p)
        struct socket *so;
        struct mbuf *nam;
 unp_connect(so, nam, p)
        struct socket *so;
        struct mbuf *nam;
@@ -441,6 +455,7 @@ bad:
        return (error);
 }
 
        return (error);
 }
 
+int
 unp_connect2(so, so2)
        register struct socket *so;
        register struct socket *so2;
 unp_connect2(so, so2)
        register struct socket *so;
        register struct socket *so2;
@@ -472,6 +487,7 @@ unp_connect2(so, so2)
        return (0);
 }
 
        return (0);
 }
 
+void
 unp_disconnect(unp)
        struct unpcb *unp;
 {
 unp_disconnect(unp)
        struct unpcb *unp;
 {
@@ -509,6 +525,7 @@ unp_disconnect(unp)
 }
 
 #ifdef notdef
 }
 
 #ifdef notdef
+void
 unp_abort(unp)
        struct unpcb *unp;
 {
 unp_abort(unp)
        struct unpcb *unp;
 {
@@ -517,6 +534,7 @@ unp_abort(unp)
 }
 #endif
 
 }
 #endif
 
+void
 unp_shutdown(unp)
        struct unpcb *unp;
 {
 unp_shutdown(unp)
        struct unpcb *unp;
 {
@@ -527,6 +545,7 @@ unp_shutdown(unp)
                socantrcvmore(so);
 }
 
                socantrcvmore(so);
 }
 
+void
 unp_drop(unp, errno)
        struct unpcb *unp;
        int errno;
 unp_drop(unp, errno)
        struct unpcb *unp;
        int errno;
@@ -550,6 +569,7 @@ unp_drain()
 }
 #endif
 
 }
 #endif
 
+int
 unp_externalize(rights)
        struct mbuf *rights;
 {
 unp_externalize(rights)
        struct mbuf *rights;
 {
@@ -581,6 +601,7 @@ unp_externalize(rights)
        return (0);
 }
 
        return (0);
 }
 
+int
 unp_internalize(control, p)
        struct mbuf *control;
        struct proc *p;
 unp_internalize(control, p)
        struct mbuf *control;
        struct proc *p;
@@ -615,9 +636,9 @@ unp_internalize(control, p)
 }
 
 int    unp_defer, unp_gcing;
 }
 
 int    unp_defer, unp_gcing;
-int    unp_mark();
 extern struct domain unixdomain;
 
 extern struct domain unixdomain;
 
+void
 unp_gc()
 {
        register struct file *fp, *nextfp;
 unp_gc()
 {
        register struct file *fp, *nextfp;
@@ -628,12 +649,11 @@ unp_gc()
        if (unp_gcing)
                return;
        unp_gcing = 1;
        if (unp_gcing)
                return;
        unp_gcing = 1;
-restart:
        unp_defer = 0;
        unp_defer = 0;
-       for (fp = filehead; fp; fp = fp->f_filef)
+       for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next)
                fp->f_flag &= ~(FMARK|FDEFER);
        do {
                fp->f_flag &= ~(FMARK|FDEFER);
        do {
-               for (fp = filehead; fp; fp = fp->f_filef) {
+               for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
                        if (fp->f_count == 0)
                                continue;
                        if (fp->f_flag & FDEFER) {
                        if (fp->f_count == 0)
                                continue;
                        if (fp->f_flag & FDEFER) {
@@ -711,8 +731,9 @@ restart:
         * 91/09/19, bsy@cs.cmu.edu
         */
        extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
         * 91/09/19, bsy@cs.cmu.edu
         */
        extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
-       for (nunref = 0, fp = filehead, fpp = extra_ref; fp; fp = nextfp) {
-               nextfp = fp->f_filef;
+       for (nunref = 0, fp = filehead.lh_first, fpp = extra_ref; fp != 0;
+           fp = nextfp) {
+               nextfp = fp->f_list.le_next;
                if (fp->f_count == 0)
                        continue;
                if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
                if (fp->f_count == 0)
                        continue;
                if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
@@ -724,23 +745,24 @@ restart:
        for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
                sorflush((struct socket *)(*fpp)->f_data);
        for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
        for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
                sorflush((struct socket *)(*fpp)->f_data);
        for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
-               closef(*fpp);
+               closef(*fpp, (struct proc *)NULL);
        free((caddr_t)extra_ref, M_FILE);
        unp_gcing = 0;
 }
 
        free((caddr_t)extra_ref, M_FILE);
        unp_gcing = 0;
 }
 
+void
 unp_dispose(m)
        struct mbuf *m;
 {
 unp_dispose(m)
        struct mbuf *m;
 {
-       int unp_discard();
 
        if (m)
                unp_scan(m, unp_discard);
 }
 
 
        if (m)
                unp_scan(m, unp_discard);
 }
 
+void
 unp_scan(m0, op)
        register struct mbuf *m0;
 unp_scan(m0, op)
        register struct mbuf *m0;
-       int (*op)();
+       void (*op) __P((struct file *));
 {
        register struct mbuf *m;
        register struct file **rp;
 {
        register struct mbuf *m;
        register struct file **rp;
@@ -767,6 +789,7 @@ unp_scan(m0, op)
        }
 }
 
        }
 }
 
+void
 unp_mark(fp)
        struct file *fp;
 {
 unp_mark(fp)
        struct file *fp;
 {
@@ -777,6 +800,7 @@ unp_mark(fp)
        fp->f_flag |= (FMARK|FDEFER);
 }
 
        fp->f_flag |= (FMARK|FDEFER);
 }
 
+void
 unp_discard(fp)
        struct file *fp;
 {
 unp_discard(fp)
        struct file *fp;
 {