1 /*
2 * linux/fs/pipe.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 #include <signal.h> // �ź�ͷ�ļ��������źŷ��ų������źŽṹ����������ԭ�͡�
8 #include <errno.h> // �����ͷ�ļ�������ϵͳ�и��ֳ����š�
9 #include <termios.h> // �ն������������ͷ�ļ�����Ҫ��������첽ͨ�ſڵ��ն˽ӿڡ�
10
11 #include <linux/sched.h> // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�
12 #include <linux/mm.h> /* for get_free_page */ /* ʹ�����е�get_free_page */
13 #include <asm/segment.h> // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����
14 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣
15
//// �ܵ�������������
// ����inode�ǹܵ���Ӧ��i�ڵ㣬buf���û����ݻ�����ָ�룬count�Ƕ�ȡ���ֽ�����
16 int read_pipe(struct m_inode * inode, char * buf, int count)
17 {
18 int chars, size, read = 0;
19
// �����Ҫ��ȡ���ֽڼ���count����0�����Ǿ�ѭ��ִ�����²�������ѭ�������������У�
// ����ǰ�ܵ���û�����ݣ�size=0�������ѵȴ��ýڵ�Ľ��̣���ͨ����д�ܵ����̡����
// ��û��д�ܵ��ߣ��� i�ڵ����ü���ֵС��2�����Ѷ��ֽ����˳��������ǰ�յ��з�
// �����źţ������̷����Ѷ�ȡ�ֽ����˳�������û���յ��κ����ݣ�����������ϵͳ
// ���ú��˳���������ý����ڸùܵ���˯�ߣ����Եȴ���Ϣ�ĵ�������PIPE_SIZE������
// include/linux/fs.h�С����ڡ���������ϵͳ���á�����μ�kernel/signal.c����
20 while (count>0) {
21 while (!(size=PIPE_SIZE(*inode))) { // ȡ�ܵ������ݳ���ֵ��
22 wake_up(& PIPE_WRITE_WAIT(*inode));
23 if (inode->i_count != 2) /* are there any writers? */
24 return read;
25 if (current->signal & ~current->blocked)
26 return read?read:-ERESTARTSYS;
27 interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
28 }
// ��ʱ˵���ܵ������������������ݡ���������ȡ�ܵ�βָ�뵽������ĩ�˵��ֽ���chars��
// �������ڻ���Ҫ��ȡ���ֽ���count�����������count�����chars���ڵ�ǰ�ܵ��к�
// �����ݵij��� size����������� size�� Ȼ�������ֽ���count��ȥ�˴οɶ����ֽ���
// chars�����ۼ��Ѷ��ֽ���read��
29 chars = PAGE_SIZE-PIPE_TAIL(*inode);
30 if (chars > count)
31 chars = count;
32 if (chars > size)
33 chars = size;
34 count -= chars;
35 read += chars;
// ����sizeָ��ܵ�βָ�봦����������ǰ�ܵ�βָ�루ǰ��chars�ֽڣ�����βָ�볬��
// �ܵ�ĩ�����ƻء�Ȼ�ܵ��е����ݸ��Ƶ��û��������С����ڹܵ�i�ڵ㣬��i_size
// �ֶ����ǹܵ������ָ�롣
36 size = PIPE_TAIL(*inode);
37 PIPE_TAIL(*inode) += chars;
38 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
39 while (chars-->0)
40 put_fs_byte(((char *)inode->i_size)[size++],buf++);
41 }
// ���˴ζ��ܵ��������������ѵȴ��ùܵ��Ľ��̣������ض�ȡ���ֽ�����
42 wake_up(& PIPE_WRITE_WAIT(*inode));
43 return read;
44 }
45
//// �ܵ�д����������
// ����inode�ǹܵ���Ӧ��i�ڵ㣬buf�����ݻ�����ָ�룬count�ǽ�д��ܵ����ֽ�����
46 int write_pipe(struct m_inode * inode, char * buf, int count)
47 {
48 int chars, size, written = 0;
49
// ���Ҫд����ֽ���count������0����ô���Ǿ�ѭ��ִ�����²�������ѭ�����������У�
// �����ǰ�ܵ����Ѿ����ˣ����пռ� size = 0�������ѵȴ��ùܵ��Ľ��̣�ͨ������
// ���Ƕ��ܵ����̡� �����û�ж��ܵ��ߣ���i�ڵ����ü���ֵС��2������ǰ���̷���
// SIGPIPE�źţ���������д����ֽ����˳�����д��0�ֽڣ��� -1�������õ�ǰ����
// �ڸùܵ���˯�ߣ��Եȴ����ܵ���������ȡ���ݣ��Ӷ��ùܵ��ڳ��ռ䡣��PIPE_SIZE()��
// PIPE_HEAD()�ȶ������ļ�include/linux/fs.h�С�
50 while (count>0) {
51 while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
52 wake_up(& PIPE_READ_WAIT(*inode));
53 if (inode->i_count != 2) { /* no readers */
54 current->signal |= (1<<(SIGPIPE-1));
55 return written?written:-1;
56 }
57 sleep_on(& PIPE_WRITE_WAIT(*inode));
58 }
// ����ִ�е������ʾ�ܵ����������п�д�ռ�size����������ȡ�ܵ�ͷָ�뵽������ĩ�˿�
// ���ֽ���chars��д�ܵ������Ǵӹܵ�ͷָ�봦��ʼд�ġ����chars���ڻ���Ҫд����ֽ�
// ��count����������� count�� ��� chars���ڵ�ǰ�ܵ��п��пռ䳤��size�����������
// size��Ȼ�����Ҫд���ֽ���count��ȥ�˴ο�д����ֽ���chars������д���ֽ����ۼӵ�
// written�С�
59 chars = PAGE_SIZE-PIPE_HEAD(*inode);
60 if (chars > count)
61 chars = count;
62 if (chars > size)
63 chars = size;
64 count -= chars;
65 written += chars;
// ����sizeָ��ܵ�����ͷָ�봦����������ǰ�ܵ�����ͷ��ָ�루ǰ��chars�ֽڣ�����ͷ
// ָ�볬���ܵ�ĩ�����ƻء�Ȼ����û�����������chars���ֽڵ��ܵ�ͷָ�뿪ʼ���� ����
// �ܵ�i�ڵ㣬��i_size�ֶ����ǹܵ������ָ�롣
66 size = PIPE_HEAD(*inode);
67 PIPE_HEAD(*inode) += chars;
68 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
69 while (chars-->0)
70 ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
71 }
// ���˴�д�ܵ��������������ѵȴ��ܵ��Ľ��̣�������д����ֽ������˳���
72 wake_up(& PIPE_READ_WAIT(*inode));
73 return written;
74 }
75
//// �����ܵ�ϵͳ���á�
// ��fildes��ָ�������д���һ���ļ��������������������ļ����ָ��һ�ܵ�i�ڵ㡣
// ������filedes -�ļ�������顣fildes[0]���ڶ��ܵ����ݣ�fildes[1]��ܵ�д�����ݡ�
// �ɹ�ʱ����0������ʱ����-1��
76 int sys_pipe(unsigned long * fildes)
77 {
78 struct m_inode * inode;
79 struct file * f[2]; // �ļ��ṹ���顣
80 int fd[2]; // �ļ�������顣
81 int i,j;
82
// ���ȴ�ϵͳ�ļ�����ȡ������������ü����ֶ�Ϊ0��������ֱ��������ü���Ϊ1��
// ��ֻ��1����������ͷŸ�����ü�����λ������û���ҵ������������ -1��
83 j=0;
84 for(i=0;j<2 && i<NR_FILE;i++)
85 if (!file_table[i].f_count)
86 (f[j++]=i+file_table)->f_count++;
87 if (j==1)
88 f[0]->f_count=0;
89 if (j<2)
90 return -1;
// �������ȡ�õ������ļ����ṹ��ֱ����һ�ļ�����ţ���ʹ�����ļ��ṹָ�������
// ����ֱ�ָ���������ļ��ṹ�����ļ�������Ǹ�����������š����Ƶأ����ֻ��һ����
// ���ļ���������ͷŸþ�����ÿ���Ӧ����������û���ҵ��������о�������ͷ�����
// ��ȡ�������ļ��ṹ���λ���ü���ֵ���������� -1��
91 j=0;
92 for(i=0;j<2 && i<NR_OPEN;i++)
93 if (!current->filp[i]) {
94 current->filp[ fd[j]=i ] = f[j];
95 j++;
96 }
97 if (j==1)
98 current->filp[fd[0]]=NULL;
99 if (j<2) {
100 f[0]->f_count=f[1]->f_count=0;
101 return -1;
102 }
// Ȼ�����ú���get_pipe_inode()����һ���ܵ�ʹ�õ�i�ڵ㣬��Ϊ�ܵ�����һҳ�ڴ���Ϊ��
// ������������ɹ�������Ӧ�ͷ������ļ�������ļ��ṹ�������-1��
103 if (!(inode=get_pipe_inode())) { // fs/inode.c����231�п�ʼ����
104 current->filp[fd[0]] =
105 current->filp[fd[1]] = NULL;
106 f[0]->f_count = f[1]->f_count = 0;
107 return -1;
108 }
// ����ܵ�i�ڵ�����ɹ�����������ļ��ṹ���г�ʼ�������������Ƕ�ָ��ͬһ���ܵ�i��
// �㣬���Ѷ�дָ�붼���㡣��1���ļ��ṹ���ļ�ģʽ��Ϊ������2���ļ��ṹ���ļ�ģʽ��
// Ϊд������ļ�������鸴�Ƶ���Ӧ���û��ռ������У��ɹ�����0���˳���
109 f[0]->f_inode = f[1]->f_inode = inode;
110 f[0]->f_pos = f[1]->f_pos = 0;
111 f[0]->f_mode = 1; /* read */
112 f[1]->f_mode = 2; /* write */
113 put_fs_long(fd[0],0+fildes);
114 put_fs_long(fd[1],1+fildes);
115 return 0;
116 }
117
//// �ܵ�io���ƺ�����
// ������pino - �ܵ�i�ڵ�ָ�룻cmd - �������arg - ������
// ��������0��ʾִ�гɹ������س����롣
118 int pipe_ioctl(struct m_inode *pino, int cmd, int arg)
119 {
// ���������ȡ�ܵ��е�ǰ�ɶ����ݳ��ȣ���ѹܵ����ݳ���ֵ�����û�����ָ����λ�ô���
// ������0��������Ч��������롣
120 switch (cmd) {
121 case FIONREAD:
122 verify_area((void *) arg,4);
123 put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
124 return 0;
125 default:
126 return -EINVAL;
127 }
128 }
129