restore missing default
[unix-history] / usr / src / sys / kern / uipc_socket.c
index ba8fec9..986e6fa 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_socket.c   4.30    82/01/24        */
+/*     uipc_socket.c   4.38    82/04/01        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -16,6 +16,7 @@
 #include "../h/ioctl.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../h/ioctl.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
+#include "../net/route.h"
 
 /*
  * Socket support routines.
 
 /*
  * Socket support routines.
@@ -70,6 +71,9 @@ COUNT(SOCREATE);
                return (ENOBUFS);
        so = mtod(m, struct socket *);
        so->so_options = options;
                return (ENOBUFS);
        so = mtod(m, struct socket *);
        so->so_options = options;
+       so->so_state = 0;
+       if (u.u_uid == 0)
+               so->so_state = SS_PRIV;
 
        /*
         * Attach protocol to socket, initializing
 
        /*
         * Attach protocol to socket, initializing
@@ -113,6 +117,8 @@ soclose(so, exiting)
 COUNT(SOCLOSE);
        if (so->so_pcb == 0)
                goto discard;
 COUNT(SOCLOSE);
        if (so->so_pcb == 0)
                goto discard;
+       if (exiting)
+               so->so_options |= SO_KEEPALIVE;
        if (so->so_state & SS_ISCONNECTED) {
                if ((so->so_state & SS_ISDISCONNECTING) == 0) {
                        u.u_error = sodisconnect(so, (struct sockaddr *)0);
        if (so->so_state & SS_ISCONNECTED) {
                if ((so->so_state & SS_ISDISCONNECTING) == 0) {
                        u.u_error = sodisconnect(so, (struct sockaddr *)0);
@@ -125,7 +131,7 @@ COUNT(SOCLOSE);
                }
                if ((so->so_options & SO_DONTLINGER) == 0) {
                        if ((so->so_state & SS_ISDISCONNECTING) &&
                }
                if ((so->so_options & SO_DONTLINGER) == 0) {
                        if ((so->so_state & SS_ISDISCONNECTING) &&
-                           (so->so_options & SO_NONBLOCKING) &&
+                           (so->so_state & SS_NBIO) &&
                            exiting == 0) {
                                u.u_error = EINPROGRESS;
                                splx(s);
                            exiting == 0) {
                                u.u_error = EINPROGRESS;
                                splx(s);
@@ -144,22 +150,6 @@ discard:
        splx(s);
 }
 
        splx(s);
 }
 
-sosplice(pso, so)
-       struct socket *pso, *so;
-{
-
-COUNT(SOSPLICE);
-       if (pso->so_proto->pr_family != PF_UNIX) {
-               struct socket *tso;
-               tso = pso; pso = so; so = tso;
-       }
-       if (pso->so_proto->pr_family != PF_UNIX)
-               return (EOPNOTSUPP);
-       /* check types and buffer space */
-       /* merge buffers */
-       return (0);
-}
-
 /*ARGSUSED*/
 sostat(so, sb)
        struct socket *so;
 /*ARGSUSED*/
 sostat(so, sb)
        struct socket *so;
@@ -266,20 +256,26 @@ sosend(so, asa)
        int error = 0, space, s;
 
 COUNT(SOSEND);
        int error = 0, space, s;
 
 COUNT(SOSEND);
-       if (so->so_state & SS_CANTSENDMORE)
-               return (EPIPE);
        if (sosendallatonce(so) && u.u_count > so->so_snd.sb_hiwat)
                return (EMSGSIZE);
        if (sosendallatonce(so) && u.u_count > so->so_snd.sb_hiwat)
                return (EMSGSIZE);
-       if ((so->so_snd.sb_flags & SB_LOCK) && (so->so_options & SO_NONBLOCKING))
+#ifdef notdef
+       /* NEED TO PREVENT BUSY WAITING IN SELECT FOR WRITING */
+       if ((so->so_snd.sb_flags & SB_LOCK) && (so->so_state & SS_NBIO))
                return (EWOULDBLOCK);
                return (EWOULDBLOCK);
