update syscalls.master
[unix-history] / usr / src / sys / kern / uipc_socket.c
index 7e5dcbc..1fe0c04 100644 (file)
@@ -4,20 +4,21 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)uipc_socket.c       7.32 (Berkeley) %G%
+ *     @(#)uipc_socket.c       7.40 (Berkeley) %G%
  */
 
  */
 
-#include "param.h"
-#include "proc.h"
-#include "file.h"
-#include "malloc.h"
-#include "mbuf.h"
-#include "domain.h"
-#include "kernel.h"
-#include "protosw.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "resourcevar.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/kernel.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/resourcevar.h>
 
 /*
  * Socket operation routines.
 
 /*
  * Socket operation routines.
@@ -42,7 +43,7 @@ socreate(dom, aso, type, proto)
                prp = pffindproto(dom, proto, type);
        else
                prp = pffindtype(dom, type);
                prp = pffindproto(dom, proto, type);
        else
                prp = pffindtype(dom, type);
-       if (prp == 0)
+       if (prp == 0 || prp->pr_usrreq == 0)
                return (EPROTONOSUPPORT);
        if (prp->pr_type != type)
                return (EPROTOTYPE);
                return (EPROTONOSUPPORT);
        if (prp->pr_type != type)
                return (EPROTOTYPE);
@@ -449,12 +450,12 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
        struct mbuf **controlp;
        int *flagsp;
 {
        struct mbuf **controlp;
        int *flagsp;
 {
-       struct proc *p = curproc;               /* XXX */
        register struct mbuf *m, **mp;
        register int flags, len, error, s, offset;
        struct protosw *pr = so->so_proto;
        struct mbuf *nextrecord;
        int moff, type;
        register struct mbuf *m, **mp;
        register int flags, len, error, s, offset;
        struct protosw *pr = so->so_proto;
        struct mbuf *nextrecord;
        int moff, type;
+       int orig_resid = uio->uio_resid;
 
        mp = mp0;
        if (paddr)
 
        mp = mp0;
        if (paddr)
@@ -547,7 +548,8 @@ restart:
                        return (error);
                goto restart;
        }
                        return (error);
                goto restart;
        }
-       p->p_stats->p_ru.ru_msgrcv++;
+       if (uio->uio_procp)
+               uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
        nextrecord = m->m_nextpkt;
        record_eor = m->m_flags & M_EOR;
        if (pr->pr_flags & PR_ADDR) {
        nextrecord = m->m_nextpkt;
        record_eor = m->m_flags & M_EOR;
        if (pr->pr_flags & PR_ADDR) {
@@ -555,6 +557,7 @@ restart:
                if (m->m_type != MT_SONAME)
                        panic("receive 1a");
 #endif
                if (m->m_type != MT_SONAME)
                        panic("receive 1a");
 #endif
+               orig_resid = 0;
                if (flags & MSG_PEEK) {
                        if (paddr)
                                *paddr = m_copy(m, 0, m->m_len);
                if (flags & MSG_PEEK) {
                        if (paddr)
                                *paddr = m_copy(m, 0, m->m_len);
@@ -593,8 +596,10 @@ restart:
                                m = so->so_rcv.sb_mb;
                        }
                }
                                m = so->so_rcv.sb_mb;
                        }
                }
-               if (controlp)
+               if (controlp) {
+                       orig_resid = 0;
                        controlp = &(*controlp)->m_next;
                        controlp = &(*controlp)->m_next;
+               }
        }
        if (m) {
                if ((flags & MSG_PEEK) == 0)
        }
        if (m) {
                if ((flags & MSG_PEEK) == 0)
@@ -672,8 +677,11 @@ restart:
                                        so->so_state |= SS_RCVATMARK;
                                        break;
                                }
                                        so->so_state |= SS_RCVATMARK;
                                        break;
                                }
-                       } else
+                       } else {
                                offset += len;
                                offset += len;
+                               if (offset == so->so_oobmark)
+                                       break;
+                       }
                }
                if (m == 0 && record_eor) {
                        flags |= record_eor;
                }
                if (m == 0 && record_eor) {
                        flags |= record_eor;
@@ -702,18 +710,27 @@ restart:
                        }
                }
        }
                        }
                }
        }
+
+       if (m && pr->pr_flags & PR_ATOMIC) {
+               flags |= MSG_TRUNC;
+               if ((flags & MSG_PEEK) == 0)
+                       (void) sbdroprecord(&so->so_rcv);
+       }
        if ((flags & MSG_PEEK) == 0) {
                if (m == 0)
                        so->so_rcv.sb_mb = nextrecord;
        if ((flags & MSG_PEEK) == 0) {
                if (m == 0)
                        so->so_rcv.sb_mb = nextrecord;
-               else if (pr->pr_flags & PR_ATOMIC) {
-                       flags |= MSG_TRUNC;
-                       (void) sbdroprecord(&so->so_rcv);
-               }
                if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
                        (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
                            (struct mbuf *)flags, (struct mbuf *)0,
                            (struct mbuf *)0);
        }
                if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
                        (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
                            (struct mbuf *)flags, (struct mbuf *)0,
                            (struct mbuf *)0);
        }
+       if (orig_resid == uio->uio_resid && orig_resid &&
+           (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
+               sbunlock(&so->so_rcv);
+               splx(s);
+               goto restart;
+       }
+               
        if (flagsp)
                *flagsp |= flags;
 release:
        if (flagsp)
                *flagsp |= flags;
 release:
@@ -788,6 +805,7 @@ sosetopt(so, level, optname, m0)
                case SO_USELOOPBACK:
                case SO_BROADCAST:
                case SO_REUSEADDR:
                case SO_USELOOPBACK:
                case SO_BROADCAST:
                case SO_REUSEADDR:
+               case SO_REUSEPORT:
                case SO_OOBINLINE:
                        if (m == NULL || m->m_len < sizeof (int)) {
                                error = EINVAL;
                case SO_OOBINLINE:
                        if (m == NULL || m->m_len < sizeof (int)) {
                                error = EINVAL;
@@ -903,6 +921,7 @@ sogetopt(so, level, optname, mp)
                case SO_DEBUG:
                case SO_KEEPALIVE:
                case SO_REUSEADDR:
                case SO_DEBUG:
                case SO_KEEPALIVE:
                case SO_REUSEADDR:
+               case SO_REUSEPORT:
                case SO_BROADCAST:
                case SO_OOBINLINE:
                        *mtod(m, int *) = so->so_options & optname;
                case SO_BROADCAST:
                case SO_OOBINLINE:
                        *mtod(m, int *) = so->so_options & optname;
@@ -964,9 +983,5 @@ sohasoutofband(so)
                gsignal(-so->so_pgid, SIGURG);
        else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
                psignal(p, SIGURG);
                gsignal(-so->so_pgid, SIGURG);
        else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
                psignal(p, SIGURG);
-       if (so->so_rcv.sb_sel) {
-               selwakeup(so->so_rcv.sb_sel, so->so_rcv.sb_flags & SB_COLL);
-               so->so_rcv.sb_sel = 0;
-               so->so_rcv.sb_flags &= ~SB_COLL;
-       }
+       selwakeup(&so->so_rcv.sb_sel);
 }
 }