summaryrefslogtreecommitdiffstats
path: root/src/fs/pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/pipe.c')
-rw-r--r--src/fs/pipe.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/fs/pipe.c b/src/fs/pipe.c
new file mode 100644
index 0000000..dfc4480
--- /dev/null
+++ b/src/fs/pipe.c
@@ -0,0 +1,111 @@
1/*
2 * linux/fs/pipe.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#include <signal.h>
8
9#include <linux/sched.h>
10#include <linux/mm.h> /* for get_free_page */
11#include <asm/segment.h>
12
13int read_pipe(struct m_inode * inode, char * buf, int count)
14{
15 int chars, size, read = 0;
16
17 while (count>0) {
18 while (!(size=PIPE_SIZE(*inode))) {
19 wake_up(&inode->i_wait);
20 if (inode->i_count != 2) /* are there any writers? */
21 return read;
22 sleep_on(&inode->i_wait);
23 }
24 chars = PAGE_SIZE-PIPE_TAIL(*inode);
25 if (chars > count)
26 chars = count;
27 if (chars > size)
28 chars = size;
29 count -= chars;
30 read += chars;
31 size = PIPE_TAIL(*inode);
32 PIPE_TAIL(*inode) += chars;
33 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
34 while (chars-->0)
35 put_fs_byte(((char *)inode->i_size)[size++],buf++);
36 }
37 wake_up(&inode->i_wait);
38 return read;
39}
40
41int write_pipe(struct m_inode * inode, char * buf, int count)
42{
43 int chars, size, written = 0;
44
45 while (count>0) {
46 while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
47 wake_up(&inode->i_wait);
48 if (inode->i_count != 2) { /* no readers */
49 current->signal |= (1<<(SIGPIPE-1));
50 return written?written:-1;
51 }
52 sleep_on(&inode->i_wait);
53 }
54 chars = PAGE_SIZE-PIPE_HEAD(*inode);
55 if (chars > count)
56 chars = count;
57 if (chars > size)
58 chars = size;
59 count -= chars;
60 written += chars;
61 size = PIPE_HEAD(*inode);
62 PIPE_HEAD(*inode) += chars;
63 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
64 while (chars-->0)
65 ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
66 }
67 wake_up(&inode->i_wait);
68 return written;
69}
70
71int sys_pipe(unsigned long * fildes)
72{
73 struct m_inode * inode;
74 struct file * f[2];
75 int fd[2];
76 int i,j;
77
78 j=0;
79 for(i=0;j<2 && i<NR_FILE;i++)
80 if (!file_table[i].f_count)
81 (f[j++]=i+file_table)->f_count++;
82 if (j==1)
83 f[0]->f_count=0;
84 if (j<2)
85 return -1;
86 j=0;
87 for(i=0;j<2 && i<NR_OPEN;i++)
88 if (!current->filp[i]) {
89 current->filp[ fd[j]=i ] = f[j];
90 j++;
91 }
92 if (j==1)
93 current->filp[fd[0]]=NULL;
94 if (j<2) {
95 f[0]->f_count=f[1]->f_count=0;
96 return -1;
97 }
98 if (!(inode=get_pipe_inode())) {
99 current->filp[fd[0]] =
100 current->filp[fd[1]] = NULL;
101 f[0]->f_count = f[1]->f_count = 0;
102 return -1;
103 }
104 f[0]->f_inode = f[1]->f_inode = inode;
105 f[0]->f_pos = f[1]->f_pos = 0;
106 f[0]->f_mode = 1; /* read */
107 f[1]->f_mode = 2; /* write */
108 put_fs_long(fd[0],0+fildes);
109 put_fs_long(fd[1],1+fildes);
110 return 0;
111}