����12-16 linux/fs/fcntl.c


  1 /*

  2  *  linux/fs/fcntl.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 10 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 11 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 12

 13 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������š�

 14 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͳ�����

 15

 16 extern int sys_close(int fd);     // �ر��ļ�ϵͳ���á�(fs/open.c, 192)

 17

    //// �����ļ�������ļ�����������

    // ����fd�������Ƶ��ļ������argָ�����ļ��������С��ֵ��

    // �������ļ����������롣

 18 static int dupfd(unsigned int fd, unsigned int arg)

 19 {

    // ���ȼ�麯����������Ч�ԡ�����ļ����ֵ����һ�����������ļ���NR_OPEN������

    // �þ�����ļ��ṹ�����ڣ��򷵻س����벢�˳������ָ�����¾��ֵarg����������

    // ������Ҳ���س����벢�˳���ע�⣬ʵ�����ļ�������ǽ����ļ��ṹָ�������������š�

 20         if (fd >= NR_OPEN || !current->filp[fd])

 21                 return -EBADF;

 22         if (arg >= NR_OPEN)

 23                 return -EINVAL;

    // Ȼ���ڵ�ǰ���̵��ļ��ṹָ��������Ѱ�������ŵ��ڻ����arg������û��ʹ�õ����

    // �ҵ����¾��ֵarg���������ļ�������û�п�������򷵻س����벢�˳���

 24         while (arg < NR_OPEN)

 25                 if (current->filp[arg])

 26                         arg++;

 27                 else

 28                         break;

 29         if (arg >= NR_OPEN)

 30                 return -EMFILE;

    // ��������ҵ��Ŀ�������������ִ��ʱ�رձ�־λͼclose_on_exec�и�λ�þ��λ��

    // ��������exec()�ຯ��ʱ������ر���dup()�����ľ����������ļ��ṹָ�����ԭ��

    // ��fd��ָ�룬���ҽ��ļ����ü�����1����󷵻��µ��ļ����arg��

 31         current->close_on_exec &= ~(1<<arg);

 32         (current->filp[arg] = current->filp[fd])->f_count++;

 33         return arg;

 34 }

 35

    //// �����ļ����ϵͳ���á�

    // ����ָ���ļ����oldfd�����ļ����ֵ����newfd�����newfd�Ѵ򿪣������ȹر�֮��

    // ������oldfd -- ԭ�ļ������newfd - ���ļ������

    // �������ļ����ֵ��

 36 int sys_dup2(unsigned int oldfd, unsigned int newfd)

 37 {

 38         sys_close(newfd);             // �����newfd�Ѿ��򿪣������ȹر�֮��

 39         return dupfd(oldfd,newfd);    // ���Ʋ������¾����

 40 }

 41

    //// �����ļ����ϵͳ���á�

    // ����ָ���ļ����oldfd���¾����ֵ�ǵ�ǰ��С��δ�þ��ֵ��

    // ������fildes -- �����Ƶ��ļ������

    // �������ļ����ֵ��

 42 int sys_dup(unsigned int fildes)

 43 {

 44         return dupfd(fildes,0);

 45 }

 46

    //// �ļ�����ϵͳ���ú�����

    // ����fd���ļ������cmd�ǿ�������μ�include/fcntl.h��23-30�У���arg����Բ�

    // ͬ�������в�ͬ�ĺ��塣���ڸ��ƾ������F_DUPFD��arg�����ļ������ȡ����Сֵ����

    // �������ļ������ͷ��ʱ�־����F_SETFL��arg���µ��ļ������ͷ���ģʽ�������ļ�����

    // ����F_GETLK��F_SETLK��F_SETLKW��arg��ָ��flock�ṹ��ָ�롣�����ں���û��ʵ��

    // �ļ��������ܡ�

    // ���أ��������������в���������-1�����ɹ�����ôF_DUPFD �������ļ������ F_GETFD

    // �����ļ�����ĵ�ǰִ��ʱ�رձ�־close_on_exec��F_GETFL�����ļ������ͷ��ʱ�־��

 47 int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)

 48 {      

 49         struct file * filp;

 50

    // ���ȼ��������ļ��������Ч�ԡ�Ȼ����ݲ�ͬ����cmd ���зֱ����� ����ļ����

    // ֵ����һ�����������ļ���NR_OPEN�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س�����

    // ���˳���

 51         if (fd >= NR_OPEN || !(filp = current->filp[fd]))

 52                 return -EBADF;

 53         switch (cmd) {

 54                 case F_DUPFD:      // �����ļ������

 55                         return dupfd(fd,arg);

 56                 case F_GETFD:      // ȡ�ļ������ִ��ʱ�رձ�־��

 57                         return (current->close_on_exec>>fd)&1;

 58                 case F_SETFD:  // ����ִ��ʱ�رձ�־��argλ0��λ�����ã�����رա�

 59                         if (arg&1)

 60                                 current->close_on_exec |= (1<<fd);

 61                         else

 62                                 current->close_on_exec &= ~(1<<fd);

 63                         return 0;

 64                 case F_GETFL:      // ȡ�ļ�״̬��־�ͷ���ģʽ��

 65                         return filp->f_flags;

 66                 case F_SETFL: // �����ļ�״̬�ͷ���ģʽ������arg�������ӡ���������־����

 67                         filp->f_flags &= ~(O_APPEND | O_NONBLOCK);

 68                         filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);

 69                         return 0;

 70                 case F_GETLK:   case F_SETLK:   case F_SETLKW:    // δʵ�֡�

 71                         return -1;

 72                 default:

 73                         return -1;

 74         }

 75 }

 76