V8/usr/sys/sys/pipe.c
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/reg.h"
#include "../h/inline.h"
#include "../h/proc.h"
#include "../h/stream.h"
struct inode *mkpipend();
/*
* The sys-pipe entry.
* Allocate 2 open inodes, stream them, and splice them together
*/
pipe()
{
struct inode *ip1, *ip2;
register struct file *rf, *wf;
register r;
extern struct streamtab nilinfo;
rf = falloc();
if(rf == NULL)
return;
r = u.u_r.r_val1;
wf = falloc();
if(wf == NULL) {
rf->f_count = 0;
u.u_ofile[r] = NULL;
return;
}
u.u_r.r_val2 = u.u_r.r_val1;
u.u_r.r_val1 = r;
if (makepipe(&ip1, &ip2)==0) {
rf->f_count = 0;
wf->f_count = 0;
u.u_ofile[u.u_r.r_val1] = NULL;
u.u_ofile[u.u_r.r_val2] = NULL;
return;
}
wf->f_flag = FREAD|FWRITE;
wf->f_inode = ip1;
rf->f_flag = FREAD|FWRITE;
rf->f_inode = ip2;
}
makepipe(ip1, ip2)
register struct inode **ip1, **ip2;
{
*ip1 = mkpipend();
*ip2 = mkpipend();
if (*ip1==NULL || *ip2==NULL) {
if (*ip1) {
stclose(*ip1, 0);
iput(*ip1);
}
if (*ip2) {
stclose(*ip2, 0);
iput(*ip2);
}
return(0);
}
qdetach(RD((*ip1)->i_sptr->wrq->next), 1);
(*ip1)->i_sptr->wrq->next = RD((*ip2)->i_sptr->wrq);
qdetach(RD((*ip2)->i_sptr->wrq->next), 1);
(*ip2)->i_sptr->wrq->next = RD((*ip1)->i_sptr->wrq);
return(1);
}
struct inode *
mkpipend()
{
register struct inode *ip;
ip = ialloc(pipedev);
if(ip == NULL)
return;
ip->i_mode = IFREG | (0666 & ~u.u_cmask);
stopen(&nilinfo, (dev_t)0, 0, ip);
if (u.u_error) {
iput(ip);
return(NULL);
}
ip->i_uid = u.u_uid;
ip->i_gid = u.u_gid;
prele(ip);
return(ip);
}
#ifdef plock
#undef plock
#endif
#ifdef prele
#undef prele
#endif
/*
* Lock an inode
* If its already locked,
* set the WANT bit and sleep.
*/
plock(ip)
register struct inode *ip;
{
while(ip->i_flag&ILOCK) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
}
ip->i_flag |= ILOCK;
}
/*
* Unlock an inode.
* If WANT bit is on,
* wakeup.
*/
prele(ip)
register struct inode *ip;
{
ip->i_flag &= ~ILOCK;
if(ip->i_flag&IWANT) {
ip->i_flag &= ~IWANT;
wakeup((caddr_t)ip);
}
}