]> git.hungrycats.org Git - linux/commitdiff
[PATCH] getrlimit,setrlimit,getrusage,wait4 unification
authorRandolph Chung <tausq@debian.org>
Wed, 16 Apr 2003 14:45:43 +0000 (07:45 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Wed, 16 Apr 2003 14:45:43 +0000 (07:45 -0700)
17 files changed:
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall.S
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/sys_ppc32.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/x86_64/ia32/ia32entry.S
arch/x86_64/ia32/sys_ia32.c
include/asm-parisc/compat.h
include/asm-ppc64/compat.h
include/asm-s390/compat.h
include/asm-sparc64/compat.h
include/asm-x86_64/compat.h
include/linux/compat.h
kernel/compat.c

index 011b648aeccb31b2b63a211d65c1f7c88856759d..63a85350d4ea05764dbb7ebe5b6318b0af0746dc 100644 (file)
@@ -475,81 +475,6 @@ sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
     return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
 }
 
-struct rusage32 {
-        struct compat_timeval ru_utime;
-        struct compat_timeval ru_stime;
-        int    ru_maxrss;
-        int    ru_ixrss;
-        int    ru_idrss;
-        int    ru_isrss;
-        int    ru_minflt;
-        int    ru_majflt;
-        int    ru_nswap;
-        int    ru_inblock;
-        int    ru_oublock;
-        int    ru_msgsnd; 
-        int    ru_msgrcv; 
-        int    ru_nsignals;
-        int    ru_nvcsw;
-        int    ru_nivcsw;
-};
-
-static int
-put_rusage32(struct rusage32 *ru32p, struct rusage *r)
-{
-       struct rusage32 r32;
-#undef CP
-#define CP(t) r32.t = r->t;
-       CP(ru_utime.tv_sec); CP(ru_utime.tv_usec);
-       CP(ru_stime.tv_sec); CP(ru_stime.tv_usec);
-       CP(ru_maxrss);
-       CP(ru_ixrss);
-       CP(ru_idrss);
-       CP(ru_isrss);
-       CP(ru_minflt);
-       CP(ru_majflt);
-       CP(ru_nswap);
-       CP(ru_inblock);
-       CP(ru_oublock);
-       CP(ru_msgsnd);
-       CP(ru_msgrcv);
-       CP(ru_nsignals);
-       CP(ru_nvcsw);
-       CP(ru_nivcsw);
-       return copy_to_user(ru32p, &r32, sizeof r32);
-}
-
-asmlinkage int
-sys32_getrusage(int who, struct rusage32 *ru)
-{
-       struct rusage r;
-       int ret;
-       extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
-               
-       KERNEL_SYSCALL(ret, sys_getrusage, who, &r);
-       if (put_rusage32(ru, &r)) return -EFAULT;
-       return ret;
-}
-
-asmlinkage int
-sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
-           struct rusage32 * ru)
-{
-       if (!ru)
-               return sys_wait4(pid, stat_addr, options, NULL);
-       else {
-               struct rusage r;
-               int ret;
-               unsigned int status;
-       
-               KERNEL_SYSCALL(ret, sys_wait4, pid, stat_addr ? &status : NULL, options, &r);
-               if (put_rusage32(ru, &r)) return -EFAULT;
-               if (stat_addr && put_user(status, stat_addr))
-                       return -EFAULT;
-               return ret;
-       }
-}
-
 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
 {
        int err;
@@ -721,74 +646,6 @@ out:
        return error;
 }
 
