marc's changes: malloc uio if too large, ktrace
[unix-history] / usr / src / sys / kern / uipc_socket2.c
index 5cffe30..21cca21 100644 (file)
@@ -1,9 +1,20 @@
 /*
 /*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)uipc_socket2.c      7.1 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)uipc_socket2.c      7.7 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -14,6 +25,7 @@
 #include "file.h"
 #include "inode.h"
 #include "buf.h"
 #include "file.h"
 #include "inode.h"
 #include "buf.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
@@ -129,7 +141,8 @@ sonewconn(head)
        so->so_state = head->so_state | SS_NOFDREF;
        so->so_proto = head->so_proto;
        so->so_timeo = head->so_timeo;
        so->so_state = head->so_state | SS_NOFDREF;
        so->so_proto = head->so_proto;
        so->so_timeo = head->so_timeo;
-       so->so_pgrp = head->so_pgrp;
+       so->so_pgid = head->so_pgid;
+       (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
        soqinsque(head, so, 0);
        if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
            (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
        soqinsque(head, so, 0);
        if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
            (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
@@ -223,7 +236,7 @@ socantrcvmore(so)
 sbselqueue(sb)
        struct sockbuf *sb;
 {
 sbselqueue(sb)
        struct sockbuf *sb;
 {
-       register struct proc *p;
+       struct proc *p;
 
        if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait)
                sb->sb_flags |= SB_COLL;
 
        if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait)
                sb->sb_flags |= SB_COLL;
@@ -244,10 +257,14 @@ sbwait(sb)
 
 /*
  * Wakeup processes waiting on a socket buffer.
 
 /*
  * Wakeup processes waiting on a socket buffer.
+ * Do asynchronous notification via SIGIO
+ * if the socket has the SS_ASYNC flag set.
  */
  */
-sbwakeup(sb)
+sowakeup(so, sb)
+       register struct socket *so;
        register struct sockbuf *sb;
 {
        register struct sockbuf *sb;
 {
+       register struct proc *p;
 
        if (sb->sb_sel) {
                selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL);
 
        if (sb->sb_sel) {
                selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL);
@@ -258,24 +275,10 @@ sbwakeup(sb)
                sb->sb_flags &= ~SB_WAIT;
                wakeup((caddr_t)&sb->sb_cc);
        }
                sb->sb_flags &= ~SB_WAIT;
                wakeup((caddr_t)&sb->sb_cc);
        }
-}
-
-/*
- * Wakeup socket readers and writers.
- * Do asynchronous notification via SIGIO
- * if the socket has the SS_ASYNC flag set.
- */
-sowakeup(so, sb)
-       register struct socket *so;
-       struct sockbuf *sb;
-{
-       register struct proc *p;
-
-       sbwakeup(sb);
        if (so->so_state & SS_ASYNC) {
        if (so->so_state & SS_ASYNC) {
-               if (so->so_pgrp < 0)
-                       gsignal(-so->so_pgrp, SIGIO);
-               else if (so->so_pgrp > 0 && (p = pfind(so->so_pgrp)) != 0)
+               if (so->so_pgid < 0)
+                       gsignal(-so->so_pgid, SIGIO);
+               else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
                        psignal(p, SIGIO);
        }
 }
                        psignal(p, SIGIO);
        }
 }
@@ -291,7 +294,7 @@ sowakeup(so, sb)
  *
  * Data stored in a socket buffer is maintained as a list of records.
  * Each record is a list of mbufs chained together with the m_next
  *
  * Data stored in a socket buffer is maintained as a list of records.
  * Each record is a list of mbufs chained together with the m_next
- * field.  Records are chained together with the m_act field. The upper
+ * field.  Records are chained together with the m_nextpkt field. The upper
  * level routine soreceive() expects the following conventions to be
  * observed when placing information in the receive buffer:
  *
  * level routine soreceive() expects the following conventions to be
  * observed when placing information in the receive buffer:
  *
