added my responsibility for the `cpm' port
[unix-history] / sys / kern / uipc_usrreq.c
index 0bc0acd..d04e801 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)uipc_usrreq.c       7.26 (Berkeley) 6/3/91
+ *     from:   @(#)uipc_usrreq.c       7.26 (Berkeley) 6/3/91
+ *     $Id: uipc_usrreq.c,v 1.4 1993/10/23 16:34:45 davidg Exp $
  */
 
 #include "param.h"
  */
 
 #include "param.h"
+#include "systm.h"
 #include "proc.h"
 #include "filedesc.h"
 #include "domain.h"
 #include "proc.h"
 #include "filedesc.h"
 #include "domain.h"
@@ -60,6 +62,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;
@@ -312,6 +315,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;
 {
@@ -329,6 +333,8 @@ unp_attach(so)
                case SOCK_DGRAM:
                        error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
                        break;
                case SOCK_DGRAM:
                        error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
                        break;
+               default:
+                       panic("unp_attach");
                }
                if (error)
                        return (error);
                }
                if (error)
                        return (error);
@@ -342,6 +348,7 @@ unp_attach(so)
        return (0);
 }
 
        return (0);
 }
 
+void
 unp_detach(unp)
        register struct unpcb *unp;
 {
 unp_detach(unp)
        register struct unpcb *unp;
 {
@@ -359,10 +366,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;
@@ -412,6 +429,7 @@ unp_bind(unp, nam, 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;
@@ -471,6 +489,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;
@@ -502,6 +521,7 @@ unp_connect2(so, so2)
        return (0);
 }
 
        return (0);
 }
 
+void
 unp_disconnect(unp)
        struct unpcb *unp;
 {
 unp_disconnect(unp)
        struct unpcb *unp;
 {
@@ -547,6 +567,7 @@ unp_abort(unp)
 }
 #endif
 
 }
 #endif
 
+void
 unp_shutdown(unp)
        struct unpcb *unp;
 {
 unp_shutdown(unp)
        struct unpcb *unp;
 {
@@ -557,6 +578,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;
@@ -580,6 +602,7 @@ unp_drain()
 }
 #endif
 
 }
 #endif
 
+int
 unp_externalize(rights)
        struct mbuf *rights;
 {
 unp_externalize(rights)
        struct mbuf *rights;
 {
@@ -591,7 +614,7 @@ unp_externalize(rights)
        int newfds = (cm->cmsg_len - sizeof(*cm)) / sizeof (int);
        int f;
 
        int newfds = (cm->cmsg_len - sizeof(*cm)) / sizeof (int);
        int f;
 
-       if (fdavail(p, newfds)) {
+       if (!fdavail(p, newfds)) {
                for (i = 0; i < newfds; i++) {
                        fp = *rp;
                        unp_discard(fp);
                for (i = 0; i < newfds; i++) {
                        fp = *rp;
                        unp_discard(fp);
@@ -611,6 +634,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;
@@ -645,9 +669,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;
 unp_gc()
 {
        register struct file *fp;
@@ -709,18 +733,18 @@ restart:
        unp_gcing = 0;
 }
 
        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)(struct file *);
 {
        register struct mbuf *m;
        register struct file **rp;
 {
        register struct mbuf *m;
        register struct file **rp;
@@ -747,6 +771,7 @@ unp_scan(m0, op)
        }
 }
 
        }
 }
 
+void
 unp_mark(fp)
        struct file *fp;
 {
 unp_mark(fp)
        struct file *fp;
 {
@@ -757,6 +782,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;
 {