|
|
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.7 ! root 52: if (inode->i_count != 2) { /* no readers */
! 53: send_sig(SIGPIPE,current,0);
! 54: return -EINTR;
! 55: }
1.1.1.2 root 56: while (count>0) {
57: while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
1.1.1.3 root 58: wake_up(& PIPE_READ_WAIT(*inode));
1.1.1.2 root 59: if (inode->i_count != 2) { /* no readers */
1.1.1.7 ! root 60: send_sig(SIGPIPE,current,0);
1.1.1.4 root 61: return written?written:-EINTR;
1.1 root 62: }
1.1.1.4 root 63: if (current->signal & ~current->blocked)
64: return written?written:-EINTR;
65: interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
1.1 root 66: }
1.1.1.2 root 67: chars = PAGE_SIZE-PIPE_HEAD(*inode);
68: if (chars > count)
69: chars = count;
70: if (chars > size)
71: chars = size;
72: count -= chars;
73: written += chars;
74: size = PIPE_HEAD(*inode);
75: PIPE_HEAD(*inode) += chars;
76: PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
77: while (chars-->0)
78: ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
1.1 root 79: }
1.1.1.3 root 80: wake_up(& PIPE_READ_WAIT(*inode));
1.1.1.2 root 81: return written;
1.1 root 82: }
83:
1.1.1.6 root 84: static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
85: {
86: return -ESPIPE;
87: }
88:
89: static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
90: {
91: return -ENOTDIR;
92: }
93:
94: static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
95: {
96: return -EBADF;
97: }
98:
99: static int pipe_ioctl(struct inode *pino, struct file * filp,
100: unsigned int cmd, unsigned int arg)
101: {
102: switch (cmd) {
103: case FIONREAD:
104: verify_area((void *) arg,4);
105: put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
106: return 0;
107: default:
108: return -EINVAL;
109: }
110: }
111:
112: /*
113: * Ok, these two routines should keep track of readers/writers,
114: * but it's currently done with the inode->i_count checking.
115: */
116: static void pipe_read_release(struct inode * inode, struct file * filp)
117: {
118: }
119:
120: static void pipe_write_release(struct inode * inode, struct file * filp)
121: {
122: }
123:
124: static struct file_operations read_pipe_fops = {
125: pipe_lseek,
126: pipe_read,
127: bad_pipe_rw,
128: pipe_readdir,
129: NULL, /* pipe_select */
130: pipe_ioctl,
131: NULL, /* no special open code */
132: pipe_read_release
133: };
134:
135: static struct file_operations write_pipe_fops = {
136: pipe_lseek,
137: bad_pipe_rw,
138: pipe_write,
139: pipe_readdir,
140: NULL, /* pipe_select */
141: pipe_ioctl,
142: NULL, /* no special open code */
143: pipe_write_release
144: };
145:
1.1 root 146: int sys_pipe(unsigned long * fildes)
147: {
1.1.1.4 root 148: struct inode * inode;
1.1 root 149: struct file * f[2];
150: int fd[2];
151: int i,j;
152:
1.1.1.7 ! root 153: verify_area(fildes,8);
1.1 root 154: j=0;
155: for(i=0;j<2 && i<NR_FILE;i++)
156: if (!file_table[i].f_count)
157: (f[j++]=i+file_table)->f_count++;
158: if (j==1)
159: f[0]->f_count=0;
160: if (j<2)
161: return -1;
162: j=0;
163: for(i=0;j<2 && i<NR_OPEN;i++)
164: if (!current->filp[i]) {
165: current->filp[ fd[j]=i ] = f[j];
166: j++;
167: }
168: if (j==1)
169: current->filp[fd[0]]=NULL;
170: if (j<2) {
171: f[0]->f_count=f[1]->f_count=0;
172: return -1;
173: }
174: if (!(inode=get_pipe_inode())) {
175: current->filp[fd[0]] =
176: current->filp[fd[1]] = NULL;
177: f[0]->f_count = f[1]->f_count = 0;
178: return -1;
179: }
180: f[0]->f_inode = f[1]->f_inode = inode;
181: f[0]->f_pos = f[1]->f_pos = 0;
1.1.1.7 ! root 182: f[0]->f_flags = f[1]->f_flags = 0;
1.1.1.6 root 183: f[0]->f_op = &read_pipe_fops;
1.1 root 184: f[0]->f_mode = 1; /* read */
1.1.1.6 root 185: f[1]->f_op = &write_pipe_fops;
1.1 root 186: f[1]->f_mode = 2; /* write */
187: put_fs_long(fd[0],0+fildes);
188: put_fs_long(fd[1],1+fildes);
189: return 0;
190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.