copyin & copyout now return EFAULT and all callers uniformly
[unix-history] / usr / src / sys / kern / uipc_syscalls.c
index 6ba5677..3d83c4b 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_syscalls.c 4.27    82/10/03        */
+/*     uipc_syscalls.c 4.39    82/12/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -12,8 +12,6 @@
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
 #include "../h/descrip.h"
 #include "../h/uio.h"
 
 #include "../h/descrip.h"
 #include "../h/uio.h"
 
@@ -33,20 +31,20 @@ socket()
        register struct file *fp;
        struct socketopt aopt;
 
        register struct file *fp;
        struct socketopt aopt;
 
-       if ((fp = falloc()) == NULL)
+       u.u_error = sockopt(&aopt, (caddr_t)uap->opt);
+       if (u.u_error)
                return;
                return;
+       if ((fp = falloc()) == NULL)
+               goto freeopt;
        fp->f_flag = FREAD|FWRITE;
        fp->f_type = DTYPE_SOCKET;
        fp->f_flag = FREAD|FWRITE;
        fp->f_type = DTYPE_SOCKET;
-       u.u_error = sockopt(&aopt, uap->opt);
-       if (u.u_error)
-               goto bad;
-       u.u_error = socreate(0, &so, uap->type, uap->protocol, &aopt);
+       u.u_error = socreate(uap->domain, &so, uap->type, uap->protocol, &aopt);
        if (u.u_error)
                goto bad;
        fp->f_socket = so;
 freeopt:
        if (uap->opt)
        if (u.u_error)
                goto bad;
        fp->f_socket = so;
 freeopt:
        if (uap->opt)
-               m_free(dtom(aopt.so_optdata));
+               (void) m_free(dtom(aopt.so_optdata));
        return;
 bad:
        u.u_ofile[u.u_r.r_val1] = 0;
        return;
 bad:
        u.u_ofile[u.u_r.r_val1] = 0;
@@ -76,15 +74,16 @@ bind()
        u.u_error = sockname(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
        u.u_error = sockname(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
-       u.u_error = sockopt(&aopt, uap->opt);
+       u.u_error = sockopt(&aopt, (caddr_t)uap->opt);
        if (u.u_error) {
                m_freem(nam);
        if (u.u_error) {
                m_freem(nam);
-               return;
+               goto freeopt;
        }
        u.u_error = sobind(fp->f_socket, nam, &aopt);
        m_freem(nam);
        }
        u.u_error = sobind(fp->f_socket, nam, &aopt);
        m_freem(nam);
+freeopt:
        if (uap->opt)
        if (uap->opt)
-               m_free(dtom(aopt.so_optdata));
+               (void) m_free(dtom(aopt.so_optdata));
 }
 
 listen()
 }
 
 listen()
@@ -122,16 +121,16 @@ accept()
 
        if (uap->name == 0)
                goto noname;
 
        if (uap->name == 0)
                goto noname;
-       if (copyin((caddr_t)uap->anamelen, (caddr_t)&namelen, sizeof (namelen))) {
-               u.u_error = EFAULT;
+       u.u_error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen,
+               sizeof (namelen));
+       if (u.u_error)
                return;
                return;
-       }
-       if (useracc((caddr_t)uap->name, namelen, B_WRITE) == 0) {
+       if (useracc((caddr_t)uap->name, (u_int)namelen, B_WRITE) == 0) {
                u.u_error = EFAULT;
                return;
        }
 noname:
                u.u_error = EFAULT;
                return;
        }
 noname:
-       u.u_error = sockopt(&aopt, uap->opt);
+       u.u_error = sockopt(&aopt, (caddr_t)uap->opt);
        if (u.u_error)
                return;
        fp = getf(uap->s);
        if (u.u_error)
                return;
        fp = getf(uap->s);
@@ -168,7 +167,7 @@ noname:
        if ((so->so_options & SO_NEWFDONCONN) == 0) {
                struct socket *nso = so->so_q;
                (void) soqremque(nso, 1);
        if ((so->so_options & SO_NEWFDONCONN) == 0) {
                struct socket *nso = so->so_q;
                (void) soqremque(nso, 1);
-               soclose(so, 1);
+               u.u_error = soclose(so, 1);
                fp->f_socket = nso;
                nso->so_q = 0;
                so = nso;
                fp->f_socket = nso;
                nso->so_q = 0;
                so = nso;
@@ -193,22 +192,22 @@ noname:
        fp->f_flag = FREAD|FWRITE;
        fp->f_socket = so;
 ret:
        fp->f_flag = FREAD|FWRITE;
        fp->f_socket = so;
 ret:
-       nam = m_get(M_WAIT);
-       nam->m_off = MMINOFF;
-       soaccept(so, nam, &aopt);
+       nam = m_get(M_WAIT, MT_SONAME);
+       (void) soaccept(so, nam, &aopt);
        if (uap->name) {
                if (namelen > nam->m_len)
                        namelen = nam->m_len;
                /* SHOULD COPY OUT A CHAIN HERE */
        if (uap->name) {
                if (namelen > nam->m_len)
                        namelen = nam->m_len;
                /* SHOULD COPY OUT A CHAIN HERE */
-               (void) copyout(mtod(nam, caddr_t), uap->name, namelen);
-               (void) copyout((caddr_t)&namelen, uap->anamelen,
+               (void) copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
+                   (u_int)namelen);
+               (void) copyout((caddr_t)&namelen, (caddr_t)uap->anamelen,
                    sizeof (*uap->anamelen));
        }
        m_freem(nam);
        splx(s);
 bad:
        if (uap->opt)
                    sizeof (*uap->anamelen));
        }
        m_freem(nam);
        splx(s);
 bad:
        if (uap->opt)
