����12-10 linux/fs/pipe.c


  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