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