socketpair
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Wed, 15 Jun 1983 11:40:51 +0000 (03:40 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Wed, 15 Jun 1983 11:40:51 +0000 (03:40 -0800)
SCCS-vsn: sys/kern/uipc_socket.c 4.76
SCCS-vsn: sys/kern/uipc_syscalls.c 4.47
SCCS-vsn: sys/kern/uipc_usrreq.c 1.13

usr/src/sys/kern/uipc_socket.c
usr/src/sys/kern/uipc_syscalls.c
usr/src/sys/kern/uipc_usrreq.c

index 2e1ef22..4ee7c88 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_socket.c   4.75    83/05/27        */
+/*     uipc_socket.c   4.76    83/06/14        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -226,7 +226,6 @@ bad:
        return (error);
 }
 
        return (error);
 }
 
-#ifdef notdef
 soconnect2(so1, so2)
        register struct socket *so1;
        struct socket *so2;
 soconnect2(so1, so2)
        register struct socket *so1;
        struct socket *so2;
@@ -234,13 +233,11 @@ soconnect2(so1, so2)
        int s = splnet();
        int error;
 
        int s = splnet();
        int error;
 
-       error =
-           (*so1->so_proto->pr_usrreq)(so, PRU_CONNECT2,
-               (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
+       error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
+           (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
        splx(s);
        return (error);
 }
        splx(s);
        return (error);
 }
-#endif
 
 sodisconnect(so, nam)
        register struct socket *so;
 
 sodisconnect(so, nam)
        register struct socket *so;
index 9e0e60c..2dac5ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_syscalls.c 4.46    83/05/27        */
+/*     uipc_syscalls.c 4.47    83/06/14        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -210,8 +210,59 @@ bad:
 
 socketpair()
 {
 
 socketpair()
 {
+       register struct a {
+               int     domain;
+               int     type;
+               int     protocol;
+               int     *rsv;
+       } *uap = (struct a *)u.u_ap;
+       register struct file *fp1, *fp2;
+       struct socket *so1, *so2;
+       int sv[2];
 
 
-       u.u_error = ENOENT;
+       if (useracc((caddr_t)uap->rsv, 2 * sizeof (int), B_WRITE) == 0) {
+               u.u_error = EFAULT;
+               return;
+       }
+       u.u_error = socreate(uap->domain, &so1, uap->type, uap->protocol);
+       if (u.u_error)
+               return;
+       u.u_error = socreate(uap->domain, &so2, uap->type, uap->protocol);
+       if (u.u_error)
+               goto free;
+       fp1 = falloc();
+       if (fp1 == NULL)
+               goto free2;
+       sv[0] = u.u_r.r_val1;
+       fp1->f_flag = FREAD|FWRITE;
+       fp1->f_type = DTYPE_SOCKET;
+       fp1->f_ops = &socketops;
+       fp1->f_data = (caddr_t)so1;
+       fp2 = falloc();
+       if (fp2 == NULL)
+               goto free3;
+       fp2->f_flag = FREAD|FWRITE;
+       fp2->f_type = DTYPE_SOCKET;
+       fp2->f_ops = &socketops;
+       fp2->f_data = (caddr_t)so2;
+       sv[1] = u.u_r.r_val1;
+       u.u_error = soconnect2(so1, so2);
+       if (u.u_error)
+               goto free4;
+       (void) copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
+       return;
+free4:
+       fp2->f_count = 0;
+       u.u_ofile[sv[1]] = 0;
+free3:
+       fp1->f_count = 0;
+       u.u_ofile[sv[0]] = 0;
+free2:
+       so2->so_state |= SS_NOFDREF;
+       sofree(so2);
+free:
+       so1->so_state |= SS_NOFDREF;
+       sofree(so1);
 }
 
 sendto()
 }
 
 sendto()
index f325e36..7a735ed 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_usrreq.c   1.12    83/06/13        */
+/*     uipc_usrreq.c   1.13    83/06/14        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -67,12 +67,11 @@ uipc_usrreq(so, req, m, nam, rights)
                error = unp_connect(so, nam);
                break;
 
                error = unp_connect(so, nam);
                break;
 
-#ifdef notdef
        case PRU_CONNECT2:
        case PRU_CONNECT2:
-               error = unp_connect2(so, (struct mbuf *)0, (struct socket *)nam);
+               error = unp_connect2(so, (struct mbuf *)0,
+                   (struct socket *)nam);
                break;
 
                break;
 
-#endif
        case PRU_DISCONNECT:
                unp_disconnect(unp);
                break;
        case PRU_DISCONNECT:
                unp_disconnect(unp);
                break;
@@ -325,6 +324,16 @@ unp_connect(so, nam)
                error = ECONNREFUSED;
                goto bad;
        }
                error = ECONNREFUSED;
                goto bad;
        }
+       if (so->so_type != so2->so_type) {
+               error = EPROTOTYPE;
+               goto bad;
+       }
+       if (so->so_proto->pr_flags & PR_CONNREQUIRED &&
+           ((so2->so_options&SO_ACCEPTCONN) == 0 ||
+            (so2 = sonewconn(so2)) == 0)) {
+               error = ECONNREFUSED;
+               goto bad;
+       }
        error = unp_connect2(so, nam, so2);
 bad:
        iput(ip);
        error = unp_connect2(so, nam, so2);
 bad:
        iput(ip);
@@ -351,9 +360,6 @@ unp_connect2(so, sonam, so2)
                break;
 
        case SOCK_STREAM:
                break;
 
        case SOCK_STREAM:
-               if ((so2->so_options&SO_ACCEPTCONN) == 0 ||
-                   (so2 = sonewconn(so2)) == 0)
-                       return (ECONNREFUSED);
                unp2 = sotounpcb(so2);
                unp->unp_conn = unp2;
                unp2->unp_conn = unp;
                unp2 = sotounpcb(so2);
                unp->unp_conn = unp2;
                unp2->unp_conn = unp;