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