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