+#endif
+restart:
        sblock(&so->so_snd);
 #define        snderr(errno)   { error = errno; splx(s); goto release; }
 
        sblock(&so->so_snd);
 #define        snderr(errno)   { error = errno; splx(s); goto release; }
 
-       s = splnet();
 again:
 again:
+       s = splnet();
+       if (so->so_state & SS_CANTSENDMORE) {
+               psignal(u.u_procp, SIGPIPE);
+               snderr(EPIPE);
+       }
        if (so->so_error) {
                error = so->so_error;
        if (so->so_error) {
                error = so->so_error;
-               so->so_error = 0;
+               so->so_error = 0;                               /* ??? */
                splx(s);
                goto release;
        }
                splx(s);
                goto release;
        }
@@ -291,11 +287,11 @@ again:
        }
        if (top) {
                error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, asa);
        }
        if (top) {
                error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, asa);
+               top = 0;
                if (error) {
                        splx(s);
                        goto release;
                }
                if (error) {
                        splx(s);
                        goto release;
                }
-               top = 0;
                mp = ⊤
        }
        if (u.u_count == 0) {
                mp = ⊤
        }
        if (u.u_count == 0) {
@@ -304,19 +300,18 @@ again:
        }
        space = sbspace(&so->so_snd);
        if (space <= 0 || sosendallatonce(so) && space < u.u_count) {
        }
        space = sbspace(&so->so_snd);
        if (space <= 0 || sosendallatonce(so) && space < u.u_count) {
-               if (so->so_options & SO_NONBLOCKING)
+               if (so->so_state & SS_NBIO)
                        snderr(EWOULDBLOCK);
                sbunlock(&so->so_snd);
                sbwait(&so->so_snd);
                splx(s);
                        snderr(EWOULDBLOCK);
                sbunlock(&so->so_snd);
                sbwait(&so->so_snd);
                splx(s);
-               goto again;
+               goto restart;
        }
        splx(s);
        while (u.u_count && space > 0) {
                MGET(m, 1);
                if (m == NULL) {
        }
        splx(s);
        while (u.u_count && space > 0) {
                MGET(m, 1);
                if (m == NULL) {
-                       error = ENOBUFS;
-                       m_freem(top);
+                       error = ENOBUFS;                        /* SIGPIPE? */
                        goto release;
                }
                if (u.u_count >= CLBYTES && space >= CLBYTES) {
                        goto release;
                }
                if (u.u_count >= CLBYTES && space >= CLBYTES) {
@@ -337,11 +332,12 @@ nopages:
                mp = &m->m_next;
                space = sbspace(&so->so_snd);
        }
                mp = &m->m_next;
                space = sbspace(&so->so_snd);
        }
-       s = splnet();
        goto again;
 
 release:
        sbunlock(&so->so_snd);
        goto again;
 
 release:
        sbunlock(&so->so_snd);
+       if (top)
+               m_freem(top);
        return (error);
 }
 
        return (error);
 }
 
@@ -374,7 +370,7 @@ restart:
                if ((so->so_state & SS_ISCONNECTED) == 0 &&
                    (so->so_proto->pr_flags & PR_CONNREQUIRED))
                        rcverr(ENOTCONN);
                if ((so->so_state & SS_ISCONNECTED) == 0 &&
                    (so->so_proto->pr_flags & PR_CONNREQUIRED))
                        rcverr(ENOTCONN);
-               if (so->so_options & SO_NONBLOCKING)
+               if (so->so_state & SS_NBIO)
                        rcverr(EWOULDBLOCK);
                sbunlock(&so->so_rcv);
                sbwait(&so->so_rcv);
                        rcverr(EWOULDBLOCK);
                sbunlock(&so->so_rcv);
                sbwait(&so->so_rcv);
