|
|
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 root 10:
11: #include <asm/segment.h>
1.1.1.6 root 12:
1.1.1.8 ! root 13: #include <linux/fcntl.h>
1.1.1.6 root 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.8 ! root 24: if (!PIPE_WRITERS(*inode)) /* 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;
1.1.1.8 ! root 36: memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
1.1.1.2 root 37: read += chars;
38: PIPE_TAIL(*inode) += chars;
39: PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
1.1.1.8 ! root 40: count -= chars;
! 41: buf += chars;
1.1 root 42: }
1.1.1.3 root 43: wake_up(& PIPE_WRITE_WAIT(*inode));
1.1.1.5 root 44: return read?read:-EAGAIN;
1.1 root 45: }
46:
1.1.1.6 root 47: static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
1.1 root 48: {
1.1.1.2 root 49: int chars, size, written = 0;
1.1 root 50:
1.1.1.8 ! root 51: if (!PIPE_READERS(*inode)) { /* no readers */
1.1.1.7 root 52: send_sig(SIGPIPE,current,0);
1.1.1.8 ! root 53: return -EPIPE;
1.1.1.7 root 54: }
1.1.1.8 ! root 55: /* if count < PAGE_SIZE, we have to make it atomic */
! 56: if (count < PAGE_SIZE)
! 57: size = PAGE_SIZE-count;
! 58: else
! 59: size = PAGE_SIZE-1;
1.1.1.2 root 60: while (count>0) {
1.1.1.8 ! root 61: while (PIPE_SIZE(*inode) >= size) {
! 62: if (!PIPE_READERS(*inode)) { /* no readers */
1.1.1.7 root 63: send_sig(SIGPIPE,current,0);
1.1.1.8 ! root 64: return written?written:-EPIPE;
1.1 root 65: }
1.1.1.4 root 66: if (current->signal & ~current->blocked)
1.1.1.8 ! root 67: return written?written:-ERESTARTSYS;
! 68: if (filp->f_flags & O_NONBLOCK)
! 69: return -EAGAIN;
! 70: else
! 71: interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
1.1 root 72: }
1.1.1.8 ! root 73: while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
! 74: chars = PAGE_SIZE-PIPE_HEAD(*inode);
! 75: if (chars > count)
! 76: chars = count;
! 77: if (chars > size)
! 78: chars = size;
! 79: memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
! 80: written += chars;
! 81: PIPE_HEAD(*inode) += chars;
! 82: PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
! 83: count -= chars;
! 84: buf += chars;
! 85: }
! 86: wake_up(& PIPE_READ_WAIT(*inode));
! 87: size = PAGE_SIZE-1;
1.1 root 88: }
1.1.1.2 root 89: return written;
1.1 root 90: }
91:
1.1.1.6 root 92: static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
93: {
94: return -ESPIPE;
95: }
96:
97: static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
98: {
99: return -ENOTDIR;
100: }
101:
102: static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
103: {
104: return -EBADF;
105: }
106:
107: static int pipe_ioctl(struct inode *pino, struct file * filp,
108: unsigned int cmd, unsigned int arg)
109: {
110: switch (cmd) {
111: case FIONREAD:
112: verify_area((void *) arg,4);
113: put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
114: return 0;
115: default:
116: return -EINVAL;
117: }
118: }
119:
120: /*
1.1.1.8 ! root 121: * Ok, these three routines NOW keep track of readers/writers,
! 122: * Linus previously did it with inode->i_count checking.
1.1.1.6 root 123: */
124: static void pipe_read_release(struct inode * inode, struct file * filp)
125: {
1.1.1.8 ! root 126: PIPE_READERS(*inode)--;
! 127: wake_up(&PIPE_WRITE_WAIT(*inode));
1.1.1.6 root 128: }
129:
130: static void pipe_write_release(struct inode * inode, struct file * filp)
131: {
1.1.1.8 ! root 132: PIPE_WRITERS(*inode)--;
! 133: wake_up(&PIPE_READ_WAIT(*inode));
! 134: }
! 135:
! 136: static void pipe_rdwr_release(struct inode * inode, struct file * filp)
! 137: {
! 138: PIPE_READERS(*inode)--;
! 139: PIPE_WRITERS(*inode)--;
! 140: wake_up(&PIPE_READ_WAIT(*inode));
! 141: wake_up(&PIPE_WRITE_WAIT(*inode));
1.1.1.6 root 142: }
143:
1.1.1.8 ! root 144: /*
! 145: * The three file_operations structs are not static because they
! 146: * are also used in linux/fs/fifo.c to do operations on fifo's.
! 147: */
! 148: struct file_operations read_pipe_fops = {
1.1.1.6 root 149: pipe_lseek,
150: pipe_read,
151: bad_pipe_rw,
152: pipe_readdir,
153: NULL, /* pipe_select */
154: pipe_ioctl,
155: NULL, /* no special open code */
156: pipe_read_release
157: };
158:
1.1.1.8 ! root 159: struct file_operations write_pipe_fops = {
1.1.1.6 root 160: pipe_lseek,
161: bad_pipe_rw,
162: pipe_write,
163: pipe_readdir,
164: NULL, /* pipe_select */
165: pipe_ioctl,
166: NULL, /* no special open code */
167: pipe_write_release
168: };
169:
1.1.1.8 ! root 170: struct file_operations rdwr_pipe_fops = {
! 171: pipe_lseek,
! 172: pipe_read,
! 173: pipe_write,
! 174: pipe_readdir,
! 175: NULL, /* pipe_select */
! 176: pipe_ioctl,
! 177: NULL, /* no special open code */
! 178: pipe_rdwr_release
! 179: };
! 180:
1.1 root 181: int sys_pipe(unsigned long * fildes)
182: {
1.1.1.4 root 183: struct inode * inode;
1.1 root 184: struct file * f[2];
185: int fd[2];
186: int i,j;
187:
1.1.1.7 root 188: verify_area(fildes,8);
1.1 root 189: j=0;
190: for(i=0;j<2 && i<NR_FILE;i++)
191: if (!file_table[i].f_count)
192: (f[j++]=i+file_table)->f_count++;
193: if (j==1)
194: f[0]->f_count=0;
195: if (j<2)
196: return -1;
197: j=0;
198: for(i=0;j<2 && i<NR_OPEN;i++)
199: if (!current->filp[i]) {
200: current->filp[ fd[j]=i ] = f[j];
201: j++;
202: }
203: if (j==1)
204: current->filp[fd[0]]=NULL;
205: if (j<2) {
206: f[0]->f_count=f[1]->f_count=0;
207: return -1;
208: }
209: if (!(inode=get_pipe_inode())) {
210: current->filp[fd[0]] =
211: current->filp[fd[1]] = NULL;
212: f[0]->f_count = f[1]->f_count = 0;
213: return -1;
214: }
215: f[0]->f_inode = f[1]->f_inode = inode;
216: f[0]->f_pos = f[1]->f_pos = 0;
1.1.1.7 root 217: f[0]->f_flags = f[1]->f_flags = 0;
1.1.1.6 root 218: f[0]->f_op = &read_pipe_fops;
1.1 root 219: f[0]->f_mode = 1; /* read */
1.1.1.6 root 220: f[1]->f_op = &write_pipe_fops;
1.1 root 221: f[1]->f_mode = 2; /* write */
222: put_fs_long(fd[0],0+fildes);
223: put_fs_long(fd[1],1+fildes);
224: return 0;
225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.