|
|
1.1.1.2 root 1: /*
2: * linux/fs/pipe.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
1.1 root 7: #include <signal.h>
1.1.1.3 root 8: #include <errno.h>
9: #include <termios.h>
1.1.1.4 root 10: #include <fcntl.h>
1.1 root 11:
12: #include <asm/segment.h>
1.1.1.6 ! root 13:
! 14: #include <linux/sched.h>
1.1.1.3 root 15: #include <linux/kernel.h>
1.1 root 16:
1.1.1.6 ! root 17: static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
1.1 root 18: {
1.1.1.2 root 19: int chars, size, read = 0;
1.1 root 20:
1.1.1.4 root 21: if (!(filp->f_flags & O_NONBLOCK))
22: while (!PIPE_SIZE(*inode)) {
1.1.1.3 root 23: wake_up(& PIPE_WRITE_WAIT(*inode));
1.1.1.2 root 24: if (inode->i_count != 2) /* are there any writers? */
1.1.1.4 root 25: return 0;
1.1.1.3 root 26: if (current->signal & ~current->blocked)
1.1.1.4 root 27: return -ERESTARTSYS;
1.1.1.3 root 28: interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
1.1.1.2 root 29: }
1.1.1.4 root 30: while (count>0 && (size = PIPE_SIZE(*inode))) {
1.1.1.2 root 31: chars = PAGE_SIZE-PIPE_TAIL(*inode);
32: if (chars > count)
33: chars = count;
34: if (chars > size)
35: chars = size;
36: count -= chars;
37: read += chars;
38: size = PIPE_TAIL(*inode);
39: PIPE_TAIL(*inode) += chars;
40: PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
41: while (chars-->0)
42: put_fs_byte(((char *)inode->i_size)[size++],buf++);
1.1 root 43: }
1.1.1.3 root 44: wake_up(& PIPE_WRITE_WAIT(*inode));
1.1.1.5 root 45: return read?read:-EAGAIN;
1.1 root 46: }
47:
1.1.1.6 ! root 48: static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
1.1 root 49: {
1.1.1.2 root 50: int chars, size, written = 0;
1.1 root 51:
1.1.1.2 root 52: while (count>0) {
53: while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
1.1.1.3 root 54: wake_up(& PIPE_READ_WAIT(*inode));
1.1.1.2 root 55: if (inode->i_count != 2) { /* no readers */
1.1 root 56: current->signal |= (1<<(SIGPIPE-1));
1.1.1.4 root 57: return written?written:-EINTR;
1.1 root 58: }
1.1.1.4 root 59: if (current->signal & ~current->blocked)
60: return written?written:-EINTR;
61: interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
1.1 root 62: }
1.1.1.2 root 63: chars = PAGE_SIZE-PIPE_HEAD(*inode);
64: if (chars > count)
65: chars = count;
66: if (chars > size)
67: chars = size;
68: count -= chars;
69: written += chars;
70: size = PIPE_HEAD(*inode);
71: PIPE_HEAD(*inode) += chars;
72: PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
73: while (chars-->0)
74: ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
1.1 root 75: }
1.1.1.3 root 76: wake_up(& PIPE_READ_WAIT(*inode));
1.1.1.2 root 77: return written;
1.1 root 78: }
79:
1.1.1.6 ! root 80: static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
! 81: {
! 82: return -ESPIPE;
! 83: }
! 84:
! 85: static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
! 86: {
! 87: return -ENOTDIR;
! 88: }
! 89:
! 90: static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
! 91: {
! 92: return -EBADF;
! 93: }
! 94:
! 95: static int pipe_ioctl(struct inode *pino, struct file * filp,
! 96: unsigned int cmd, unsigned int arg)
! 97: {
! 98: switch (cmd) {
! 99: case FIONREAD:
! 100: verify_area((void *) arg,4);
! 101: put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
! 102: return 0;
! 103: default:
! 104: return -EINVAL;
! 105: }
! 106: }
! 107:
! 108: /*
! 109: * Ok, these two routines should keep track of readers/writers,
! 110: * but it's currently done with the inode->i_count checking.
! 111: */
! 112: static void pipe_read_release(struct inode * inode, struct file * filp)
! 113: {
! 114: }
! 115:
! 116: static void pipe_write_release(struct inode * inode, struct file * filp)
! 117: {
! 118: }
! 119:
! 120: static struct file_operations read_pipe_fops = {
! 121: pipe_lseek,
! 122: pipe_read,
! 123: bad_pipe_rw,
! 124: pipe_readdir,
! 125: NULL, /* pipe_select */
! 126: pipe_ioctl,
! 127: NULL, /* no special open code */
! 128: pipe_read_release
! 129: };
! 130:
! 131: static struct file_operations write_pipe_fops = {
! 132: pipe_lseek,
! 133: bad_pipe_rw,
! 134: pipe_write,
! 135: pipe_readdir,
! 136: NULL, /* pipe_select */
! 137: pipe_ioctl,
! 138: NULL, /* no special open code */
! 139: pipe_write_release
! 140: };
! 141:
1.1 root 142: int sys_pipe(unsigned long * fildes)
143: {
1.1.1.4 root 144: struct inode * inode;
1.1 root 145: struct file * f[2];
146: int fd[2];
147: int i,j;
148:
149: j=0;
150: for(i=0;j<2 && i<NR_FILE;i++)
151: if (!file_table[i].f_count)
152: (f[j++]=i+file_table)->f_count++;
153: if (j==1)
154: f[0]->f_count=0;
155: if (j<2)
156: return -1;
157: j=0;
158: for(i=0;j<2 && i<NR_OPEN;i++)
159: if (!current->filp[i]) {
160: current->filp[ fd[j]=i ] = f[j];
161: j++;
162: }
163: if (j==1)
164: current->filp[fd[0]]=NULL;
165: if (j<2) {
166: f[0]->f_count=f[1]->f_count=0;
167: return -1;
168: }
169: if (!(inode=get_pipe_inode())) {
170: current->filp[fd[0]] =
171: current->filp[fd[1]] = NULL;
172: f[0]->f_count = f[1]->f_count = 0;
173: return -1;
174: }
175: f[0]->f_inode = f[1]->f_inode = inode;
176: f[0]->f_pos = f[1]->f_pos = 0;
1.1.1.6 ! root 177: f[0]->f_op = &read_pipe_fops;
1.1 root 178: f[0]->f_mode = 1; /* read */
1.1.1.6 ! root 179: f[1]->f_op = &write_pipe_fops;
1.1 root 180: f[1]->f_mode = 2; /* write */
181: put_fs_long(fd[0],0+fildes);
182: put_fs_long(fd[1],1+fildes);
183: return 0;
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.