@@ -306,15 +309,15 @@ sowakeup(so, sb)
  *    a data record, perhaps of zero length.
  *
  * Before using a new socket structure it is first necessary to reserve
  *    a data record, perhaps of zero length.
  *
  * Before using a new socket structure it is first necessary to reserve
- * buffer space to the socket, by calling sbreserve().  This commits
+ * buffer space to the socket, by calling sbreserve().  This should commit
  * some of the available buffer space in the system buffer pool for the
  * some of the available buffer space in the system buffer pool for the
- * socket.  The space should be released by calling sbrelease() when the
- * socket is destroyed.
+ * socket (currently, it does nothing but enforce limits).  The space
+ * should be released by calling sbrelease() when the socket is destroyed.
  */
 
 soreserve(so, sndcc, rcvcc)
        register struct socket *so;
  */
 
 soreserve(so, sndcc, rcvcc)
        register struct socket *so;
-       int sndcc, rcvcc;
+       u_long sndcc, rcvcc;
 {
 
        if (sbreserve(&so->so_snd, sndcc) == 0)
 {
 
        if (sbreserve(&so->so_snd, sndcc) == 0)
@@ -335,9 +338,10 @@ bad:
  */
 sbreserve(sb, cc)
        struct sockbuf *sb;
  */
 sbreserve(sb, cc)
        struct sockbuf *sb;
+       u_long cc;
 {
 
 {
 
-       if ((unsigned) cc > (unsigned)SB_MAX * CLBYTES / (2 * MSIZE + CLBYTES))
+       if (cc > (u_long)SB_MAX * MCLBYTES / (2 * MSIZE + MCLBYTES))
                return (0);
        sb->sb_hiwat = cc;
        sb->sb_mbmax = MIN(cc * 2, SB_MAX);
                return (0);
        sb->sb_hiwat = cc;
        sb->sb_mbmax = MIN(cc * 2, SB_MAX);
@@ -395,8 +399,8 @@ sbappend(sb, m)
        if (m == 0)
                return;
        if (n = sb->sb_mb) {
        if (m == 0)
                return;
        if (n = sb->sb_mb) {
-               while (n->m_act)
-                       n = n->m_act;
+               while (n->m_nextpkt)
+                       n = n->m_nextpkt;
                while (n->m_next)
                        n = n->m_next;
        }
                while (n->m_next)
                        n = n->m_next;
        }
@@ -416,15 +420,15 @@ sbappendrecord(sb, m0)
        if (m0 == 0)
                return;
        if (m = sb->sb_mb)
        if (m0 == 0)
                return;
        if (m = sb->sb_mb)
-               while (m->m_act)
-                       m = m->m_act;
+               while (m->m_nextpkt)
+                       m = m->m_nextpkt;
        /*
         * Put the first mbuf on the queue.
         * Note this permits zero length records.
         */
        sballoc(sb, m0);
        if (m)
        /*
         * Put the first mbuf on the queue.
         * Note this permits zero length records.
         */
        sballoc(sb, m0);
        if (m)
-               m->m_act = m0;
+               m->m_nextpkt = m0;
        else
                sb->sb_mb = m0;
        m = m0->m_next;
        else
                sb->sb_mb = m0;
        m = m0->m_next;
@@ -434,19 +438,22 @@ sbappendrecord(sb, m0)
 
 /*
  * Append address and data, and optionally, rights
 
 /*
  * Append address and data, and optionally, rights
- * to the receive queue of a socket.  Return 0 if
+ * to the receive queue of a socket.  If present,
+ * m0 Return 0 if
  * no space in sockbuf or insufficient mbufs.
  */
 sbappendaddr(sb, asa, m0, rights0)
        register struct sockbuf *sb;
        struct sockaddr *asa;
  * no space in sockbuf or insufficient mbufs.
  */
 sbappendaddr(sb, asa, m0, rights0)
        register struct sockbuf *sb;
        struct sockaddr *asa;
-       struct mbuf *rights0, *m0;
+       struct mbuf *m0, *rights0;
 {
        register struct mbuf *m, *n;
        int space = sizeof (*asa);
 
 {
        register struct mbuf *m, *n;
        int space = sizeof (*asa);
 
-       for (m = m0; m; m = m->m_next)
-               space += m->m_len;
+if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+panic("sbappendaddr");
+       if (m0)
+               space += m0->m_pkthdr.len;
        if (rights0)
                space += rights0->m_len;
        if (space > sbspace(sb))
        if (rights0)
                space += rights0->m_len;
        if (space > sbspace(sb))
@@ -466,9 +473,9 @@ sbappendaddr(sb, asa, m0, rights0)
        }
        sballoc(sb, m);
        if (n = sb->sb_mb) {
        }
        sballoc(sb, m);
        if (n = sb->sb_mb) {
-               while (n->m_act)
-                       n = n->m_act;
-               n->m_act = m;
+               while (n->m_nextpkt)
+                       n = n->m_nextpkt;
+               n->m_nextpkt = m;
        } else
                sb->sb_mb = m;
        if (m->m_next)
        } else
                sb->sb_mb = m;
        if (m->m_next)
@@ -497,9 +504,9 @@ sbappendrights(sb, m0, rights)
                return (0);
        sballoc(sb, m);
        if (n = sb->sb_mb) {
                return (0);
        sballoc(sb, m);
        if (n = sb->sb_mb) {
-               while (n->m_act)
-                       n = n->m_act;
-               n->m_act = m;
+               while (n->m_nextpkt)
+                       n = n->m_nextpkt;
+               n->m_nextpkt = m;
        } else
                sb->sb_mb = m;
        if (m0)
        } else
                sb->sb_mb = m;
        if (m0)
@@ -522,8 +529,8 @@ sbcompress(sb, m, n)
                        m = m_free(m);
                        continue;
                }
                        m = m_free(m);
                        continue;
                }
-               if (n && n->m_off <= MMAXOFF && m->m_off <= MMAXOFF &&
-                   (n->m_off + n->m_len + m->m_len) <= MMAXOFF &&
+               if (n && (n->m_flags & M_EXT) == 0 &&
+                   (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] &&
                    n->m_type == m->m_type) {
                        bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
                            (unsigned)m->m_len);
                    n->m_type == m->m_type) {
                        bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
                            (unsigned)m->m_len);
@@ -569,18 +576,18 @@ sbdrop(sb, len)
        register struct mbuf *m, *mn;
        struct mbuf *next;
 
        register struct mbuf *m, *mn;
        struct mbuf *next;
 
-       next = (m = sb->sb_mb) ? m->m_act : 0;
+       next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
        while (len > 0) {
                if (m == 0) {
                        if (next == 0)
                                panic("sbdrop");
                        m = next;
        while (len > 0) {
                if (m == 0) {
                        if (next == 0)
                                panic("sbdrop");
                        m = next;
-                       next = m->m_act;
+                       next = m->m_nextpkt;
                        continue;
                }
                if (m->m_len > len) {
                        m->m_len -= len;
                        continue;
                }
                if (m->m_len > len) {
                        m->m_len -= len;
-                       m->m_off += len;
+                       m->m_data += len;
                        sb->sb_cc -= len;
                        break;
                }
                        sb->sb_cc -= len;
                        break;
                }
@@ -596,7 +603,7 @@ sbdrop(sb, len)
        }
        if (m) {
                sb->sb_mb = m;
        }
        if (m) {
                sb->sb_mb = m;
-               m->m_act = next;
+               m->m_nextpkt = next;
        } else
                sb->sb_mb = next;
 }
        } else
                sb->sb_mb = next;
 }
@@ -612,7 +619,7 @@ sbdroprecord(sb)
 
        m = sb->sb_mb;
        if (m) {
 
        m = sb->sb_mb;
        if (m) {
-               sb->sb_mb = m->m_act;
+               sb->sb_mb = m->m_nextpkt;
                do {
                        sbfree(sb, m);
                        MFREE(m, mn);
                do {
                        sbfree(sb, m);
                        MFREE(m, mn);