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