-struct rlimit32 {
-       __u32   rlim_cur;
-       __u32   rlim_max;
-};
-
-#define RLIM32_INFINITY 0xffffffff
-
-asmlinkage long sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit32 rlim32;
-       struct rlimit *rlimip;
-
-       if (resource >= RLIM_NLIMITS)
-               return -EINVAL;
-       rlimip = current->rlim + resource;
-       if (rlimip->rlim_cur >= RLIM32_INFINITY) {
-               rlim32.rlim_cur = RLIM32_INFINITY;
-       } else {
-               rlim32.rlim_cur = rlimip->rlim_cur;
-       }
-       if (rlimip->rlim_max >= RLIM32_INFINITY) {
-               rlim32.rlim_max = RLIM32_INFINITY;
-       } else {
-               rlim32.rlim_max = rlimip->rlim_max;
-       }
-       return copy_to_user(rlim, &rlim32, sizeof (struct rlimit32));
-}
-
-asmlinkage long sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit32 rlim32;
-       struct rlimit new_rlim, *old_rlim;
-
-       if (resource >= RLIM_NLIMITS)
-               return -EINVAL;
-       if (copy_from_user(&rlim32, rlim, sizeof(rlim)))
-               return -EFAULT;
-       if (rlim32.rlim_cur == RLIM32_INFINITY) {
-               new_rlim.rlim_cur = RLIM_INFINITY;
-       } else {
-               new_rlim.rlim_cur = rlim32.rlim_cur;
-       }
-       if (rlim32.rlim_max == RLIM32_INFINITY) {
-               new_rlim.rlim_max = RLIM_INFINITY;
-       } else {
-               new_rlim.rlim_max = rlim32.rlim_max;
-       }
-
-       old_rlim = current->rlim + resource;
-       if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
-            (new_rlim.rlim_max > old_rlim->rlim_max)) &&
-           !capable(CAP_SYS_RESOURCE))
-               return -EPERM;
-       if (resource == RLIMIT_NOFILE) {
-               if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
-                       return -EPERM;
-       }
-       if (resource == RLIMIT_STACK) {
-               if (new_rlim.rlim_max > 1024 * 1024 * 1024) {
-                       new_rlim.rlim_max = 1024 * 1024 * 1024;
-               }
-               new_rlim.rlim_max = PAGE_ALIGN(new_rlim.rlim_max);
-       }
-       
-       *old_rlim = new_rlim;
-       return 0;
-}
-
 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
 {
        int i;
index 929a4a3cb695fbbe4be6d746d5af00a970276557..f1b08ceafe807b7ea99d44884699f87d94446687 100644 (file)
@@ -431,9 +431,9 @@ sys_call_table:
        ENTRY_COMP(sigpending)
        ENTRY_SAME(sethostname)
        /* Following 3 have linux-common-code structs containing longs -( */
-       ENTRY_DIFF(setrlimit)           /* 75 */
-       ENTRY_DIFF(getrlimit)
-       ENTRY_DIFF(getrusage)
+       ENTRY_COMP(setrlimit)           /* 75 */
+       ENTRY_COMP(getrlimit)
+       ENTRY_COMP(getrusage)
        /* struct timeval and timezone are maybe?? consistent wide and narrow */
        ENTRY_DIFF(gettimeofday)
        ENTRY_DIFF(settimeofday)
@@ -476,7 +476,7 @@ sys_call_table:
        ENTRY_SAME(fstat64)
        ENTRY_SAME(vfork_wrapper)
        /* struct rusage contains longs... */
-       ENTRY_DIFF(wait4)
+       ENTRY_COMP(wait4)
        ENTRY_SAME(swapoff)             /* 115 */
        ENTRY_DIFF(sysinfo)
        ENTRY_SAME(shutdown)
index 2af247e0e7a1645baddc16716380d87446c67e53..b13facd777aa6cdd7c4dd7dd3d8119aa652d50d0 100644 (file)
@@ -577,9 +577,9 @@ _GLOBAL(sys_call_table32)
        .llong .sys_sigsuspend
        .llong .compat_sys_sigpending
        .llong .sys32_sethostname
-       .llong .sys32_setrlimit         /* 75 */
-       .llong .sys32_old_getrlimit
-       .llong .sys32_getrusage
+       .llong .compat_sys_setrlimit            /* 75 */
+       .llong .compat_sys_old_getrlimit
+       .llong .compat_sys_getrusage
        .llong .sys32_gettimeofday
        .llong .sys32_settimeofday
        .llong .sys32_getgroups         /* 80 */
@@ -616,7 +616,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys_vhangup
        .llong .sys_ni_syscall          /* old idle syscall */
        .llong .sys_ni_syscall          /* old vm86 syscall */
-       .llong .sys32_wait4
+       .llong .compat_sys_wait4
        .llong .sys_swapoff             /* 115 */
        .llong .sys32_sysinfo
        .llong .sys32_ipc
@@ -692,7 +692,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys_ni_syscall          /* reserved for streams1 */
        .llong .sys_ni_syscall          /* reserved for streams2 */
        .llong .sys_vfork
-       .llong .sys32_getrlimit         /* 190 */
+       .llong .compat_sys_getrlimit            /* 190 */
        .llong .sys32_readahead
        .llong .sys32_mmap2
        .llong .sys32_truncate64
index a7c67d5da6b26e146ed608dce63d6ea9494fdd8f..fba8c8254455153e7daf72aaf4052a94bc779e31 100644 (file)
@@ -1125,152 +1125,6 @@ static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
                 __put_user(i->tv_usec, &o->tv_usec)));
 }
 
