Research V5 development
authorKen Thompson <ken@research.uucp>
Tue, 26 Nov 1974 23:13:21 +0000 (18:13 -0500)
committerKen Thompson <ken@research.uucp>
Tue, 26 Nov 1974 23:13:21 +0000 (18:13 -0500)
Work on file usr/sys/ken/pipe.c

Synthesized-from: v5

usr/sys/ken/pipe.c [new file with mode: 0644]

diff --git a/usr/sys/ken/pipe.c b/usr/sys/ken/pipe.c
new file mode 100644 (file)
index 0000000..cc5cf99
--- /dev/null
@@ -0,0 +1,134 @@
+#
+/*
+ *     Copyright 1973 Bell Telephone Laboratories Inc
+ */
+
+#include "../param.h"
+#include "../systm.h"
+#include "../user.h"
+#include "../inode.h"
+#include "../file.h"
+#include "../reg.h"
+
+#define        PIPSIZ  4096
+pipe()
+{
+       register *ip, *rf, *wf;
+
+       ip = ialloc(rootdev);
+       if(ip == NULL)
+               return;
+       wf = falloc();
+       if(wf == NULL) {
+               iput(ip);
+               return;
+       }
+       u.u_ar0[R1] = u.u_ar0[R0];
+       rf = falloc();
+       if(rf == NULL) {
+               wf->f_count = 0;
+               u.u_ofile[u.u_ar0[R1]] = NULL;
+               iput(ip);
+               return;
+       }
+       wf->f_flag = FWRITE|FPIPE;
+       wf->f_inode = ip;
+       rf->f_flag = FREAD|FPIPE;
+       rf->f_inode = ip;
+       ip->i_count = 2;
+       ip->i_flag = IACC|IUPD;
+       ip->i_mode = IALLOC;
+}
+
+readp(fp)
+int *fp;
+{
+       register *rp, *ip;
+
+       rp = fp;
+       ip = rp->f_inode;
+
+loop:
+       plock(ip);
+       if(rp->f_offset[1] == ip->i_size1) {
+               if(rp->f_offset[1] != 0) {
+                       rp->f_offset[1] = 0;
+                       ip->i_size1 = 0;
+                       if(ip->i_mode&IWRITE) {
+                               ip->i_mode =& ~IWRITE;
+                               wakeup(ip+1);
+                       }
+               }
+               prele(ip);
+               if(ip->i_count < 2)
+                       return;
+               ip->i_mode =| IREAD;
+               sleep(ip+2, PPIPE);
+               goto loop;
+       }
+       u.u_offset[0] = 0;
+       u.u_offset[1] = rp->f_offset[1];
+       readi(ip);
+       rp->f_offset[1] = u.u_offset[1];
+       prele(ip);
+}
+
+writep(fp)
+{
+       register *rp, *ip, c;
+
+       rp = fp;
+       ip = rp->f_inode;
+       c = u.u_count;
+
+loop:
+       plock(ip);
+       if(ip->i_count<2 || c==0) {
+               prele(ip);
+               u.u_count = c;
+               return;
+       }
+       if(ip->i_size1 == PIPSIZ) {
+               ip->i_mode =| IWRITE;
+               prele(ip);
+               sleep(ip+1, PPIPE);
+               goto loop;
+       }
+       u.u_offset[0] = 0;
+       u.u_offset[1] = ip->i_size1;
+       u.u_count = min(c, PIPSIZ-u.u_offset[1]);
+       c =- u.u_count;
+       writei(ip);
+       prele(ip);
+       if(ip->i_mode&IREAD) {
+               ip->i_mode =& ~IREAD;
+               wakeup(ip+2);
+       }
+       goto loop;
+}
+
+plock(ip)
+int *ip;
+{
+       register *rp;
+
+       rp = ip;
+       while(rp->i_flag&ILOCK) {
+               rp->i_flag =| IWANT;
+               sleep(rp, PPIPE);
+       }
+       rp->i_flag =| ILOCK;
+}
+
+prele(ip)
+int *ip;
+{
+       register *rp;
+
+       rp = ip;
+       rp->i_flag =& ~ILOCK;
+       if(rp->i_flag&IWANT) {
+               rp->i_flag =& ~IWANT;
+               wakeup(rp);
+       }
+}