����8-9 linux/kernel/sys.c����
1 /*
2 * linux/kernel/sys.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 #include <errno.h> // �����ͷ�ļ�������ϵͳ�и��ֳ����š�
8
9 #include <linux/sched.h> // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�
// ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣
10 #include <linux/tty.h> // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������
11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣
12 #include <linux/config.h> // �ں˳��������ļ���������Ҫʹ�����е�ϵͳ���Ƴ���������Ϣ��
13 #include <asm/segment.h> // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����
14 #include <sys/times.h> // �����˽���������ʱ��Ľṹtms�Լ�times()����ԭ�͡�
15 #include <sys/utsname.h> // ϵͳ���ƽṹͷ�ļ���
16 #include <sys/param.h> // ϵͳ����ͷ�ļ�������ϵͳһЩȫ�ֳ������š�����HZ�ȡ�
17 #include <sys/resource.h> // ϵͳ��Դͷ�ļ��������йؽ�����Դʹ������Ľṹ����Ϣ��
18 #include <string.h> // �ַ���ͷ�ļ����ַ������ڴ��ֽ����в���������
19
20 /*
21 * The timezone where the local system is located. Used as a default by some
22 * programs who obtain this value by using gettimeofday.
23 */
/*
* ��ϵͳ���ڵ�ʱ����timezone������ΪijЩ����ʹ��gettimeofdayϵͳ���û�ȡ
* ʱ����Ĭ��ֵ��
*/
// ʱ���ṹtimezone��1���ֶΣ�tz_minuteswest����ʾ��������α�ʱ��GMT�����ķ���
// ������2���ֶΣ�tz_dsttime��������ʱDST��Daylight Savings Time���������͡� �ýṹ
// ������include/sys/time.h��
24 struct timezone sys_tz = { 0, 0};
25
// ���ݽ������pgrpȡ�ý����������Ự��session���š��ú�����kernel/exit.c��ʵ�֡�
26 extern int session_of_pgrp(int pgrp);
27
// �������ں�ʱ�䣨ftime �C Fetch time����
// ���·���ֵ��-ENOSYS��ϵͳ���ú�������ʾ�ڱ��汾�ں��л�δʵ�֡�
28 int sys_ftime()
29 {
30 return -ENOSYS;
31 }
32
33 int sys_break()
34 {
35 return -ENOSYS;
36 }
37
// ���ڵ�ǰ���̶��ӽ��̽��е���(debugging)��
38 int sys_ptrace()
39 {
40 return -ENOSYS;
41 }
42
// �ı䲢��ӡ�ն������á�
43 int sys_stty()
44 {
45 return -ENOSYS;
46 }
47
// ȡ�ն���������Ϣ��
48 int sys_gtty()
49 {
50 return -ENOSYS;
51 }
52
// �������
53 int sys_rename()
54 {
55 return -ENOSYS;
56 }
57
58 int sys_prof()
59 {
60 return -ENOSYS;
61 }
62
63 /*
64 * This is done BSD-style, with no consideration of the saved gid, except
65 * that if you set the effective gid, it sets the saved gid too. This
66 * makes it possible for a setgid program to completely drop its privileges,
67 * which is often a useful assertion to make when you are doing a security
68 * audit over a program.
69 *
70 * The general idea is that a program which uses just setregid() will be
71 * 100% compatible with BSD. A program which uses just setgid() will be
72 * 100% compatible with POSIX w/ Saved ID's.
73 */
/*
* ������BSD��ʽ��ʵ�֣�û�п��DZ����gid��saved gid��sgid�������˵���
* ��������Ч��gid��effective gid��egid��ʱ�������gidҲ�ᱻ���á���ʹ
* ��һ��ʹ��setgid�ij��������ȫ��������Ȩ�������ڶ�һ��������а�ȫ��
* ��ʱ����ͨ����һ�ֺܺõĴ���������
*
* ������Ŀ�����һ��ʹ��setregid()�ij�����BSDϵͳ100%�ļ��ݡ���һ
* ��ʹ��setgid()�ͱ����gid�ij�����POSIX 100%�ļ��ݡ�
*/
// ���õ�ǰ�����ʵ���Լ�/������Ч��ID��gid�����������û�г����û���Ȩ����ôֻ�ܻ�
// ����ʵ����ID ����Ч�� ID�����������г����û���Ȩ����������������Ч�ĺ�ʵ�ʵ���
// ID��������gid��saved gid�������ó�����Чgid��ʵ����ID��ָ���̵�ǰ��gid��
74 int sys_setregid(int rgid, int egid)
75 {
76 if (rgid>0) {
77 if ((current->gid == rgid) ||
78 suser())
79 current->gid = rgid;
80 else
81 return(-EPERM);
82 }
83 if (egid>0) {
84 if ((current->gid == egid) ||
85 (current->egid == egid) ||
86 suser()) {
87 current->egid = egid;
88 current->sgid = egid;
89 } else
90 return(-EPERM);
91 }
92 return 0;
93 }
94
95 /*
96 * setgid() is implemeneted like SysV w/ SAVED_IDS
97 */
/*
* setgid()��ʵ�������SAVED_IDS��SYSV��ʵ�ַ������ơ�
*/
// ���ý������(gid)���������û�г����û���Ȩ��������ʹ�� setgid() ������Чgid
// ��effective gid������Ϊ���䱣��gid(saved gid)����ʵ��gid(real gid)���������
// �г����û���Ȩ����ʵ��gid����Чgid�ͱ���gid�������óɲ���ָ����gid��
98 int sys_setgid(int gid)
99 {
100 if (suser())
101 current->gid = current->egid = current->sgid = gid;
102 else if ((gid == current->gid) || (gid == current->sgid))
103 current->egid = gid;
104 else
105 return -EPERM;
106 return 0;
107 }
108
// ��رս��̼��ʹ��ܡ�
109 int sys_acct()
110 {
111 return -ENOSYS;
112 }
113
// ӳ�����������ڴ浽���̵������ַ�ռ䡣
114 int sys_phys()
115 {
116 return -ENOSYS;
117 }
118
119 int sys_lock()
120 {
121 return -ENOSYS;
122 }
123
124 int sys_mpx()
125 {
126 return -ENOSYS;
127 }
128
129 int sys_ulimit()
130 {
131 return -ENOSYS;
132 }
133
// ���ش� 1970��1��1��00:00:00 GMT ��ʼ��ʱ��ʱ��ֵ���룩�����tloc��Ϊnull��
// ��ʱ��ֵҲ�洢�����
// ���ڲ�����һ��ָ�룬������ָλ�����û��ռ䣬�����Ҫʹ�ú��� put_fs_long() ��
// ���ʸ�ֵ���ڽ����ں�������ʱ���μĴ���fs��Ĭ�ϵ�ָ��ǰ�û����ݿռ䡣��˸�
// �����Ϳ�����fs�������û��ռ��е�ֵ��
134 int sys_time(long * tloc)
135 {
136 int i;
137
138 i = CURRENT_TIME;
139 if (tloc) {
140 verify_area(tloc,4); // ��֤�ڴ������Ƿ�������4�ֽڣ���
141 put_fs_long(i,(unsigned long *)tloc); // �����û����ݶ�tloc����
142 }
143 return i;
144 }
145
146 /*
147 * Unprivileged users may change the real user id to the effective uid
148 * or vice versa. (BSD-style)
149 *
150 * When you set the effective uid, it sets the saved uid too. This
151 * makes it possible for a setuid program to completely drop its privileges,
152 * which is often a useful assertion to make when you are doing a security
153 * audit over a program.
154 *
155 * The general idea is that a program which uses just setreuid() will be
156 * 100% compatible with BSD. A program which uses just setuid() will be
157 * 100% compatible with POSIX w/ Saved ID's.
158 */
/*
* ����Ȩ���û����Լ�ʵ�ʵ�uid��real uid���ij���Ч��uid��effective uid����
* ��֮ҲȻ����BSD��ʽ��ʵ�֣�
*
* ����������Ч��uid ʱ����ͬʱҲ�����˱���� uid����ʹ��һ��ʹ�� setuid
* �ij��������ȫ��������Ȩ�������ڶ�һ��������а�ȫ���ʱ����ͨ����һ��
* �ܺõĴ���������
* ������Ŀ�����һ��ʹ�� setreuid()�ij����� BSDϵͳ100%�ļ��ݡ���һ
* ��ʹ��setuid()�ͱ����gid�ij�����POSIX 100%�ļ��ݡ�
*/
// ���������ʵ���Լ�/������Ч���û�ID��uid�����������û�г����û���Ȩ����ôֻ��
// ������ʵ�ʵ�uid ����Ч��uid�����������г����û���Ȩ����������������Ч�ĺ�ʵ
// �ʵ��û�ID�������uid��saved uid�������ó�����Чuidֵͬ��
159 int sys_setreuid(int ruid, int euid)
160 {
161 int old_ruid = current->uid;
162
163 if (ruid>0) {
164 if ((current->euid==ruid) ||
165 (old_ruid == ruid) ||
166 suser())
167 current->uid = ruid;
168 else
169 return(-EPERM);
170 }
171 if (euid>0) {
172 if ((old_ruid == euid) ||
173 (current->euid == euid) ||
174 suser()) {
175 current->euid = euid;
176 current->suid = euid;
177 } else {
178 current->uid = old_ruid;
179 return(-EPERM);
180 }
181 }
182 return 0;
183 }
184
185 /*
186 * setuid() is implemeneted like SysV w/ SAVED_IDS
187 *
188 * Note that SAVED_ID's is deficient in that a setuid root program
189 * like sendmail, for example, cannot set its uid to be a normal
190 * user and then switch back, because if you're root, setuid() sets
191 * the saved uid too. If you don't like this, blame the bright people
192 * in the POSIX commmittee and/or USG. Note that the BSD-style setreuid()
193 * will allow a root program to temporarily drop privileges and be able to
194 * regain them by swapping the real and effective uid.
195 */
/*
* setuid()��ʵ�������SAVED_IDS��SYSV��ʵ�ַ������ơ�
*
* ��ע��ʹ��SAVED_ID��setuid()��ijЩ�����Dz����Ƶġ����磬һ��ʹ��
* setuid�ij����û�����sendmail������������uid���ó�һ����ͨ�û���
* uid��Ȼ���ٽ��������� ��Ϊ�������һ�������û���setuid() Ҳͬʱ��
* ���ñ����uid������㲻ϲ�������������Ļ��������POSIX��ί���Լ�
* /����USG�еĴ����˰ɡ�������ע��BSD��ʽ��setreuid()ʵ���ܹ�����
* һ�������û�������ʱ������Ȩ��������ͨ������ʵ�ʵĺ���Ч�� uid ��
* �ٴλ����Ȩ��
*/
// ���������û�ID��uid�����������û�г����û���Ȩ��������ʹ��setuid()������Ч��
// uid��effective uid�����ó��䱣���uid��saved uid������ʵ�ʵ�uid��real uid����
// ��������г����û���Ȩ����ʵ�ʵ�uid����Ч��uid�ͱ����uid���ᱻ���óɲ���ָ
// ����uid��
196 int sys_setuid(int uid)
197 {
198 if (suser())
199 current->uid = current->euid = current->suid = uid;
200 else if ((uid == current->uid) || (uid == current->suid))
201 current->euid = uid;
202 else
203 return -EPERM;
204 return(0);
205 }
206
// ����ϵͳ����ʱ�䡣����tptr�Ǵ�1970��1��1��00:00:00 GMT��ʼ��ʱ��ʱ��ֵ���룩��
// ���ý��̱�����г����û�Ȩ�ޡ�����HZ=100�����ں�ϵͳ����Ƶ�ʡ�
// ���ڲ�����һ��ָ�룬������ָλ�����û��ռ䣬�����Ҫʹ�ú���get_fs_long()�����ʸ�
// ֵ���ڽ����ں�������ʱ���μĴ��� fs ��Ĭ�ϵ�ָ��ǰ�û����ݿռ䡣��˸ú����Ϳ���
// ��fs�������û��ռ��е�ֵ��
// ���������ṩ�ĵ�ǰʱ��ֵ��ȥϵͳ�Ѿ����е�ʱ����ֵ��jiffies/HZ�����ǿ���ʱ����ֵ��
207 int sys_stime(long * tptr)
208 {
209 if (!suser()) // ������dz����û���������أ����ɣ���
210 return -EPERM;
211 startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;
212 jiffies_offset = 0;
213 return 0;
214 }
215
// ��ȡ��ǰ��������ʱ��ͳ��ֵ��
// ��tbuf��ָ�û����ݿռ䴦����tms�ṹ����������ʱ��ͳ��ֵ��tms�ṹ�а��������û�
// ����ʱ�䡢�ںˣ�ϵͳ��ʱ�䡢�ӽ����û�����ʱ�䡢�ӽ���ϵͳ����ʱ�䡣��������ֵ��
// ϵͳ���е���ǰ���������
216 int sys_times(struct tms * tbuf)
217 {
218 if (tbuf) {
219 verify_area(tbuf,sizeof *tbuf);
220 put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);
221 put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);
222 put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);
223 put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);
224 }
225 return jiffies;
226 }
227
// ������end_data_seg��ֵ����������ϵͳȷʵ���㹻���ڴ棬���ҽ���û�г�Խ���������
// �δ�Сʱ���ú����������ݶ�ĩβΪend_data_segָ����ֵ����ֵ������ڴ����β����Ҫ
// С�ڶ�ջ��β16KB������ֵ�����ݶε��½�βֵ���������ֵ��Ҫ��ֵ��ͬ��������д���
// ���������ú����������û�ֱ�ӵ��ã�����libc�⺯�����а�װ�����ҷ���ֵҲ��һ����
228 int sys_brk(unsigned long end_data_seg)
229 {
// �������ֵ���ڴ����β������С�ڣ���ջ - 16KB���������������ݶν�βֵ��
230 if (end_data_seg >= current->end_code &&
231 end_data_seg < current->start_stack - 16384)
232 current->brk = end_data_seg;
233 return current->brk; // ���ؽ��̵�ǰ�����ݶν�βֵ��
234 }
235
236 /*
237 * This needs some heave checking ...
238 * I just haven't get the stomach for it. I also don't fully
239 * understand sessions/pgrp etc. Let somebody who does explain it.
240 *
241 * OK, I think I have the protection semantics right.... this is really
242 * only important on a multi-user system anyway, to make sure one user
243 * can't send a signal to a process owned by another. -TYT, 12/12/91
244 */
/*
* ���������ҪijЩ�ϸ�ļ����
* ��ֻ��û��θ��������Щ����Ҳ����ȫ����sessions/pgrp�ȵĺ��塣������
* �˽����ǵ��������ɡ�
*
* OK���������Ѿ���ȷ��ʵ���˱�������...����֮������ʵֻ�Զ��û�ϵͳ��
* ��Ҫ�ģ���ȷ��һ���û������������û��Ľ��̷����źš� -TYT 12/12/91
*/
// ����ָ������pid�Ľ������Ϊpgid��
// ����pid ��ָ�����̵Ľ��̺š������Ϊ0������pid���ڵ�ǰ���̵Ľ��̺š�����pgid
// ��ָ���Ľ�����š������Ϊ0�����������ڽ���pid�Ľ�����š�����ú������ڽ�����
// ��һ���������Ƶ���һ�������飬���������������������ͬһ���Ự(session)��������
// ����£�����pgid ָ����Ҫ��������н�����ID����ʱ����ĻỰID�����뽫Ҫ�����
// �̵���ͬ(263��)��
245 int sys_setpgid(int pid, int pgid)
246 {
247 int i;
248
// �������pidΪ0����pidȡֵΪ��ǰ���̵Ľ��̺�pid���������pgidΪ0����pgidҲ
// ȡֵΪ��ǰ���̵�pid��[?? ������POSIX���������г��� ]���� pgidС��0����
// ��Ч�����롣
249 if (!pid)
250 pid = current->pid;
251 if (!pgid)
252 pgid = current->pid;
253 if (pgid < 0)
254 return -EINVAL;
// ɨ���������飬����ָ�����̺� pid ����������ҵ��˽��̺���pid �Ľ��̣����Ҹý���
// �ĸ����̾��ǵ�ǰ���̻��߸ý��̾��ǵ�ǰ���̣���ô���������Ѿ��ǻỰ���죬��������ء�
// ��������ĻỰ�ţ�session���뵱ǰ���̵IJ�ͬ������ָ���Ľ������pgid��pid��ͬ����
// pgid �����������Ự���뵱ǰ���������Ự�Ų�ͬ����Ҳ�������ء� ����Ѳ��ҵ��Ľ��̵�
// pgrp����Ϊpgid��������0����û���ҵ�ָ��pid�Ľ��̣��ؽ��̲����ڳ����롣
255 for (i=0 ; i<NR_TASKS ; i++)
256 if (task[i] && (task[i]->pid == pid) &&
257 ((task[i]->p_pptr == current) ||
258 (task[i] == current))) {
259 if (task[i]->leader)
260 return -EPERM;
261 if ((task[i]->session != current->session) ||
262 ((pgid != pid) &&
263 (session_of_pgrp(pgid) != current->session)))
264 return -EPERM;
265 task[i]->pgrp = pgid;
266 return 0;
267 }
268 return -ESRCH;
269 }
270
// ���ص�ǰ���̵Ľ�����š���getpgid(0)��ͬ��
271 int sys_getpgrp(void)
272 {
273 return current->pgrp;
274 }
275
// ����һ���Ự(session)����������leader=1��������������Ự��=�����=����̺š�
// �����ǰ�������ǻỰ���첢�Ҳ��dz����û�����������ء��������õ�ǰ����Ϊ�»Ự
// ���죨leader = 1�����������õ�ǰ���̻Ự�� session�����pgrp�����ڽ��̺�pid��
// �������õ�ǰ����û�п����նˡ����ϵͳ���÷��ػỰ�š�
276 int sys_setsid(void)
277 {
278 if (current->leader && !suser())
279 return -EPERM;
280 current->leader = 1;
281 current->session = current->pgrp = current->pid;
282 current->tty = -1; // ��ʾ��ǰ����û�п����նˡ�
283 return current->pgrp;
284 }
285
286 /*
287 * Supplementary group ID's
288 */
/*
* ���̵������û���š�
*/
// ȡ��ǰ�������������û���š�
// �������ݽṹ��groups[]���鱣���Ž���ͬʱ�����Ķ���û���š������鹲NGROUPS���
// ��ij���ֵ��NOGROUP����Ϊ -1�������ʾ�Ӹ��ʼ�Ժ���������С������������б�
// ������û���š�
// ����gidsetsize�ǻ�ȡ���û���Ÿ�����grouplist�Ǵ洢��Щ�û���ŵ��û��ռ仺�档
289 int sys_getgroups(int gidsetsize, gid_t *grouplist)
290 {
291 int i;
292
// ������֤grouplistָ����ָ���û�����ռ��Ƿ��㹻��Ȼ��ӵ�ǰ���̽ṹ��groups[]
// ���������ȡ���û���Ų����Ƶ��û������С��ڸ��ƹ����У���� groups[] �е�����
// ���ڸ����IJ��� gidsetsize ��ָ���ĸ��������ʾ�û������Ļ���̫С���������µ�ǰ
// ����������ţ���˴˴�ȡ��Ų�����������ء������ƹ����������������᷵�ظ�
// �Ƶ��û���Ÿ�������gidsetsize �C gid set size���û���ż���С����
293 if (gidsetsize)
294 verify_area(grouplist, sizeof(gid_t) * gidsetsize);
295
296 for (i = 0; (i < NGROUPS) && (current->groups[i] != NOGROUP);
297 i++, grouplist++) {
298 if (gidsetsize) {
299 if (i >= gidsetsize)
300 return -EINVAL;
301 put_fs_word(current->groups[i], (short *) grouplist);
302 }
303 }
304 return(i); // ����ʵ�ʺ��е��û���Ÿ�����
305 }
306
// ���õ�ǰ����ͬʱ���������������û���š�
// ����gidsetsize�ǽ����õ��û���Ÿ�����grouplist�Ǻ����û���ŵ��û��ռ仺�档
307 int sys_setgroups(int gidsetsize, gid_t *grouplist)
308 {
309 int i;
310
// ���Ȳ�Ȩ�Ͳ�������Ч�ԡ�ֻ�г����û������Ļ����õ�ǰ���̵ĸ����û���ţ�����
// ���õ��������ܳ������̵�groups[NGROUPS]�����������Ȼ����û���������������û�
// ��ţ���gidsetsize����������Ƶĸ���û������groups[]���������һ��������ֵΪ-1
// ���NOGROUP�������������0��
311 if (!suser())
312 return -EPERM;
313 if (gidsetsize > NGROUPS)
314 return -EINVAL;
315 for (i = 0; i < gidsetsize; i++, grouplist++) {
316 current->groups[i] = get_fs_word((unsigned short *) grouplist);
317 }
318 if (i < NGROUPS)
319 current->groups[i] = NOGROUP;
320 return 0;
321 }
322
// ��鵱ǰ�����Ƿ���ָ�����û���grp�С�����1������0��
323 int in_group_p(gid_t grp)
324 {
325 int i;
326
// �����ǰ���̵���Ч��ž���grp�����ʾ��������grp�����顣��������1���������
// ���̵ĸ����û���������ɨ���Ƿ��� grp ������š���������Ҳ����1����ɨ�赽ֵ
// Ϊ NOGROUP �����ʾ��ɨ����ȫ����Ч���û�з���ƥ�����ţ���˺�������0��
327 if (grp == current->egid)
328 return 1;
329
330 for (i = 0; i < NGROUPS; i++) {
331 if (current->groups[i] == NOGROUP)
332 break;
333 if (current->groups[i] == grp)
334 return 1;
335 }
336 return 0;
337 }
338
// utsname�ṹ����һЩ�ַ����ֶΡ����ڱ���ϵͳ�����ơ����а���5���ֶΣ��ֱ��ǣ�
// ��ǰ����ϵͳ�����ơ�����ڵ����ƣ�������������ǰ����ϵͳ���м��𡢲���ϵͳ�汾
// ���Լ�ϵͳ���е�Ӳ���������ơ��ýṹ������ include/sys/utsname.h �ļ��С� ����
// �ں�ʹ�� include/linux/config.h �ļ��еij����������������ǵ�Ĭ��ֵ�����Ƿֱ�Ϊ
// ��Linux������(none)������0������0.12������i386����
339 static struct utsname thisname = {
340 UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_MACHINE
341 };
342
// ��ȡϵͳ���Ƶ���Ϣ��
343 int sys_uname(struct utsname * name)
344 {
345 int i;
346
347 if (!name) return -ERROR;
348 verify_area(name,sizeof *name);
349 for(i=0;i<sizeof *name;i++)
350 put_fs_byte(((char *) &thisname)[i],i+(char *) name);
351 return 0;
352 }
353
354 /*
355 * Only sethostname; gethostname can be implemented by calling uname()
356 */
/*
* ͨ������uname()ֻ��ʵ��sethostname��gethostname��
*/
// ����ϵͳ��������ϵͳ������ڵ�������
// ����nameָ��ָ���û��������к����������ַ����Ļ�������len���������ַ������ȡ�
357 int sys_sethostname(char *name, int len)
358 {
359 int i;
360
// ϵͳ������ֻ���ɳ����û����û��ģ��������������Ȳ��ܳ������MAXHOSTNAMELEN��
361 if (!suser())
362 return -EPERM;
363 if (len > MAXHOSTNAMELEN)
364 return -EINVAL;
365 for (i=0; i < len; i++) {
366 if ((thisname.nodename[i] = get_fs_byte(name+i)) == 0)
367 break;
368 }
// �ڸ�����Ϻ�����û��ṩ���ַ�����û�а���NULL�ַ�����ô�����Ƶ����������Ȼ�û��
// ���� MAXHOSTNAMELEN�������������ַ���������һ��NULL�����Ѿ����� MAXHOSTNAMELEN����
// ����������һ���ַ��ij�NULL�ַ�����thisname.nodename[min(i,MAXHOSTNAMELEN)] = 0��
369 if (thisname.nodename[i]) {
370 thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0;
371 }
372 return 0;
373 }
374
// ȡ��ǰ����ָ����Դ�Ľ���ֵ��
// ���̵�����ṹ�ж�����һ������rlim[RLIM_NLIMITS]�����ڿ��ƽ���ʹ��ϵͳ��Դ�Ľ��ޡ�
// ����ÿ������һ��rlimit �ṹ�����а��������ֶΡ� һ��˵�����̶�ָ����Դ�ĵ�ǰ����
// ���ޣ�soft limit���������ƣ�����һ��˵��ϵͳ��ָ����Դ��������ƽ��ޣ�hard limit��
// ��Ӳ���ƣ��� rlim[] �����ÿһ���Ӧϵͳ�Ե�ǰ����һ����Դ�Ľ�����Ϣ��Linux 0.12
// ϵͳ����6����Դ�涨�˽��ޣ���RLIM_NLIMITS=6����ο�ͷ�ļ�include/sys/resource.h
// �е�41 �� 46�е�˵����
// ���� resource ָ��������ѯ����Դ���ƣ�ʵ������������ṹ��rlim[]�����������ֵ��
// ����rlim��ָ��rlimit�ṹ���û�������ָ�룬���ڴ��ȡ�õ���Դ������Ϣ��
375 int sys_getrlimit(int resource, struct rlimit *rlim)
376 {
// ����ѯ����Դresourceʵ�����ǽ�������ṹ��rlim[]�����������ֵ��������ֵ��Ȼ����
// ���������������� RLIM_NLIMITS������֤�� rlim ָ����ָ�û������㹻�Ժ�����Ͱ�
// ����ָ������Դresource�ṹ��Ϣ���Ƶ��û������У�������0��
377 if (resource >= RLIM_NLIMITS)
378 return -EINVAL;
379 verify_area(rlim,sizeof *rlim);
380 put_fs_long(current->rlim[resource].rlim_cur, // ��ǰ����������ֵ��
381 (unsigned long *) rlim);
382 put_fs_long(current->rlim[resource].rlim_max, // ϵͳ��Ӳ������ֵ��
383 ((unsigned long *) rlim)+1);
384 return 0;
385 }
386
// ���õ�ǰ����ָ����Դ�Ľ���ֵ��
// ���� resource ָ���������ý�����Դ���ƣ�ʵ������������ṹ��rlim[]���������
// ��ֵ������rlim��ָ��rlimit�ṹ���û�������ָ�룬�����ں˶�ȡ�µ���Դ������Ϣ��
387 int sys_setrlimit(int resource, struct rlimit *rlim)
388 {
389 struct rlimit new, *old;
390
// �����жϲ���resource������ṹrlim[]������ֵ����Ч�ԡ�Ȼ������rlimit�ṹָ��
// oldָ��ָ��������ṹ��ָ����Դ�ĵ�ǰrlimit�ṹ��Ϣ�����Ű��û��ṩ����Դ����
// ��Ϣ���Ƶ���ʱrlimit�ṹnew�С���ʱ����жϳ�new�ṹ�е�������ֵ��Ӳ����ֵ
// ���ڽ��̸���ԴԭӲ����ֵ�����ҵ�ǰ���dz����û��Ļ����ͷ������ɴ��������ʾnew
// ����Ϣ�������߽����dz����û����̣�����ԭ����ָ����Դ��Ϣ����new�ṹ�е���Ϣ��
// ���ɹ�����0��
391 if (resource >= RLIM_NLIMITS)
392 return -EINVAL;
393 old = current->rlim + resource; // ��old = current->rlim[resource]��
394 new.rlim_cur = get_fs_long((unsigned long *) rlim);
395 new.rlim_max = get_fs_long(((unsigned long *) rlim)+1);
396 if (((new.rlim_cur > old->rlim_max) ||
397 (new.rlim_max > old->rlim_max)) &&
398 !suser())
399 return -EPERM;
400 *old = new;
401 return 0;
402 }
403
404 /*
405 * It would make sense to put struct rusuage in the task_struct,
406 * except that would make the task_struct be *really big*. After
407 * task_struct gets moved into malloc'ed memory, it would
408 * make sense to do this. It will make moving the rest of the information
409 * a lot simpler! (Which we're not doing right now because we're not
410 * measuring them yet).
411 */
/*
* ��rusuage�ṹ�Ž�����ṹtask struct����ǡ���ģ���������ʹ����
* �ṹ���ȱ�÷dz����ڰ�����ṹ�����ں�malloc������ڴ���֮��
* ��������ʹ����ṹ�ܴ�Ҳû�����ˡ��⽫ʹ��������Ϣ���ƶ���÷dz�
* ���㣡�����ǻ�û������������Ϊ���ǻ�û�в��Թ����ǵĴ�С����
*/
// ��ȡָ�����̵���Դ������Ϣ��
// ��ϵͳ�����ṩ��ǰ���̻�������ֹ�ĺ͵ȴ��ŵ��ӽ�����Դʹ��������������who����
// RUSAGE_SELF���ص�ǰ���̵���Դ������Ϣ�����ָ������who �� RUSAGE_CHILDREN��
// �ص�ǰ���̵�����ֹ�͵ȴ��ŵ��ӽ�����Դ������Ϣ�� ���ų���RUSAGE_SELF ��
// RUSAGE_CHILDREN �Լ� rusage�ṹ�������� include/sys/resource.hͷ�ļ��С�
412 int sys_getrusage(int who, struct rusage *ru)
413 {
414 struct rusage r;
415 unsigned long *lp, *lpend, *dest;
416
// �����жϲ���ָ�����̵���Ч�ԡ����who�Ȳ���RUSAGE_SELF��ָ����ǰ���̣���Ҳ����
// RUSAGE_CHILDREN ��ָ���ӽ��̣���������Ч�����뷵�ء���������֤��ָ��ru ָ������
// �������������ʱ rusage�ṹ����r���㡣
417 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
418 return -EINVAL;
419 verify_area(ru, sizeof *ru);
420 memset((char *) &r, 0, sizeof(r)); // ��include/strings.h����
// ������who ��RUSAGE_SELF�����Ƶ�ǰ������Դ������Ϣ��r�ṹ�С���ָ������who
// ��RUSAGE_CHILDREN�� ���Ƶ�ǰ���̵�����ֹ�͵ȴ��ŵ��ӽ�����Դ������Ϣ����ʱ
// rusuage�ṹr�С���CT_TO_SECS ��CT_TO_USECS���ڰ�ϵͳ��ǰ�����ת��������ֵ
// ����ֵ��ʾ�����Ƕ����� include/linux/sched.h �ļ��С� jiffies_offset��ϵͳ
// ���������������
421 if (who == RUSAGE_SELF) {
422 r.ru_utime.tv_sec = CT_TO_SECS(current->utime);
423 r.ru_utime.tv_usec = CT_TO_USECS(current->utime);
424 r.ru_stime.tv_sec = CT_TO_SECS(current->stime);
425 r.ru_stime.tv_usec = CT_TO_USECS(current->stime);
426 } else {
427 r.ru_utime.tv_sec = CT_TO_SECS(current->cutime);
428 r.ru_utime.tv_usec = CT_TO_USECS(current->cutime);
429 r.ru_stime.tv_sec = CT_TO_SECS(current->cstime);
430 r.ru_stime.tv_usec = CT_TO_USECS(current->cstime);
431 }
// Ȼ����lpָ��ָ��r�ṹ��lpendָ��r�ṹĩβ������destָ��ָ���û��ռ��е�ru
// �ṹ������r����Ϣ���Ƶ��û��ռ�ru�ṹ�У�������0��
432 lp = (unsigned long *) &r;
433 lpend = (unsigned long *) (&r+1);
434 dest = (unsigned long *) ru;
435 for (; lp < lpend; lp++, dest++)
436 put_fs_long(*lp, dest);
437 return(0);
438 }
439
// ȡ��ϵͳ��ǰʱ�䣬����ָ����ʽ���ء�
// timeval�ṹ��timezone�ṹ��������include/sys/time.h�ļ��С�timeval�ṹ������
// ���루tv_sec��tv_usec�������ֶΡ�timezone�ṹ���б��ؾ�������α�ʱ������
// �ķ�������tz_minuteswest��������ʱ��������ͣ�tz_dsttime�������ֶΡ�
// ��dst -- Daylight Savings Time��
440 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
441 {
// �������������timeval�ṹָ�벻�գ����ڸýṹ�з��ص�ǰʱ�䣨��ֵ����ֵ����
// ��������������û����ݿռ��� timezone�ṹ��ָ�벻�գ���Ҳ���ظýṹ����Ϣ��
// ������startup_time��ϵͳ����ʱ�䣨��ֵ���� ��CT_TO_SECS��CT_TO_USECS����
// ��ϵͳ��ǰ�����ת��������ֵ����ֵ��ʾ�����Ƕ�����include/linux/sched.h
// �ļ��С�jiffies_offset��ϵͳ���������������
442 if (tv) {
443 verify_area(tv, sizeof *tv);
444 put_fs_long(startup_time + CT_TO_SECS(jiffies+jiffies_offset),
445 (unsigned long *) tv);
446 put_fs_long(CT_TO_USECS(jiffies+jiffies_offset),
447 ((unsigned long *) tv)+1);
448 }
449 if (tz) {
450 verify_area(tz, sizeof *tz);
451 put_fs_long(sys_tz.tz_minuteswest, (unsigned long *) tz);
452 put_fs_long(sys_tz.tz_dsttime, ((unsigned long *) tz)+1);
453 }
454 return 0;
455 }
456
457 /*
458 * The first time we set the timezone, we will warp the clock so that
459 * it is ticking GMT time instead of local time. Presumably,
460 * if someone is setting the timezone then we are running in an
461 * environment where the programs understand about timezones.
462 * This should be done at boot time in the /etc/rc script, as
463 * soon as possible, so that the clock can be set right. Otherwise,
464 * various programs will get confused when the clock gets warped.
465 */
/*
* �ڵ�1������ʱ����timezone��ʱ�����ǻ�ı�ʱ��ֵ����ϵͳʹ�ø���
* ���α�ʱ�䣨GMT�����У�����ʹ�ñ���ʱ�䡣 �Ʋ�����˵�����ij��
* ������ʱ��ʱ�䣬��ô���Ǿ������ڳ���֪��ʱ��ʱ��Ļ����С�����ʱ
* ������Ӧ����ϵͳ�����Σ��������/etc/rc�ű������н��С�����ʱ
* �ӾͿ���������ȷ�� ����Ļ����������Ժ������ʱ��������ʱ��ʱ��
* �ı䣬���ܻ���һЩ��������г������⡣
*/
// ����ϵͳ��ǰʱ�䡣
// ����tv��ָ���û���������timeval�ṹ��Ϣ��ָ�롣����tz���û���������timezone
// �ṹ��ָ�롣�ò�����Ҫ�����û�Ȩ�ޡ�������߽�Ϊ�գ���ʲôҲ��������������0��
466 int sys_settimeofday(struct timeval *tv, struct timezone *tz)
467 {
468 static int firsttime = 1;
469 void adjust_clock();
470
// ����ϵͳ��ǰʱ����Ҫ�����û�Ȩ�ޡ����tzָ�벻�գ�������ϵͳʱ����Ϣ���������û�
// timezone�ṹ��Ϣ��ϵͳ�е� sys_tz�ṹ�У�����24�У�������ǵ�1�ε��ñ�ϵͳ����
// ���Ҳ���tvָ�벻�գ������ϵͳʱ��ֵ��
471 if (!suser())
472 return -EPERM;
473 if (tz) {
474 sys_tz.tz_minuteswest = get_fs_long((unsigned long *) tz);
475 sys_tz.tz_dsttime = get_fs_long(((unsigned long *) tz)+1);
476 if (firsttime) {
477 firsttime = 0;
478 if (!tv)
479 adjust_clock();
480 }
481 }
// ���������timeval�ṹָ��tv���գ����øýṹ��Ϣ����ϵͳʱ�ӡ����ȴ�tv��ָ��
// ��ȡ����ֵ��sec������ֵ��usec����ʾ��ϵͳʱ�䣬Ȼ������ֵ��ϵͳ����ʱ��ȫ��
// ����startup_timeֵ��������ֵ����ϵͳ������ֵjiffies_offset��
482 if (tv) {
483 int sec, usec;
484
485 sec = get_fs_long((unsigned long *)tv);
486 usec = get_fs_long(((unsigned long *)tv)+1);
487
488 startup_time = sec - jiffies/HZ;
489 jiffies_offset = usec * HZ / 1000000 - jiffies%HZ;
490 }
491 return 0;
492 }
493
494 /*
495 * Adjust the time obtained from the CMOS to be GMT time instead of
496 * local time.
497 *
498 * This is ugly, but preferable to the alternatives. Otherwise we
499 * would either need to write a program to do it in /etc/rc (and risk
500 * confusion if the program gets run more than once; it would also be
501 * hard to make the program warp the clock precisely n hours) or
502 * compile in the timezone information into the kernel. Bad, bad....
503 *
504 * XXX Currently does not adjust for daylight savings time. May not
505 * need to do anything, depending on how smart (dumb?) the BIOS
506 * is. Blast it all.... the best thing to do not depend on the CMOS
507 * clock at all, but get the time via NTP or timed if you're on a
508 * network.... - TYT, 1/1/92
509 */
/*
* �Ѵ�CMOS�ж�ȡ��ʱ��ֵ����ΪGMTʱ��ֵ���棬���DZ���ʱ��ֵ��
*
* ��������������ţ���Ҫ�����������á��������Ǿ���Ҫдһ����������
* ��/etc/rc��������������£�����ð�Ÿó�����ܻᱻ���ִ�ж�������
* ���⡣ ����������Ҳ�����ó����ʱ�Ӿ�ȷ�ص���nСʱ�� ���߰�ʱ����
* Ϣ������ں��С���Ȼ�������ͷdz����dz����...
*
* Ŀǰ���溯����XXX���ĵ���������û�п��ǵ�����ʱ���⡣����BIOS�ж�
* ô���ܣ�������Ҳ�������Ͳ��ÿ����ⷽ�档��Ȼ����õ���������ȫ��
* ������CMOSʱ�ӣ�������ϵͳͨ��NTP������ʱ��Э�飩����timed��ʱ��
* �����������ʱ�䣬��������������Ļ�...�� - TYT��1/1/92
*/
// ��ϵͳ����ʱ�����Ϊ��GMTΪ����ʱ�䡣
// startup_time����ֵ�����������Ҫ��ʱ������ֵ����60��
510 void adjust_clock()
511 {
512 startup_time += sys_tz.tz_minuteswest*60;
513 }
514
// ���õ�ǰ���̴����ļ�����������Ϊmask & 0777��������ԭ�����롣
515 int sys_umask(int mask)
516 {
517 int old = current->umask;
518
519 current->umask = mask & 0777;
520 return (old);
521 }
522