-
-
-
-#define RLIM_INFINITY32        0xffffffff
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
-
-struct rlimit32 {
-       u32     rlim_cur;
-       u32     rlim_max;
-};
-
-extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage long sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
-       set_fs(old_fs);
-       if (!ret) {
-               ret = put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
-               ret |= __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max);
-       }
-       
-       return ret;
-}
-
-/* Back compatibility for getrlimit. Needed for some apps. */
-asmlinkage long sys32_old_getrlimit(unsigned int resource, struct rlimit32* rlim)
-{
-       struct rlimit   x;    // 64-bit version of the resource limits.
-       struct rlimit32 x32;  // 32-bit version of the resource limits.
-
-       if (resource >= RLIM_NLIMITS)
-               return -EINVAL;
-
-       memcpy(&x, current->rlim+resource, sizeof(struct rlimit));
-
-       if (x.rlim_cur > RLIM_INFINITY32)
-               x32.rlim_cur = RLIM_INFINITY32;
-       else
-               x32.rlim_cur = x.rlim_cur;
-
-       if (x.rlim_max > RLIM_INFINITY32)
-               x32.rlim_max = RLIM_INFINITY32;
-       else
-               x32.rlim_max = x.rlim_max;
-
-       return (copy_to_user(rlim, &x32, sizeof(x32))) ? (-EFAULT) : 0;
-}
-
-extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage long sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       long ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       if (resource >= RLIM_NLIMITS) return -EINVAL;   
-       if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
-           __get_user (r.rlim_max, &rlim->rlim_max))
-               return -EFAULT;
-       if (r.rlim_cur >= RLIM_INFINITY32)
-               r.rlim_cur = RLIM_INFINITY;
-       if (r.rlim_max >= RLIM_INFINITY32)
-               r.rlim_max = RLIM_INFINITY;
-       set_fs (KERNEL_DS);
-       ret = sys_setrlimit(resource, &r);
-       set_fs (old_fs);
-       
-       return ret;
-}
-
-
-struct rusage32 {
-        struct compat_timeval ru_utime;
-        struct compat_timeval ru_stime;
-        s32    ru_maxrss;
-        s32    ru_ixrss;
-        s32    ru_idrss;
-        s32    ru_isrss;
-        s32    ru_minflt;
-        s32    ru_majflt;
-        s32    ru_nswap;
-        s32    ru_inblock;
-        s32    ru_oublock;
-        s32    ru_msgsnd; 
-        s32    ru_msgrcv; 
-        s32    ru_nsignals;
-        s32    ru_nvcsw;
-        s32    ru_nivcsw;
-};
-
-static int put_rusage (struct rusage32 *ru, struct rusage *r)
-{
-       int err;
-       
-       err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
-       err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
-       err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
-       err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
-       err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
-       err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
-       err |= __put_user (r->ru_idrss, &ru->ru_idrss);
-       err |= __put_user (r->ru_isrss, &ru->ru_isrss);
-       err |= __put_user (r->ru_minflt, &ru->ru_minflt);
-       err |= __put_user (r->ru_majflt, &ru->ru_majflt);
-       err |= __put_user (r->ru_nswap, &ru->ru_nswap);
-       err |= __put_user (r->ru_inblock, &ru->ru_inblock);
-       err |= __put_user (r->ru_oublock, &ru->ru_oublock);
-       err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
-       err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
-       err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
-       err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
-       err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
-       return err;
-}
-
-
-extern asmlinkage long sys_getrusage(int who, struct rusage *ru);
-
-/* Note: it is necessary to treat who as an unsigned int, 
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
- * and the register representation of a signed int (msr in 64-bit mode) is performed.
- */
-asmlinkage long sys32_getrusage(u32 who, struct rusage32 *ru)
-{
-       struct rusage r;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_getrusage((int)who, &r);
-       set_fs (old_fs);
-       if (put_rusage (ru, &r)) 
-               return -EFAULT;
-
-       return ret;
-}
-
-
-
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
@@ -2340,35 +2194,6 @@ asmlinkage long sys32_creat(const char * pathname, u32 mode)
 }
 
 