-               m_free(dtom(aopt.so_optdata));
+               (void) m_free(dtom(aopt.so_optdata));
 }
 
 connect()
 }
 
 connect()
@@ -236,7 +235,7 @@ connect()
        u.u_error = sockname(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
        u.u_error = sockname(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
-       u.u_error = sockopt(&aopt, uap->opt);
+       u.u_error = sockopt(&aopt, (caddr_t)uap->opt);
        if (u.u_error) {
                m_freem(nam);
                return;
        if (u.u_error) {
                m_freem(nam);
                return;
@@ -259,7 +258,7 @@ connect()
 bad:
        m_freem(nam);
        if (uap->opt)
 bad:
        m_freem(nam);
        if (uap->opt)
-               m_free(dtom(aopt.so_optdata));
+               (void) m_free(dtom(aopt.so_optdata));
        return;
 }
 
        return;
 }
 
@@ -298,14 +297,15 @@ sendto()
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, uap->len, B_READ) == 0) {
+       if (useracc(uap->buf, (u_int)uap->len, B_READ) == 0) {
                u.u_error = EFAULT;
                return;
        }
        u.u_error = sockname(&to, uap->to, uap->tolen);
        if (u.u_error)
                goto bad;
                u.u_error = EFAULT;
                return;
        }
        u.u_error = sockname(&to, uap->to, uap->tolen);
        if (u.u_error)
                goto bad;
-       u.u_error = sosend(fp->f_socket, to, &auio);
+       u.u_error = sosend(fp->f_socket, to, &auio, uap->flags);
+       u.u_r.r_val1 = uap->len - auio.uio_resid;
 bad:
        m_freem(to);
 }
 bad:
        m_freem(to);
 }
@@ -321,7 +321,6 @@ send()
        register struct file *fp;
        struct uio auio;
        struct iovec aiov;
        register struct file *fp;
        struct uio auio;
        struct iovec aiov;
-       struct mbuf *nam;
 
        fp = getf(uap->s);
        if (fp == 0)
 
        fp = getf(uap->s);
        if (fp == 0)