@@ -402,16 +398,14 @@ restart:
        eor = 0;
        do {
                len = MIN(m->m_len, cnt);
        eor = 0;
        do {
                len = MIN(m->m_len, cnt);
-               if (len == m->m_len) {
-                       eor = (int)m->m_act;
-                       sbfree(&so->so_rcv, m);
-                       so->so_rcv.sb_mb = m->m_next;
-               }
                splx(s);
                iomove(mtod(m, caddr_t), len, B_READ);
                cnt -= len;
                s = splnet();
                if (len == m->m_len) {
                splx(s);
                iomove(mtod(m, caddr_t), len, B_READ);
                cnt -= len;
                s = splnet();
                if (len == m->m_len) {
+                       eor = (int)m->m_act;
+                       sbfree(&so->so_rcv, m);
+                       so->so_rcv.sb_mb = m->m_next;
                        MFREE(m, n);
                } else {
                        m->m_off += len;
                        MFREE(m, n);
                } else {
                        m->m_off += len;
@@ -475,9 +469,9 @@ COUNT(SOIOCTL);
                        return;
                }
                if (nbio)
                        return;
                }
                if (nbio)
-                       so->so_options |= SO_NONBLOCKING;
+                       so->so_state |= SS_NBIO;
                else
                else
-                       so->so_options &= ~SO_NONBLOCKING;
+                       so->so_state &= ~SS_NBIO;
                return;
        }
 
                return;
        }
 
@@ -488,9 +482,9 @@ COUNT(SOIOCTL);
                        return;
                }
                if (async)
                        return;
                }
                if (async)
-                       ;
+                       so->so_state |= SS_ASYNC;
                else
                else
-                       ;
+                       so->so_state &= ~SS_ASYNC;
                return;
        }
 
                return;
        }
 
@@ -501,14 +495,14 @@ COUNT(SOIOCTL);
                        return;
                }
                if (keep)
                        return;
                }
                if (keep)
-                       so->so_options &= ~SO_NOKEEPALIVE;
+                       so->so_options &= ~SO_KEEPALIVE;
                else
                else
-                       so->so_options |= SO_NOKEEPALIVE;
+                       so->so_options |= SO_KEEPALIVE;
                return;
        }
 
        case SIOCGKEEP: {
                return;
        }
 
        case SIOCGKEEP: {
-               int keep = (so->so_options & SO_NOKEEPALIVE) == 0;
+               int keep = (so->so_options & SO_KEEPALIVE) != 0;
                if (copyout((caddr_t)&keep, cmdp, sizeof (keep)))
                        u.u_error = EFAULT;
                return;
                if (copyout((caddr_t)&keep, cmdp, sizeof (keep)))
                        u.u_error = EFAULT;
                return;
@@ -564,6 +558,7 @@ COUNT(SOIOCTL);
                        int s = splimp();
                        socantrcvmore(so);
                        sbflush(&so->so_rcv);
                        int s = splimp();
                        socantrcvmore(so);
                        sbflush(&so->so_rcv);
+                       splx(s);
                }
                if (flags & FWRITE)
                        u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_SHUTDOWN, (struct mbuf *)0, 0);
                }
                if (flags & FWRITE)
                        u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_SHUTDOWN, (struct mbuf *)0, 0);
@@ -613,6 +608,24 @@ COUNT(SOIOCTL);
                }
                return;
        }
                }
                return;
        }
+
+       /* routing table update calls */
+       case SIOCADDRT:
+       case SIOCDELRT:
+       case SIOCCHGRT: {
+               struct rtentry route;
+#ifdef notdef
+               if (!suser())
+                       return;
+#endif
+               if (copyin(cmdp, (caddr_t)&route, sizeof (route))) {
+                       u.u_error = EFAULT;
+                       return;
+               }
+               u.u_error = rtrequest(cmd, &route);
+               return;
+       }
+
        /* type/protocol specific ioctls */
        }
        u.u_error = EOPNOTSUPP;
        /* type/protocol specific ioctls */
        }
        u.u_error = EOPNOTSUPP;