����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