@@ -337,13 +336,14 @@ send()
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, uap->len, B_READ) == 0) {
+       if (useracc(uap->buf, (u_int)uap->len, B_READ) == 0) {
                u.u_error = EFAULT;
                return;
        }
        if (u.u_error)
                return;
                u.u_error = EFAULT;
                return;
        }
        if (u.u_error)
                return;
-       u.u_error = sosend(fp->f_socket, (struct mbuf *)0, &auio);
+       u.u_error = sosend(fp->f_socket, (struct mbuf *)0, &auio, uap->flags);
+       u.u_r.r_val1 = uap->len - auio.uio_resid;
 }
 
 recvfrom()
 }
 
 recvfrom()
@@ -362,10 +362,10 @@ recvfrom()
        struct mbuf *from;
        int fromlen;
 
        struct mbuf *from;
        int fromlen;
 
-       if (copyin((caddr_t)uap->fromlenaddr, (caddr_t)&fromlen, sizeof (fromlen))) {
-               u.u_error = EFAULT;
+       u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&fromlen,
+               sizeof (fromlen));
+       if (u.u_error)
                return;
                return;
-       }
        fp = getf(uap->s);
        if (fp == 0)
                return;
        fp = getf(uap->s);
        if (fp == 0)
                return;
@@ -380,12 +380,12 @@ recvfrom()
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, uap->len, B_WRITE) == 0)  {
+       if (useracc(uap->buf, (u_int)uap->len, B_WRITE) == 0)  {
                u.u_error = EFAULT;
                return;
        }
        from = 0;
                u.u_error = EFAULT;
                return;
        }
        from = 0;
-       u.u_error = soreceive(fp->f_socket, &from, &auio);
+       u.u_error = soreceive(fp->f_socket, &from, &auio, uap->flags);
        if (u.u_error)
                goto bad;
        if (from == 0)
        if (u.u_error)
                goto bad;
        if (from == 0)
@@ -393,16 +393,15 @@ recvfrom()
        else {
                if (fromlen > from->m_len)
                        fromlen = from->m_len;
        else {
                if (fromlen > from->m_len)
                        fromlen = from->m_len;
-               if (copyout(mtod(from, caddr_t), uap->from, fromlen)) {
-                       u.u_error = EFAULT;
+               u.u_error = copyout(mtod(from, caddr_t), uap->from,
+                       (u_int)fromlen);
+               if (u.u_error)
                        goto bad;
                        goto bad;
-               }
        }
        }
-       if (copyout((caddr_t)&fromlen, (caddr_t)uap->fromlenaddr,
-           sizeof (fromlen))) {
-               u.u_error = EFAULT;
+       u.u_error = copyout((caddr_t)&fromlen, (caddr_t)uap->fromlenaddr,
+           sizeof (fromlen));
+       if (u.u_error)
                goto bad;
                goto bad;
-       }
        u.u_r.r_val1 = uap->len - auio.uio_resid;
 bad:
        if (from)
        u.u_r.r_val1 = uap->len - auio.uio_resid;
 bad:
        if (from)
@@ -436,11 +435,12 @@ recv()
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
        auio.uio_resid = uap->len;
        auio.uio_segflg = 0;
        auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, uap->len, B_WRITE) == 0)  {
+       if (useracc(uap->buf, (u_int)uap->len, B_WRITE) == 0)  {
                u.u_error = EFAULT;
                return;
        }
                u.u_error = EFAULT;
                return;
        }
-       u.u_error = soreceive(fp->f_socket, (struct mbuf *)0, &auio);
+       u.u_error =
+           soreceive(fp->f_socket, (struct mbuf **)0, &auio, uap->flags);
        u.u_r.r_val1 = uap->len - auio.uio_resid;
 }
 
        u.u_r.r_val1 = uap->len - auio.uio_resid;
 }
 