-extern asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options, struct rusage * ru);
-
-/* Note: it is necessary to treat pid and options as unsigned ints,
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
- * and the register representation of a signed int (msr in 64-bit mode) is performed.
- */
-asmlinkage long sys32_wait4(u32 pid, unsigned int * stat_addr, u32 options, struct rusage * ru)
-{
-       if (!ru)
-               return sys_wait4((int)pid, stat_addr, options, NULL);
-       else {
-               struct rusage r;
-               int ret;
-               unsigned int status;
-               mm_segment_t old_fs = get_fs();
-               
-               set_fs (KERNEL_DS);
-               ret = sys_wait4((int)pid, stat_addr ? &status : NULL, options, &r);
-               set_fs (old_fs);
-               if (put_rusage ((struct rusage32 *)ru, &r)) return -EFAULT;
-               if (stat_addr && put_user (status, stat_addr))
-                       return -EFAULT;
-               return ret;
-       }
-       
-}
-
-
 extern asmlinkage long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
 
 /* Note: it is necessary to treat pid and options as unsigned ints,
index 7120e9f3d1e47d6852b0f820b2c82e96f65c7544..fc131aa5d8ba15115c2425ddb0d8f581fa49f671 100644 (file)
@@ -1492,26 +1492,6 @@ static int put_rusage (struct rusage32 *ru, struct rusage *r)
        return err;
 }
 
-asmlinkage int sys32_wait4(compat_pid_t pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
-{
-       if (!ru)
-               return sys_wait4(pid, stat_addr, options, NULL);
-       else {
-               struct rusage r;
-               int ret;
-               unsigned int status;
-               mm_segment_t old_fs = get_fs();
-               
-               set_fs (KERNEL_DS);
-               ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
-               set_fs (old_fs);
-               if (put_rusage (ru, &r)) return -EFAULT;
-               if (stat_addr && put_user (status, stat_addr))
-                       return -EFAULT;
-               return ret;
-       }
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
@@ -1733,87 +1713,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
        return ret;
 }
 
-#define RLIM_OLD_INFINITY32    0x7fffffff
-#define RLIM_INFINITY32                0xffffffff
-#define RESOURCE32_OLD(x)      ((x > RLIM_OLD_INFINITY32) ? RLIM_OLD_INFINITY32 : x)
-#define RESOURCE32(x)          ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
-
-struct rlimit32 {
-       u32     rlim_cur;
-       u32     rlim_max;
-};
-
-extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage int sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
-       set_fs (old_fs);
-       if (!ret) {
-               ret = put_user (RESOURCE32_OLD(r.rlim_cur), &rlim->rlim_cur);
-               ret |= __put_user (RESOURCE32_OLD(r.rlim_max), &rlim->rlim_max);
-       }
-       return ret;
-}
-
-asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
-       set_fs (old_fs);
-       if (!ret) {
-               ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
-               ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
-       }
-       return ret;
-}
-
-extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-
-       if (resource >= RLIM_NLIMITS) return -EINVAL;   
-       if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
-           __get_user (r.rlim_max, &rlim->rlim_max))
-               return -EFAULT;
-       if (r.rlim_cur == RLIM_INFINITY32)
-               r.rlim_cur = RLIM_INFINITY;
-       if (r.rlim_max == RLIM_INFINITY32)
-               r.rlim_max = RLIM_INFINITY;
-       set_fs (KERNEL_DS);
-       ret = sys_setrlimit(resource, &r);
-       set_fs (old_fs);
-       return ret;
-}
-
-extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
-
-asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
-{
-       struct rusage r;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-               
-       set_fs (KERNEL_DS);
-       ret = sys_getrusage(who, &r);
-       set_fs (old_fs);
-       if (put_rusage (ru, &r)) return -EFAULT;
-       return ret;
-}
-
 extern void check_pending(int signum);
 
 /*
index 6b45e7f1ee37dc9394d956c4d37f5e78cdf0c63f..e450a8116a030fd2793e92340b63120c043e4918 100644 (file)
@@ -299,34 +299,34 @@ sys32_sethostname_wrapper:
        lgfr    %r3,%r3                 # int
        jg      sys_sethostname         # branch to system call
 
-       .globl  sys32_setrlimit_wrapper 
-sys32_setrlimit_wrapper:
+       .globl  compat_sys_setrlimit_wrapper 
+compat_sys_setrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
-       jg      sys32_setrlimit         # branch to system call
+       jg      compat_sys_setrlimit    # branch to system call
 
-       .globl  sys32_old_getrlimit_wrapper 
-sys32_old_getrlimit_wrapper:
+       .globl  compat_sys_old_getrlimit_wrapper 
+compat_sys_old_getrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
-       jg      sys32_old_getrlimit     # branch to system call
+       jg      compat_sys_old_getrlimit # branch to system call
 
-       .globl  sys32_getrlimit_wrapper 
-sys32_getrlimit_wrapper:
+       .globl  compat_sys_getrlimit_wrapper 
+compat_sys_getrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
-       jg      sys32_getrlimit         # branch to system call
+       jg      compat_sys_getrlimit    # branch to system call
 
        .globl  sys32_mmap2_wrapper 
 sys32_mmap2_wrapper:
        llgtr   %r2,%r2                 # struct mmap_arg_struct_emu31 *
        jg      sys32_mmap2                     # branch to system call
 
-       .globl  sys32_getrusage_wrapper 
-sys32_getrusage_wrapper:
+       .globl  compat_sys_getrusage_wrapper 
+compat_sys_getrusage_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct rusage_emu31 *
-       jg      sys32_getrusage         # branch to system call
+       jg      compat_sys_getrusage    # branch to system call
 
        .globl  sys32_gettimeofday_wrapper 
 sys32_gettimeofday_wrapper:
@@ -498,13 +498,13 @@ compat_sys_newfstat_wrapper:
 
 #sys32_vhangup_wrapper                 # void 
 
-       .globl  sys32_wait4_wrapper 
-sys32_wait4_wrapper:
+       .globl  compat_sys_wait4_wrapper 
+compat_sys_wait4_wrapper:
        lgfr    %r2,%r2                 # pid_t
        llgtr   %r3,%r3                 # unsigned int *
        lgfr    %r4,%r4                 # int
        llgtr   %r5,%r5                 # struct rusage *
-       jg      sys32_wait4             # branch to system call
+       jg      compat_sys_wait4        # branch to system call
 
        .globl  sys32_swapoff_wrapper 
 sys32_swapoff_wrapper:
index 9122aa000ad51db4a3c4efc0d1a73fc51714b8bd..b1194401debae39f114896cfa4fe7e1c09f742e4 100644 (file)
@@ -1521,70 +1521,6 @@ out:
        return err;
 }
 
-struct rusage32 {
-        struct compat_timeval ru_utime;
-        struct compat_timeval ru_stime;
-        s32    ru_maxrss;
-        s32    ru_ixrss;
-        s32    ru_idrss;
-        s32    ru_isrss;
-        s32    ru_minflt;
-        s32    ru_majflt;
-        s32    ru_nswap;
-        s32    ru_inblock;
-        s32    ru_oublock;
-        s32    ru_msgsnd; 
-        s32    ru_msgrcv; 
-        s32    ru_nsignals;
-        s32    ru_nvcsw;
-        s32    ru_nivcsw;
-};
-
-static int put_rusage (struct rusage32 *ru, struct rusage *r)
-{
-       int err;
-       
-       err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
-       err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
-       err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
-       err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
-       err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
-       err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
-       err |= __put_user (r->ru_idrss, &ru->ru_idrss);
-       err |= __put_user (r->ru_isrss, &ru->ru_isrss);
-       err |= __put_user (r->ru_minflt, &ru->ru_minflt);
-       err |= __put_user (r->ru_majflt, &ru->ru_majflt);
-       err |= __put_user (r->ru_nswap, &ru->ru_nswap);
-       err |= __put_user (r->ru_inblock, &ru->ru_inblock);
-       err |= __put_user (r->ru_oublock, &ru->ru_oublock);
-       err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
-       err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
-       err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
-       err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
-       err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
-       return err;
-}
-
-asmlinkage int sys32_wait4(compat_pid_t pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
-{
-       if (!ru)
-               return sys_wait4(pid, stat_addr, options, NULL);
-       else {
-               struct rusage r;
-               int ret;
-               unsigned int status;
-               mm_segment_t old_fs = get_fs();
-               
-               set_fs (KERNEL_DS);
-               ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
-               set_fs (old_fs);
-               if (put_rusage (ru, &r)) return -EFAULT;
-               if (stat_addr && put_user (status, stat_addr))
-                       return -EFAULT;
-               return ret;
-       }
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
@@ -1805,69 +1741,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
        return ret;
 }
 
-#define RLIM_INFINITY32        0x7fffffff
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
-
-struct rlimit32 {
-       u32     rlim_cur;
-       u32     rlim_max;
-};
-
-extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
-       set_fs (old_fs);
-       if (!ret) {
-               ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
-               ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
-       }
-       return ret;
-}
-
-extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-
-       if (resource >= RLIM_NLIMITS) return -EINVAL;   
-       if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
-           __get_user (r.rlim_max, &rlim->rlim_max))
-               return -EFAULT;
-       if (r.rlim_cur == RLIM_INFINITY32)
-               r.rlim_cur = RLIM_INFINITY;
-       if (r.rlim_max == RLIM_INFINITY32)
-               r.rlim_max = RLIM_INFINITY;
-       set_fs (KERNEL_DS);
-       ret = sys_setrlimit(resource, &r);
-       set_fs (old_fs);
-       return ret;
-}
-
-extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
-
-asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
-{
-       struct rusage r;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-               
-       set_fs (KERNEL_DS);
-       ret = sys_getrusage(who, &r);
-       set_fs (old_fs);
-       if (put_rusage (ru, &r)) return -EFAULT;
-       return ret;
-}
-
 extern void check_pending(int signum);
 
 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
index 31efe79e77c94afca9940766494ceba476b76718..e2d02cced8536da788c2a7fbbdadd674b456c81e 100644 (file)
@@ -20,7 +20,7 @@
        .globl sys_call_table32
 sys_call_table32:
 /*0*/  .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
