+ * Pipe system call interface.
+ */
+spipe()
+{
+ register struct file *rf, *wf;
+ struct socket *rso, *wso;
+ int r;
+COUNT(SPIPE);
+
+ u.u_error = socreate(&rso, SOCK_STREAM,
+ &localproto, (struct sockaddr *)0, 0);
+ if (u.u_error)
+ return;
+ u.u_error = socreate(&wso, SOCK_STREAM,
+ &localproto, (struct sockaddr *)0, 0);
+ if (u.u_error)
+ goto free;
+ rf = falloc();
+ if (rf == NULL)
+ goto free2;
+ r = u.u_r.r_val1;
+ rf->f_flag = FREAD|FSOCKET;
+ rf->f_socket = rso;
+ wf = falloc();
+ if (wf == NULL)
+ goto free3;
+ wf->f_flag = FWRITE|FSOCKET;
+ wf->f_socket = wso;
+ u.u_r.r_val2 = u.u_r.r_val1;
+ u.u_r.r_val1 = r;
+ if (piconnect(wso, rso) == 0)
+ goto free4;
+ return;
+free4:
+ wf->f_count = 0;
+ u.u_ofile[u.u_r.r_val1] = 0;
+free3:
+ rf->f_count = 0;
+ u.u_ofile[r] = 0;
+free2:
+ wso->so_state |= SS_USERGONE;
+ sofree(wso);
+free:
+ rso->so_state |= SS_USERGONE;
+ sofree(rso);
+}
+
+/*
+ * Splice system call interface.
+ */
+ssplice()
+{
+ register struct a {
+ int fd1;
+ int fd2;
+ } *ap = (struct a *)u.u_ap;
+ struct file *f1, *f2;
+COUNT(SSPLICE);
+
+ f1 = getf(ap->fd1);
+ if (f1 == NULL)
+ return;
+ f2 = getf(ap->fd2);
+ if (f2 == NULL)
+ return;
+ if (f1 == f2) {
+ u.u_error = EINVAL;
+ return;
+ }
+ if ((f1->f_flag & FSOCKET) == 0 || (f2->f_flag & FSOCKET) == 0) {
+ u.u_error = ENOTSOCK;
+ return;
+ }
+ if (f1->f_count > 1 || f2->f_count > 1) {
+ u.u_error = ETOOMANYREFS;
+ return;
+ }
+ u.u_error = sosplice(f1->f_socket, f2->f_socket);
+ if (u.u_error)
+ return;
+ u.u_ofile[ap->fd1] = 0;
+ u.u_ofile[ap->fd2] = 0;
+ f1->f_count = 0;
+ f2->f_count = 0;
+}
+
+/*
+ * Socket system call interface. Copy sa arguments