add directory kernel
This commit is contained in:
131
kernel/0.95/linux-0.95/fs/pipe.c
Normal file
131
kernel/0.95/linux-0.95/fs/pipe.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* linux/fs/pipe.c
|
||||
*
|
||||
* (C) 1991 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/segment.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
|
||||
{
|
||||
int chars, size, read = 0;
|
||||
|
||||
if (!(filp->f_flags & O_NONBLOCK))
|
||||
while (!PIPE_SIZE(*inode)) {
|
||||
wake_up(& PIPE_WRITE_WAIT(*inode));
|
||||
if (inode->i_count != 2) /* are there any writers? */
|
||||
return 0;
|
||||
if (current->signal & ~current->blocked)
|
||||
return -ERESTARTSYS;
|
||||
interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
|
||||
}
|
||||
while (count>0 && (size = PIPE_SIZE(*inode))) {
|
||||
chars = PAGE_SIZE-PIPE_TAIL(*inode);
|
||||
if (chars > count)
|
||||
chars = count;
|
||||
if (chars > size)
|
||||
chars = size;
|
||||
count -= chars;
|
||||
read += chars;
|
||||
size = PIPE_TAIL(*inode);
|
||||
PIPE_TAIL(*inode) += chars;
|
||||
PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
|
||||
while (chars-->0)
|
||||
put_fs_byte(((char *)inode->i_size)[size++],buf++);
|
||||
}
|
||||
wake_up(& PIPE_WRITE_WAIT(*inode));
|
||||
return read;
|
||||
}
|
||||
|
||||
int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
|
||||
{
|
||||
int chars, size, written = 0;
|
||||
|
||||
while (count>0) {
|
||||
while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
|
||||
wake_up(& PIPE_READ_WAIT(*inode));
|
||||
if (inode->i_count != 2) { /* no readers */
|
||||
current->signal |= (1<<(SIGPIPE-1));
|
||||
return written?written:-EINTR;
|
||||
}
|
||||
if (current->signal & ~current->blocked)
|
||||
return written?written:-EINTR;
|
||||
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
|
||||
}
|
||||
chars = PAGE_SIZE-PIPE_HEAD(*inode);
|
||||
if (chars > count)
|
||||
chars = count;
|
||||
if (chars > size)
|
||||
chars = size;
|
||||
count -= chars;
|
||||
written += chars;
|
||||
size = PIPE_HEAD(*inode);
|
||||
PIPE_HEAD(*inode) += chars;
|
||||
PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
|
||||
while (chars-->0)
|
||||
((char *)inode->i_size)[size++]=get_fs_byte(buf++);
|
||||
}
|
||||
wake_up(& PIPE_READ_WAIT(*inode));
|
||||
return written;
|
||||
}
|
||||
|
||||
int sys_pipe(unsigned long * fildes)
|
||||
{
|
||||
struct inode * inode;
|
||||
struct file * f[2];
|
||||
int fd[2];
|
||||
int i,j;
|
||||
|
||||
j=0;
|
||||
for(i=0;j<2 && i<NR_FILE;i++)
|
||||
if (!file_table[i].f_count)
|
||||
(f[j++]=i+file_table)->f_count++;
|
||||
if (j==1)
|
||||
f[0]->f_count=0;
|
||||
if (j<2)
|
||||
return -1;
|
||||
j=0;
|
||||
for(i=0;j<2 && i<NR_OPEN;i++)
|
||||
if (!current->filp[i]) {
|
||||
current->filp[ fd[j]=i ] = f[j];
|
||||
j++;
|
||||
}
|
||||
if (j==1)
|
||||
current->filp[fd[0]]=NULL;
|
||||
if (j<2) {
|
||||
f[0]->f_count=f[1]->f_count=0;
|
||||
return -1;
|
||||
}
|
||||
if (!(inode=get_pipe_inode())) {
|
||||
current->filp[fd[0]] =
|
||||
current->filp[fd[1]] = NULL;
|
||||
f[0]->f_count = f[1]->f_count = 0;
|
||||
return -1;
|
||||
}
|
||||
f[0]->f_inode = f[1]->f_inode = inode;
|
||||
f[0]->f_pos = f[1]->f_pos = 0;
|
||||
f[0]->f_mode = 1; /* read */
|
||||
f[1]->f_mode = 2; /* write */
|
||||
put_fs_long(fd[0],0+fildes);
|
||||
put_fs_long(fd[1],1+fildes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pipe_ioctl(struct inode *pino, int cmd, int arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case FIONREAD:
|
||||
verify_area((void *) arg,4);
|
||||
put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user