-/*5*/  .word sparc32_open, sys_close, sys32_wait4, sys_creat, sys_link
+/*5*/  .word sparc32_open, sys_close, compat_sys_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/ .word sys32_chmod, sys32_lchown16, sparc_brk, sys_perfctr, sys32_lseek
 /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
@@ -42,13 +42,13 @@ sys_call_table32:
 /*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
        .word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-       .word sys_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
+       .word sys_getgroups, sys32_gettimeofday, compat_sys_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/        .word sys32_readv, sys32_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
        .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
 /*130*/        .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
        .word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64
-/*140*/        .word sys32_sendfile64, sys_nis_syscall, compat_sys_futex, sys_gettid, sys32_getrlimit
-       .word sys32_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
+/*140*/        .word sys32_sendfile64, sys_nis_syscall, compat_sys_futex, sys_gettid, compat_sys_getrlimit
+       .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
 /*150*/        .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
        .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
 /*160*/        .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
index d70801da8afe2c9045e0bdddacba252e79f8ef27..ae1196f233013b3000fd082863ee740475e0795e 100644 (file)
@@ -279,9 +279,9 @@ ia32_sys_call_table:
        .quad stub32_sigsuspend
        .quad compat_sys_sigpending
        .quad sys_sethostname
-       .quad sys32_setrlimit   /* 75 */
-       .quad sys32_old_getrlimit       /* old_getrlimit */
-       .quad sys32_getrusage
+       .quad compat_sys_setrlimit      /* 75 */
+       .quad compat_sys_old_getrlimit  /* old_getrlimit */
+       .quad compat_sys_getrusage
        .quad sys32_gettimeofday
        .quad sys32_settimeofday
        .quad sys_getgroups16   /* 80 */
