This source file includes following definitions.
- sys_ni_syscall
- proc_sel
- sys_setpriority
- sys_getpriority
- sys_profil
- sys_ftime
- sys_break
- sys_stty
- sys_gtty
- sys_prof
- sys_reboot
- ctrl_alt_del
- sys_setregid
- sys_setgid
- acct_process
- sys_acct
- sys_phys
- sys_lock
- sys_mpx
- sys_ulimit
- sys_old_syscall
- sys_setreuid
- sys_setuid
- sys_setfsuid
- sys_setfsgid
- sys_times
- sys_brk
- sys_setpgid
- sys_getpgid
- sys_getpgrp
- sys_getsid
- sys_setsid
- sys_getgroups
- sys_setgroups
- in_group_p
- sys_newuname
- sys_uname
- sys_olduname
- sys_sethostname
- sys_gethostname
- sys_setdomainname
- sys_getrlimit
- sys_setrlimit
- getrusage
- sys_getrusage
- sys_umask
1
2
3
4
5
6
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/times.h>
11 #include <linux/utsname.h>
12 #include <linux/param.h>
13 #include <linux/resource.h>
14 #include <linux/signal.h>
15 #include <linux/string.h>
16 #include <linux/ptrace.h>
17 #include <linux/stat.h>
18 #include <linux/mman.h>
19 #include <linux/mm.h>
20 #include <linux/pagemap.h>
21 #include <linux/swap.h>
22 #include <linux/fcntl.h>
23 #include <linux/acct.h>
24 #include <linux/tty.h>
25
26 #include <asm/segment.h>
27 #include <asm/io.h>
28
29
30
31
32 int C_A_D = 1;
33
34 extern void adjust_clock(void);
35
36 asmlinkage int sys_ni_syscall(void)
37 {
38 return -ENOSYS;
39 }
40
41 static int proc_sel(struct task_struct *p, int which, int who)
42 {
43 if(p->pid)
44 {
45 switch (which) {
46 case PRIO_PROCESS:
47 if (!who && p == current)
48 return 1;
49 return(p->pid == who);
50 case PRIO_PGRP:
51 if (!who)
52 who = current->pgrp;
53 return(p->pgrp == who);
54 case PRIO_USER:
55 if (!who)
56 who = current->uid;
57 return(p->uid == who);
58 }
59 }
60 return 0;
61 }
62
63 asmlinkage int sys_setpriority(int which, int who, int niceval)
64 {
65 struct task_struct *p;
66 int error = ESRCH;
67 unsigned int priority;
68
69 if (which > 2 || which < 0)
70 return -EINVAL;
71
72
73 priority = niceval;
74 if (niceval < 0)
75 priority = -niceval;
76 if (priority > 20)
77 priority = 20;
78 priority = (priority * DEF_PRIORITY + 10) / 20 + DEF_PRIORITY;
79
80 if (niceval >= 0) {
81 priority = 2*DEF_PRIORITY - priority;
82 if (!priority)
83 priority = 1;
84 }
85
86 for_each_task(p) {
87 if (!proc_sel(p, which, who))
88 continue;
89 if (p->uid != current->euid &&
90 p->uid != current->uid && !suser()) {
91 error = EPERM;
92 continue;
93 }
94 if (error == ESRCH)
95 error = 0;
96 if (priority > p->priority && !suser())
97 error = EACCES;
98 else
99 p->priority = priority;
100 }
101 return -error;
102 }
103
104
105
106
107
108
109 asmlinkage int sys_getpriority(int which, int who)
110 {
111 struct task_struct *p;
112 long max_prio = -ESRCH;
113
114 if (which > 2 || which < 0)
115 return -EINVAL;
116
117 for_each_task (p) {
118 if (!proc_sel(p, which, who))
119 continue;
120 if (p->priority > max_prio)
121 max_prio = p->priority;
122 }
123
124
125 if (max_prio > 0)
126 max_prio = (max_prio * 20 + DEF_PRIORITY/2) / DEF_PRIORITY;
127 return max_prio;
128 }
129
130 #ifndef __alpha__
131
132
133
134
135
136
137
138 asmlinkage int sys_profil(void)
139 {
140 return -ENOSYS;
141 }
142
143 asmlinkage int sys_ftime(void)
144 {
145 return -ENOSYS;
146 }
147
148 asmlinkage int sys_break(void)
149 {
150 return -ENOSYS;
151 }
152
153 asmlinkage int sys_stty(void)
154 {
155 return -ENOSYS;
156 }
157
158 asmlinkage int sys_gtty(void)
159 {
160 return -ENOSYS;
161 }
162
163 asmlinkage int sys_prof(void)
164 {
165 return -ENOSYS;
166 }
167
168 #endif
169
170 extern void hard_reset_now(void);
171 extern asmlinkage sys_kill(int, int);
172
173
174
175
176
177
178
179
180
181 asmlinkage int sys_reboot(int magic, int magic_too, int flag)
182 {
183 if (!suser())
184 return -EPERM;
185 if (magic != 0xfee1dead || magic_too != 672274793)
186 return -EINVAL;
187 if (flag == 0x01234567)
188 hard_reset_now();
189 else if (flag == 0x89ABCDEF)
190 C_A_D = 1;
191 else if (!flag)
192 C_A_D = 0;
193 else if (flag == 0xCDEF0123) {
194 printk(KERN_EMERG "System halted\n");
195 sys_kill(-1, SIGKILL);
196 do_exit(0);
197 } else
198 return -EINVAL;
199 return (0);
200 }
201
202
203
204
205
206
207 void ctrl_alt_del(void)
208 {
209 if (C_A_D)
210 hard_reset_now();
211 else
212 kill_proc(1, SIGINT, 1);
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
232 {
233 int old_rgid = current->gid;
234 int old_egid = current->egid;
235
236 if (rgid != (gid_t) -1) {
237 if ((old_rgid == rgid) ||
238 (current->egid==rgid) ||
239 suser())
240 current->gid = rgid;
241 else
242 return(-EPERM);
243 }
244 if (egid != (gid_t) -1) {
245 if ((old_rgid == egid) ||
246 (current->egid == egid) ||
247 (current->sgid == egid) ||
248 suser())
249 current->egid = egid;
250 else {
251 current->gid = old_rgid;
252 return(-EPERM);
253 }
254 }
255 if (rgid != (gid_t) -1 ||
256 (egid != (gid_t) -1 && egid != old_rgid))
257 current->sgid = current->egid;
258 current->fsgid = current->egid;
259 if (current->egid != old_egid)
260 current->dumpable = 0;
261 return 0;
262 }
263
264
265
266
267 asmlinkage int sys_setgid(gid_t gid)
268 {
269 int old_egid = current->egid;
270
271 if (suser())
272 current->gid = current->egid = current->sgid = current->fsgid = gid;
273 else if ((gid == current->gid) || (gid == current->sgid))
274 current->egid = current->fsgid = gid;
275 else
276 return -EPERM;
277 if (current->egid != old_egid)
278 current->dumpable = 0;
279 return 0;
280 }
281
282 static char acct_active = 0;
283 static struct file acct_file;
284
285 int acct_process(long exitcode)
286 {
287 struct acct ac;
288 unsigned short fs;
289
290 if (acct_active) {
291 strncpy(ac.ac_comm, current->comm, ACCT_COMM);
292 ac.ac_comm[ACCT_COMM-1] = '\0';
293 ac.ac_utime = current->utime;
294 ac.ac_stime = current->stime;
295 ac.ac_btime = CT_TO_SECS(current->start_time) + (xtime.tv_sec - (jiffies / HZ));
296 ac.ac_etime = CURRENT_TIME - ac.ac_btime;
297 ac.ac_uid = current->uid;
298 ac.ac_gid = current->gid;
299 ac.ac_tty = (current)->tty == NULL ? -1 :
300 MKDEV(4, current->tty->device);
301 ac.ac_flag = 0;
302 if (current->flags & PF_FORKNOEXEC)
303 ac.ac_flag |= AFORK;
304 if (current->flags & PF_SUPERPRIV)
305 ac.ac_flag |= ASU;
306 if (current->flags & PF_DUMPCORE)
307 ac.ac_flag |= ACORE;
308 if (current->flags & PF_SIGNALED)
309 ac.ac_flag |= AXSIG;
310 ac.ac_minflt = current->min_flt;
311 ac.ac_majflt = current->maj_flt;
312 ac.ac_exitcode = exitcode;
313
314
315 fs = get_fs();
316 set_fs(KERNEL_DS);
317
318 acct_file.f_op->write(acct_file.f_inode, &acct_file,
319 (char *)&ac, sizeof(struct acct));
320
321 set_fs(fs);
322 }
323 return 0;
324 }
325
326 asmlinkage int sys_acct(const char *name)
327 {
328 struct inode *inode = (struct inode *)0;
329 char *tmp;
330 int error;
331
332 if (!suser())
333 return -EPERM;
334
335 if (name == (char *)0) {
336 if (acct_active) {
337 if (acct_file.f_op->release)
338 acct_file.f_op->release(acct_file.f_inode, &acct_file);
339
340 if (acct_file.f_inode != (struct inode *) 0)
341 iput(acct_file.f_inode);
342
343 acct_active = 0;
344 }
345 return 0;
346 } else {
347 if (!acct_active) {
348
349 if ((error = getname(name, &tmp)) != 0)
350 return (error);
351
352 error = open_namei(tmp, O_RDWR, 0600, &inode, 0);
353 putname(tmp);
354
355 if (error)
356 return (error);
357
358 if (!S_ISREG(inode->i_mode)) {
359 iput(inode);
360 return -EACCES;
361 }
362
363 if (!inode->i_op || !inode->i_op->default_file_ops ||
364 !inode->i_op->default_file_ops->write) {
365 iput(inode);
366 return -EIO;
367 }
368
369 acct_file.f_mode = 3;
370 acct_file.f_flags = 0;
371 acct_file.f_count = 1;
372 acct_file.f_inode = inode;
373 acct_file.f_pos = inode->i_size;
374 acct_file.f_reada = 0;
375 acct_file.f_op = inode->i_op->default_file_ops;
376
377 if (acct_file.f_op->open)
378 if (acct_file.f_op->open(acct_file.f_inode, &acct_file)) {
379 iput(inode);
380 return -EIO;
381 }
382
383 acct_active = 1;
384 return 0;
385 } else
386 return -EBUSY;
387 }
388 }
389
390 #ifndef __alpha__
391
392
393
394
395
396
397
398 asmlinkage int sys_phys(void)
399 {
400 return -ENOSYS;
401 }
402
403 asmlinkage int sys_lock(void)
404 {
405 return -ENOSYS;
406 }
407
408 asmlinkage int sys_mpx(void)
409 {
410 return -ENOSYS;
411 }
412
413 asmlinkage int sys_ulimit(void)
414 {
415 return -ENOSYS;
416 }
417
418 asmlinkage int sys_old_syscall(void)
419 {
420 return -ENOSYS;
421 }
422
423 #endif
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
441 {
442 int old_ruid = current->uid;
443 int old_euid = current->euid;
444
445 if (ruid != (uid_t) -1) {
446 if ((old_ruid == ruid) ||
447 (current->euid==ruid) ||
448 suser())
449 current->uid = ruid;
450 else
451 return(-EPERM);
452 }
453 if (euid != (uid_t) -1) {
454 if ((old_ruid == euid) ||
455 (current->euid == euid) ||
456 (current->suid == euid) ||
457 suser())
458 current->euid = euid;
459 else {
460 current->uid = old_ruid;
461 return(-EPERM);
462 }
463 }
464 if (ruid != (uid_t) -1 ||
465 (euid != (uid_t) -1 && euid != old_ruid))
466 current->suid = current->euid;
467 current->fsuid = current->euid;
468 if (current->euid != old_euid)
469 current->dumpable = 0;
470 return 0;
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484 asmlinkage int sys_setuid(uid_t uid)
485 {
486 int old_euid = current->euid;
487
488 if (suser())
489 current->uid = current->euid = current->suid = current->fsuid = uid;
490 else if ((uid == current->uid) || (uid == current->suid))
491 current->fsuid = current->euid = uid;
492 else
493 return -EPERM;
494 if (current->euid != old_euid)
495 current->dumpable = 0;
496 return(0);
497 }
498
499
500
501
502
503
504
505 asmlinkage int sys_setfsuid(uid_t uid)
506 {
507 int old_fsuid = current->fsuid;
508
509 if (uid == current->uid || uid == current->euid ||
510 uid == current->suid || uid == current->fsuid || suser())
511 current->fsuid = uid;
512 if (current->fsuid != old_fsuid)
513 current->dumpable = 0;
514 return old_fsuid;
515 }
516
517
518
519
520 asmlinkage int sys_setfsgid(gid_t gid)
521 {
522 int old_fsgid = current->fsgid;
523
524 if (gid == current->gid || gid == current->egid ||
525 gid == current->sgid || gid == current->fsgid || suser())
526 current->fsgid = gid;
527 if (current->fsgid != old_fsgid)
528 current->dumpable = 0;
529 return old_fsgid;
530 }
531
532 asmlinkage long sys_times(struct tms * tbuf)
533 {
534 if (tbuf) {
535 int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
536 if (error)
537 return error;
538 put_user(current->utime,&tbuf->tms_utime);
539 put_user(current->stime,&tbuf->tms_stime);
540 put_user(current->cutime,&tbuf->tms_cutime);
541 put_user(current->cstime,&tbuf->tms_cstime);
542 }
543 return jiffies;
544 }
545
546 asmlinkage unsigned long sys_brk(unsigned long brk)
547 {
548 int freepages;
549 unsigned long rlim;
550 unsigned long newbrk, oldbrk;
551
552 if (brk < current->mm->end_code)
553 return current->mm->brk;
554 newbrk = PAGE_ALIGN(brk);
555 oldbrk = PAGE_ALIGN(current->mm->brk);
556 if (oldbrk == newbrk)
557 return current->mm->brk = brk;
558
559
560
561
562 if (brk <= current->mm->brk) {
563 current->mm->brk = brk;
564 do_munmap(newbrk, oldbrk-newbrk);
565 return brk;
566 }
567
568
569
570 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
571 if (rlim >= RLIM_INFINITY)
572 rlim = ~0;
573 if (brk - current->mm->end_code > rlim)
574 return current->mm->brk;
575
576
577
578 if (find_vma_intersection(current, oldbrk, newbrk+PAGE_SIZE))
579 return current->mm->brk;
580
581
582
583
584
585 freepages = buffermem >> PAGE_SHIFT;
586 freepages += page_cache_size;
587 freepages >>= 1;
588 freepages += nr_free_pages;
589 freepages += nr_swap_pages;
590 freepages -= MAP_NR(high_memory) >> 4;
591 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
592 if (freepages < 0)
593 return current->mm->brk;
594 #if 0
595 freepages += current->mm->rss;
596 freepages -= oldbrk >> 12;
597 if (freepages < 0)
598 return current->mm->brk;
599 #endif
600
601
602
603 current->mm->brk = brk;
604 do_mmap(NULL, oldbrk, newbrk-oldbrk,
605 PROT_READ|PROT_WRITE|PROT_EXEC,
606 MAP_FIXED|MAP_PRIVATE, 0);
607 return brk;
608 }
609
610
611
612
613
614
615
616
617
618
619
620
621
622 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
623 {
624 struct task_struct * p;
625
626 if (!pid)
627 pid = current->pid;
628 if (!pgid)
629 pgid = pid;
630 if (pgid < 0)
631 return -EINVAL;
632 for_each_task(p) {
633 if (p->pid == pid)
634 goto found_task;
635 }
636 return -ESRCH;
637
638 found_task:
639 if (p->p_pptr == current || p->p_opptr == current) {
640 if (p->session != current->session)
641 return -EPERM;
642 if (p->did_exec)
643 return -EACCES;
644 } else if (p != current)
645 return -ESRCH;
646 if (p->leader)
647 return -EPERM;
648 if (pgid != pid) {
649 struct task_struct * tmp;
650 for_each_task (tmp) {
651 if (tmp->pgrp == pgid &&
652 tmp->session == current->session)
653 goto ok_pgid;
654 }
655 return -EPERM;
656 }
657
658 ok_pgid:
659 p->pgrp = pgid;
660 return 0;
661 }
662
663 asmlinkage int sys_getpgid(pid_t pid)
664 {
665 struct task_struct * p;
666
667 if (!pid)
668 return current->pgrp;
669 for_each_task(p) {
670 if (p->pid == pid)
671 return p->pgrp;
672 }
673 return -ESRCH;
674 }
675
676 asmlinkage int sys_getpgrp(void)
677 {
678 return current->pgrp;
679 }
680
681 asmlinkage int sys_getsid(pid_t pid)
682 {
683 struct task_struct * p;
684
685 if (!pid)
686 return current->session;
687 for_each_task(p) {
688 if (p->pid == pid)
689 return p->session;
690 }
691 return -ESRCH;
692 }
693
694 asmlinkage int sys_setsid(void)
695 {
696 if (current->leader)
697 return -EPERM;
698 current->leader = 1;
699 current->session = current->pgrp = current->pid;
700 current->tty = NULL;
701 current->tty_old_pgrp = 0;
702 return current->pgrp;
703 }
704
705
706
707
708 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
709 {
710 int i;
711 int * groups;
712
713 if (gidsetsize) {
714 i = verify_area(VERIFY_WRITE, grouplist, sizeof(gid_t) * gidsetsize);
715 if (i)
716 return i;
717 }
718 groups = current->groups;
719 for (i = 0 ; (i < NGROUPS) && (*groups != NOGROUP) ; i++, groups++) {
720 if (!gidsetsize)
721 continue;
722 if (i >= gidsetsize)
723 break;
724 put_user(*groups, grouplist);
725 grouplist++;
726 }
727 return(i);
728 }
729
730 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
731 {
732 int i;
733
734 if (!suser())
735 return -EPERM;
736 if (gidsetsize > NGROUPS)
737 return -EINVAL;
738 i = verify_area(VERIFY_READ, grouplist, sizeof(gid_t) * gidsetsize);
739 if (i)
740 return i;
741 for (i = 0; i < gidsetsize; i++, grouplist++) {
742 current->groups[i] = get_user(grouplist);
743 }
744 if (i < NGROUPS)
745 current->groups[i] = NOGROUP;
746 return 0;
747 }
748
749 int in_group_p(gid_t grp)
750 {
751 int i;
752
753 if (grp == current->fsgid)
754 return 1;
755
756 for (i = 0; i < NGROUPS; i++) {
757 if (current->groups[i] == NOGROUP)
758 break;
759 if (current->groups[i] == grp)
760 return 1;
761 }
762 return 0;
763 }
764
765 asmlinkage int sys_newuname(struct new_utsname * name)
766 {
767 int error;
768
769 if (!name)
770 return -EFAULT;
771 error = verify_area(VERIFY_WRITE, name, sizeof *name);
772 if (!error)
773 memcpy_tofs(name,&system_utsname,sizeof *name);
774 return error;
775 }
776
777 #ifndef __alpha__
778
779
780
781
782
783 asmlinkage int sys_uname(struct old_utsname * name)
784 {
785 int error;
786 if (!name)
787 return -EFAULT;
788 error = verify_area(VERIFY_WRITE, name,sizeof *name);
789 if (error)
790 return error;
791 memcpy_tofs(&name->sysname,&system_utsname.sysname,
792 sizeof (system_utsname.sysname));
793 memcpy_tofs(&name->nodename,&system_utsname.nodename,
794 sizeof (system_utsname.nodename));
795 memcpy_tofs(&name->release,&system_utsname.release,
796 sizeof (system_utsname.release));
797 memcpy_tofs(&name->version,&system_utsname.version,
798 sizeof (system_utsname.version));
799 memcpy_tofs(&name->machine,&system_utsname.machine,
800 sizeof (system_utsname.machine));
801 return 0;
802 }
803
804 asmlinkage int sys_olduname(struct oldold_utsname * name)
805 {
806 int error;
807 if (!name)
808 return -EFAULT;
809 error = verify_area(VERIFY_WRITE, name,sizeof *name);
810 if (error)
811 return error;
812 memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
813 put_user(0,name->sysname+__OLD_UTS_LEN);
814 memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
815 put_user(0,name->nodename+__OLD_UTS_LEN);
816 memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN);
817 put_user(0,name->release+__OLD_UTS_LEN);
818 memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN);
819 put_user(0,name->version+__OLD_UTS_LEN);
820 memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
821 put_user(0,name->machine+__OLD_UTS_LEN);
822 return 0;
823 }
824
825 #endif
826
827 asmlinkage int sys_sethostname(char *name, int len)
828 {
829 int error;
830
831 if (!suser())
832 return -EPERM;
833 if (len < 0 || len > __NEW_UTS_LEN)
834 return -EINVAL;
835 error = verify_area(VERIFY_READ, name, len);
836 if (error)
837 return error;
838 memcpy_fromfs(system_utsname.nodename, name, len);
839 system_utsname.nodename[len] = 0;
840 return 0;
841 }
842
843 asmlinkage int sys_gethostname(char *name, int len)
844 {
845 int i;
846
847 if (len < 0)
848 return -EINVAL;
849 i = verify_area(VERIFY_WRITE, name, len);
850 if (i)
851 return i;
852 i = 1+strlen(system_utsname.nodename);
853 if (i > len)
854 i = len;
855 memcpy_tofs(name, system_utsname.nodename, i);
856 return 0;
857 }
858
859
860
861
862
863 asmlinkage int sys_setdomainname(char *name, int len)
864 {
865 int error;
866
867 if (!suser())
868 return -EPERM;
869 if (len < 0 || len > __NEW_UTS_LEN)
870 return -EINVAL;
871 error = verify_area(VERIFY_READ, name, len);
872 if (error)
873 return error;
874 memcpy_fromfs(system_utsname.domainname, name, len);
875 system_utsname.domainname[len] = 0;
876 return 0;
877 }
878
879 asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
880 {
881 int error;
882
883 if (resource >= RLIM_NLIMITS)
884 return -EINVAL;
885 error = verify_area(VERIFY_WRITE,rlim,sizeof *rlim);
886 if (error)
887 return error;
888 memcpy_tofs(rlim, current->rlim + resource, sizeof(*rlim));
889 return 0;
890 }
891
892 asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
893 {
894 struct rlimit new_rlim, *old_rlim;
895 int err;
896
897 if (resource >= RLIM_NLIMITS)
898 return -EINVAL;
899 err = verify_area(VERIFY_READ, rlim, sizeof(*rlim));
900 if (err)
901 return err;
902 memcpy_fromfs(&new_rlim, rlim, sizeof(*rlim));
903 old_rlim = current->rlim + resource;
904 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
905 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
906 !suser())
907 return -EPERM;
908 if (resource == RLIMIT_NOFILE) {
909 if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
910 return -EPERM;
911 }
912 *old_rlim = new_rlim;
913 return 0;
914 }
915
916
917
918
919
920
921
922
923
924 int getrusage(struct task_struct *p, int who, struct rusage *ru)
925 {
926 int error;
927 struct rusage r;
928
929 error = verify_area(VERIFY_WRITE, ru, sizeof *ru);
930 if (error)
931 return error;
932 memset((char *) &r, 0, sizeof(r));
933 switch (who) {
934 case RUSAGE_SELF:
935 r.ru_utime.tv_sec = CT_TO_SECS(p->utime);
936 r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
937 r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
938 r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
939 r.ru_minflt = p->min_flt;
940 r.ru_majflt = p->maj_flt;
941 r.ru_nswap = p->nswap;
942 break;
943 case RUSAGE_CHILDREN:
944 r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
945 r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
946 r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
947 r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
948 r.ru_minflt = p->cmin_flt;
949 r.ru_majflt = p->cmaj_flt;
950 r.ru_nswap = p->cnswap;
951 break;
952 default:
953 r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
954 r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
955 r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
956 r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
957 r.ru_minflt = p->min_flt + p->cmin_flt;
958 r.ru_majflt = p->maj_flt + p->cmaj_flt;
959 r.ru_nswap = p->nswap + p->cnswap;
960 break;
961 }
962 memcpy_tofs(ru, &r, sizeof(r));
963 return 0;
964 }
965
966 asmlinkage int sys_getrusage(int who, struct rusage *ru)
967 {
968 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
969 return -EINVAL;
970 return getrusage(current, who, ru);
971 }
972
973 asmlinkage int sys_umask(int mask)
974 {
975 int old = current->fs->umask;
976
977 current->fs->umask = mask & S_IRWXUGO;
978 return (old);
979 }