@@ -468,10 +468,12 @@ pipe()
        struct socket *rso, *wso;
        int r;
 
        struct socket *rso, *wso;
        int r;
 
-       u.u_error = socreate(1, &rso, SOCK_STREAM, 0, 0);
+       u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0,
+               (struct socketopt *)0);
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       u.u_error = socreate(1, &wso, SOCK_STREAM, 0, 0);
+       u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0,
+               (struct socketopt *)0);
        if (u.u_error)
                goto free;
        rf = falloc();
        if (u.u_error)
                goto free;
        rf = falloc();
@@ -527,13 +529,13 @@ ssocketaddr()
                return;
        }
        so = fp->f_socket;
                return;
        }
        so = fp->f_socket;
-       m = m_getclr(M_WAIT);
+       m = m_getclr(M_WAIT, MT_SONAME);
        u.u_error =
                (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
        if (u.u_error)
                goto bad;
        u.u_error =
                (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
        if (u.u_error)
                goto bad;
-       if (copyout(mtod(m, caddr_t), (caddr_t)uap->asa, sizeof (struct sockaddr)))
-               u.u_error = EFAULT;
+       u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa,
+               sizeof (struct sockaddr));
 bad:
        m_freem(m);
 }
 bad:
        m_freem(m);
 }
@@ -544,18 +546,18 @@ sockname(aname, name, namelen)
        int namelen;
 {
        register struct mbuf *m;
        int namelen;
 {
        register struct mbuf *m;
+       int error;
 
        if (namelen > MLEN)
                return (EINVAL);
 
        if (namelen > MLEN)
                return (EINVAL);
-       m = m_get(M_WAIT);
-       m->m_off = MMINOFF;
+       m = m_get(M_WAIT, MT_SONAME);
        m->m_len = namelen;
        m->m_len = namelen;
-       if (copyin(name, mtod(m, caddr_t), namelen)) {
+       error = copyin(name, mtod(m, caddr_t), (u_int)namelen);
+       if (error)
                (void) m_free(m);
                (void) m_free(m);
-               return (EFAULT);
-       }
-       *aname = m;
-       return (0);
+       else
+               *aname = m;
+       return (error);
 }
 
 sockopt(so, opt)
 }
 
 sockopt(so, opt)
@@ -563,22 +565,24 @@ sockopt(so, opt)
        caddr_t opt;
 {
        register struct mbuf *m;
        caddr_t opt;
 {
        register struct mbuf *m;
+       int error;
 
        if (opt == 0) {
                so->so_optlen = 0;
                so->so_optdata = 0;
                return (0);
        }
 
        if (opt == 0) {
                so->so_optlen = 0;
                so->so_optdata = 0;
                return (0);
        }
-       if (copyin((caddr_t)opt, (caddr_t)so, sizeof (struct socketopt)))
-               return (EFAULT);
+       error = copyin((caddr_t)opt, (caddr_t)so, sizeof (struct socketopt));
+       if (error)
+               return (error);
        if (so->so_optlen < 0 || so->so_optlen > MLEN)
                return (EINVAL);
        if (so->so_optlen < 0 || so->so_optlen > MLEN)
                return (EINVAL);
-       m = m_get(M_WAIT);
-       m->m_off = MMINOFF;
+       m = m_get(M_WAIT, MT_SOOPTS);
        m->m_len = so->so_optlen;
        m->m_len = so->so_optlen;
-       if (copyin(so->so_optdata, mtod(m, caddr_t), m->m_len)) {
+       error = copyin(so->so_optdata, mtod(m, caddr_t), (u_int)m->m_len);
+       if (error) {
                (void) m_free(m);
                (void) m_free(m);
-               return (EFAULT);
+               return (error);
        }
        so->so_optdata = mtod(m, caddr_t);
        return (0);
        }
        so->so_optdata = mtod(m, caddr_t);
        return (0);