@@ -318,7 +318,7 @@ ia32_sys_call_table:
        .quad sys_vhangup
        .quad ni_syscall        /* old "idle" system call */
        .quad sys32_vm86_warning        /* vm86old */ 
-       .quad sys32_wait4
+       .quad compat_sys_wait4
        .quad sys_swapoff               /* 115 */
        .quad sys32_sysinfo
        .quad sys32_ipc
@@ -395,7 +395,7 @@ ia32_sys_call_table:
        .quad ni_syscall                /* streams1 */
        .quad ni_syscall                /* streams2 */
        .quad stub32_vfork            /* 190 */
-       .quad sys32_getrlimit
+       .quad compat_sys_getrlimit
        .quad sys32_mmap2
        .quad sys_truncate
        .quad sys_ftruncate
index 40a88a198c31770b84f64de732063ee7b0608b00..292936f958f0529909a8690e846fbc2d73253291 100644 (file)
@@ -836,82 +836,6 @@ sys32_writev(int fd, struct compat_iovec *vector, u32 count)
        return ret;
 }
 
-#define RLIM_INFINITY32        0xffffffff
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
-
-struct rlimit32 {
-       int     rlim_cur;
-       int     rlim_max;
-};
-
-extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage long
-sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
-       set_fs(old_fs);
-       if (!ret) {
-               if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
-                   __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) ||
-                   __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max))
-                       ret = -EFAULT;
-       }
-       return ret;
-}
-
-extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage long
-sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs;
-       
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_old_getrlimit(resource, &r);
-       set_fs(old_fs);
-       if (!ret) {
-               if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
-                   __put_user(r.rlim_cur, &rlim->rlim_cur) ||
-                   __put_user(r.rlim_max, &rlim->rlim_max))
-                       ret = -EFAULT;
-       }
-       return ret;
-}
-
-extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-
-asmlinkage long
-sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
-{
-       struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-
-       if (resource >= RLIM_NLIMITS) return -EINVAL;   
-       if (verify_area(VERIFY_READ, rlim, sizeof(struct rlimit32)) ||
-           __get_user (r.rlim_cur, &rlim->rlim_cur) ||
-           __get_user (r.rlim_max, &rlim->rlim_max))
-               return -EFAULT;
-       if (r.rlim_cur == RLIM_INFINITY32)
-               r.rlim_cur = RLIM_INFINITY;
-       if (r.rlim_max == RLIM_INFINITY32)
-               r.rlim_max = RLIM_INFINITY;
-       set_fs (KERNEL_DS);
-       ret = sys_setrlimit(resource, &r);
-       set_fs (old_fs);
-       return ret;
-}
-
 /*
  * sys_time() can be implemented in user-level using
  * sys_gettimeofday().  x86-64 did this but i386 Linux did not
@@ -931,80 +855,10 @@ asmlinkage long sys32_time(int * tloc)
        return i;
 }
 
-struct rusage32 {
-        struct compat_timeval ru_utime;
-        struct compat_timeval ru_stime;
-        int    ru_maxrss;
-        int    ru_ixrss;
-        int    ru_idrss;
-        int    ru_isrss;
-        int    ru_minflt;
-        int    ru_majflt;
-        int    ru_nswap;
-        int    ru_inblock;
-        int    ru_oublock;
-        int    ru_msgsnd; 
-        int    ru_msgrcv; 
-        int    ru_nsignals;
-        int    ru_nvcsw;
-        int    ru_nivcsw;
-};
-
-static int
-put_rusage (struct rusage32 *ru, struct rusage *r)
-{
-       if (verify_area(VERIFY_WRITE, ru, sizeof(struct rusage32)) ||
-           __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
-           __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
-           __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
-           __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
-           __put_user (r->ru_maxrss, &ru->ru_maxrss) ||
-           __put_user (r->ru_ixrss, &ru->ru_ixrss) ||
-           __put_user (r->ru_idrss, &ru->ru_idrss) ||
-           __put_user (r->ru_isrss, &ru->ru_isrss) ||
-           __put_user (r->ru_minflt, &ru->ru_minflt) ||
-           __put_user (r->ru_majflt, &ru->ru_majflt) ||
-           __put_user (r->ru_nswap, &ru->ru_nswap) ||
-           __put_user (r->ru_inblock, &ru->ru_inblock) ||
-           __put_user (r->ru_oublock, &ru->ru_oublock) ||
-           __put_user (r->ru_msgsnd, &ru->ru_msgsnd) ||
-           __put_user (r->ru_msgrcv, &ru->ru_msgrcv) ||
-           __put_user (r->ru_nsignals, &ru->ru_nsignals) ||
-           __put_user (r->ru_nvcsw, &ru->ru_nvcsw) ||
-           __put_user (r->ru_nivcsw, &ru->ru_nivcsw))
-               return -EFAULT;
-       return 0;
-}
-
-extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
-                               int options, struct rusage * ru);
-
-asmlinkage long
-sys32_wait4(compat_pid_t pid, unsigned int *stat_addr, int options,
-           struct rusage32 *ru)
-{
-       if (!ru)
-               return sys_wait4(pid, stat_addr, options, NULL);
-       else {
-               struct rusage r;
-               int ret;
-               unsigned int status;
-               mm_segment_t old_fs = get_fs();
-               
-               set_fs (KERNEL_DS);
-               ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
-               set_fs (old_fs);
-               if (put_rusage (ru, &r)) return -EFAULT;
-               if (stat_addr && put_user (status, stat_addr))
-                       return -EFAULT;
-               return ret;
-       }
-}
-
 asmlinkage long
 sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
 {
-       return sys32_wait4(pid, stat_addr, options, NULL);
+       return compat_sys_wait4(pid, stat_addr, options, NULL);
 }
 
 
index 2940a9757a6473e4b65976bc6fffceba62edbe0b..3a3ac178498df510df1735fd4fa38158abfc1103 100644 (file)
@@ -99,6 +99,8 @@ struct compat_statfs {
        s32             f_spare[6];
 };
 
+#define COMPAT_RLIM_INFINITY 0xffffffff
+
 typedef u32            compat_old_sigset_t;    /* at least 32 bits */
 
 #define _COMPAT_NSIG           64
index 4934e9315e761273eae8cd34f738d90e53afd406..913cbd936dd9470c14f61173843c97ee8c53a087 100644 (file)
@@ -93,6 +93,9 @@ struct compat_statfs {
        int             f_spare[6];
 };
 
+#define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
+#define COMPAT_RLIM_INFINITY           0xffffffff
+
 typedef u32            compat_old_sigset_t;
 
 #define _COMPAT_NSIG           64
index 55966b41d29087897edeb851e1c38ae7c51dbb80..b010629a46e98a7f2ab8d88a3b8a589fddba0992 100644 (file)
@@ -96,6 +96,9 @@ struct compat_statfs {
        s32             f_spare[6];
 };
 
+#define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
+#define COMPAT_RLIM_INFINITY           0xffffffff
+
 typedef u32            compat_old_sigset_t;    /* at least 32 bits */
 
 #define _COMPAT_NSIG           64
index dc174a7ef925ae691bac85d9b512508a20e507ac..6503e10e5a754160cf484598dfbda7ec24e9a004 100644 (file)
@@ -95,6 +95,8 @@ struct compat_statfs {
        int             f_spare[6];
 };
 
+#define COMPAT_RLIM_INFINITY 0x7fffffff
+
 typedef u32            compat_old_sigset_t;
 
 #define _COMPAT_NSIG           64
index 06c27d32eae527306852e9135b56628270e508d2..90265acf71b27068d13845d05c1c417a6a720f1a 100644 (file)
@@ -102,6 +102,9 @@ struct compat_statfs {
        int             f_spare[6];
 };
 
+#define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
+#define COMPAT_RLIM_INFINITY           0xffffffff
+
 typedef u32            compat_old_sigset_t;    /* at least 32 bits */
 
 #define _COMPAT_NSIG           64
index 305b8f0411a562760220f84257c909737cb7d9b4..bc69ea28d7e98c2abb6ea72f160a872b5a292c45 100644 (file)
@@ -47,5 +47,29 @@ struct compat_iovec {
        compat_size_t   iov_len;
 };
 
+struct compat_rlimit {
+       compat_ulong_t  rlim_cur;
+       compat_ulong_t  rlim_max;
+};
+
+struct compat_rusage {
+       struct compat_timeval ru_utime;
+       struct compat_timeval ru_stime;
+       compat_long_t   ru_maxrss;
+       compat_long_t   ru_ixrss;
+       compat_long_t   ru_idrss;
+       compat_long_t   ru_isrss;
+       compat_long_t   ru_minflt;
+       compat_long_t   ru_majflt;
+       compat_long_t   ru_nswap;
+       compat_long_t   ru_inblock;
+       compat_long_t   ru_oublock;
+       compat_long_t   ru_msgsnd;
+       compat_long_t   ru_msgrcv;
+       compat_long_t   ru_nsignals;
+       compat_long_t   ru_nvcsw;
+       compat_long_t   ru_nivcsw;
+};
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
index 13ab289c0fc5d88a9ea894ba6a18fb2331136f2c..0dcab5fc6acd858e862865014ad93b51323598f2 100644 (file)
@@ -227,6 +227,152 @@ asmlinkage long compat_sys_futex(u32 *uaddr, int op, int val,
        return do_futex((unsigned long)uaddr, op, val, timeout);
 }
 
+asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
+
+asmlinkage long compat_sys_setrlimit(unsigned int resource, struct compat_rlimit *rlim)
+{
+       struct rlimit r;
+       int ret;
+       mm_segment_t old_fs = get_fs ();
+
+       if (resource >= RLIM_NLIMITS) 
+               return -EINVAL; 
+
+       if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
+           __get_user(r.rlim_cur, &rlim->rlim_cur) ||
+           __get_user(r.rlim_max, &rlim->rlim_max))
+               return -EFAULT;
+
+       if (r.rlim_cur == COMPAT_RLIM_INFINITY)
+               r.rlim_cur = RLIM_INFINITY;
+       if (r.rlim_max == COMPAT_RLIM_INFINITY)
+               r.rlim_max = RLIM_INFINITY;
+       set_fs(KERNEL_DS);
+       ret = sys_setrlimit(resource, &r);
+       set_fs(old_fs);
+       return ret;
+}
+
+#ifdef COMPAT_RLIM_OLD_INFINITY
+asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
+
+asmlinkage long compat_sys_old_getrlimit(unsigned int resource, struct compat_rlimit *rlim)
+{
+       struct rlimit r;
+       int ret;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs(KERNEL_DS);
+       ret = sys_old_getrlimit(resource, &r);
+       set_fs(old_fs);
+
+       if (!ret) {
+               if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
+                       r.rlim_cur = COMPAT_RLIM_INFINITY;
+               if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
+                       r.rlim_max = COMPAT_RLIM_INFINITY;
+
+               if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
+                   __put_user(r.rlim_cur, &rlim->rlim_cur) ||
+                   __put_user(r.rlim_max, &rlim->rlim_max))
+                       return -EFAULT;
+       }
+       return ret;
+}
+#endif
+
+asmlinkage long sys_getrlimit (unsigned int resource, struct rlimit *rlim);
+
+asmlinkage long compat_sys_getrlimit (unsigned int resource, struct compat_rlimit *rlim)
+{
+       struct rlimit r;
+       int ret;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs(KERNEL_DS);
+       ret = sys_getrlimit(resource, &r);
+       set_fs(old_fs);
+       if (!ret) {
+               if (r.rlim_cur > COMPAT_RLIM_INFINITY)
+                       r.rlim_cur = COMPAT_RLIM_INFINITY;
+               if (r.rlim_max > COMPAT_RLIM_INFINITY)
+                       r.rlim_max = COMPAT_RLIM_INFINITY;
+
+               if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
+                   __put_user(r.rlim_cur, &rlim->rlim_cur) ||
+                   __put_user(r.rlim_max, &rlim->rlim_max))
+                       return -EFAULT;
+       }
+       return ret;
+}
+
+static long put_compat_rusage (struct compat_rusage *ru, struct rusage *r)
+{
+       if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
+           __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
+           __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
+           __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
+           __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
+           __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
+           __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
+           __put_user(r->ru_idrss, &ru->ru_idrss) ||
+           __put_user(r->ru_isrss, &ru->ru_isrss) ||
+           __put_user(r->ru_minflt, &ru->ru_minflt) ||
+           __put_user(r->ru_majflt, &ru->ru_majflt) ||
+           __put_user(r->ru_nswap, &ru->ru_nswap) ||
+           __put_user(r->ru_inblock, &ru->ru_inblock) ||
+           __put_user(r->ru_oublock, &ru->ru_oublock) ||
+           __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
+           __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
+           __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
+           __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
+           __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
+               return -EFAULT;
+       return 0;
+}
+
+asmlinkage long sys_getrusage(int who, struct rusage *ru);
+
+asmlinkage long compat_sys_getrusage(int who, struct compat_rusage *ru)
+{
+       struct rusage r;
+       int ret;
+       mm_segment_t old_fs = get_fs();
+               
+       set_fs(KERNEL_DS);
+       ret = sys_getrusage(who, &r);
+       set_fs(old_fs);
+
+       return ret || put_compat_rusage(ru, &r);
+}
+
+asmlinkage long
+compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options,
+       struct compat_rusage *ru)
+{
+       if (!ru) {
+               return sys_wait4(pid, stat_addr, options, NULL);
+       } else {
+               struct rusage r;
+               int ret;
+               unsigned int status;
+               mm_segment_t old_fs = get_fs();
+
+               set_fs (KERNEL_DS);
+               ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+               set_fs (old_fs);
+
+               if (!ret)
+               {
+                       if (put_compat_rusage(ru, &r)) 
+                               return -EFAULT;
+                       if (stat_addr && put_user(status, stat_addr))
+                               return -EFAULT;
+               }
+               return ret;
+       }
+}
+
 extern asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
                                            unsigned long *user_mask_ptr);