vserver 1.9.3
[linux-2.6.git] / arch / sparc64 / kernel / sys_sparc32.c
index e55f9e4..b81f155 100644 (file)
@@ -867,138 +867,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
                return sys_ftruncate(fd, (high << 32) | low);
 }
 
-/* readdir & getdents */
-
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
-
-struct old_linux_dirent32 {
-       u32             d_ino;
-       u32             d_offset;
-       unsigned short  d_namlen;
-       char            d_name[1];
-};
-
-struct readdir_callback32 {
-       struct old_linux_dirent32 __user * dirent;
-       int count;
-};
-
-static int fillonedir(void * __buf, const char * name, int namlen,
-                     loff_t offset, ino_t ino, unsigned int d_type)
-{
-       struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
-       struct old_linux_dirent32 __user * dirent;
-
-       if (buf->count)
-               return -EINVAL;
-       buf->count++;
-       dirent = buf->dirent;
-       put_user(ino, &dirent->d_ino);
-       put_user(offset, &dirent->d_offset);
-       put_user(namlen, &dirent->d_namlen);
-       copy_to_user(dirent->d_name, name, namlen);
-       put_user(0, dirent->d_name + namlen);
-       return 0;
-}
-
-asmlinkage long old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count)
-{
-       int error = -EBADF;
-       struct file * file;
-       struct readdir_callback32 buf;
-
-       file = fget(fd);
-       if (!file)
-               goto out;
-
-       buf.count = 0;
-       buf.dirent = dirent;
-
-       error = vfs_readdir(file, fillonedir, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.count;
-
-out_putf:
-       fput(file);
-out:
-       return error;
-}
-
-struct linux_dirent32 {
-       u32             d_ino;
-       u32             d_off;
-       unsigned short  d_reclen;
-       char            d_name[1];
-};
-
-struct getdents_callback32 {
-       struct linux_dirent32 __user *current_dir;
-       struct linux_dirent32 __user *previous;
-       int count;
-       int error;
-};
-
-static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
-                  unsigned int d_type)
-{
-       struct linux_dirent32 __user * dirent;
-       struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
-       int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
-
-       buf->error = -EINVAL;   /* only used if we fail.. */
-       if (reclen > buf->count)
-               return -EINVAL;
-       dirent = buf->previous;
-       if (dirent)
-               put_user(offset, &dirent->d_off);
-       dirent = buf->current_dir;
-       buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
-       put_user(reclen, &dirent->d_reclen);
-       copy_to_user(dirent->d_name, name, namlen);
-       put_user(0, dirent->d_name + namlen);
-       put_user(d_type, (char __user *) dirent + reclen - 1);
-       dirent = (void __user *) dirent + reclen;
-       buf->current_dir = dirent;
-       buf->count -= reclen;
-       return 0;
-}
-
-asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent, unsigned int count)
-{
-       struct file * file;
-       struct linux_dirent32 __user *lastdirent;
-       struct getdents_callback32 buf;
-       int error = -EBADF;
-
-       file = fget(fd);
-       if (!file)
-               goto out;
-
-       buf.current_dir = dirent;
-       buf.previous = NULL;
-       buf.count = count;
-       buf.error = 0;
-
-       error = vfs_readdir(file, filldir, &buf);
-       if (error < 0)
-               goto out_putf;
-       lastdirent = buf.previous;
-       error = buf.error;
-       if (lastdirent) {
-               put_user(file->f_pos, &lastdirent->d_off);
-               error = count - buf.count;
-       }
-out_putf:
-       fput(file);
-out:
-       return error;
-}
-
-/* end of readdir & getdents */
-
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
        int err;
@@ -1177,7 +1045,7 @@ asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
 }
 
 asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese,
-                                     siginfo_t32 __user *uinfo,
+                                     struct siginfo32 __user *uinfo,
                                      struct compat_timespec __user *uts,
                                      compat_size_t sigsetsize)
 {
@@ -1262,15 +1130,15 @@ asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese,
 }
 
 asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
-                                          siginfo_t32 __user *uinfo)
+                                          struct siginfo32 __user *uinfo)
 {
        siginfo_t info;
        int ret;
        mm_segment_t old_fs = get_fs();
        
-       if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
-           copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
+       if (copy_siginfo_to_kernel32(&info, uinfo))
                return -EFAULT;
+
        set_fs (KERNEL_DS);
        ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
        set_fs (old_fs);
@@ -1293,9 +1161,9 @@ asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act
                u32 u_handler, u_restorer;
                
                ret = get_user(u_handler, &act->sa_handler);
-               new_ka.sa.sa_handler = (void *) (long) u_handler;
+               new_ka.sa.sa_handler =  compat_ptr(u_handler);
                ret |= __get_user(u_restorer, &act->sa_restorer);
-               new_ka.sa.sa_restorer = (void *) (long) u_restorer;
+               new_ka.sa.sa_restorer = compat_ptr(u_restorer);
                ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
                ret |= __get_user(mask, &act->sa_mask);
                if (ret)
@@ -1340,7 +1208,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
 
                new_ka.ka_restorer = restorer;
                ret = get_user(u_handler, &act->sa_handler);
-               new_ka.sa.sa_handler = (void *) (long) u_handler;
+               new_ka.sa.sa_handler =  compat_ptr(u_handler);
                ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
                switch (_NSIG_WORDS) {
                case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
@@ -1350,7 +1218,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
                }
                ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
                ret |= __get_user(u_restorer, &act->sa_restorer);
-               new_ka.sa.sa_restorer = (void *) (long) u_restorer;
+               new_ka.sa.sa_restorer = compat_ptr(u_restorer);
                 if (ret)
                        return -EFAULT;
        }
@@ -1868,3 +1736,33 @@ sys32_timer_create(u32 clock, struct sigevent32 __user *se32,
        return err;
 }
 
+asmlinkage long compat_sys_waitid(u32 which, u32 pid,
+                                 struct siginfo32 __user *uinfo, u32 options,
+                                 struct compat_rusage __user *uru)
+{
+       siginfo_t info;
+       struct rusage ru;
+       long ret;
+       mm_segment_t old_fs = get_fs();
+
+       memset(&info, 0, sizeof(info));
+
+       set_fs (KERNEL_DS);
+       ret = sys_waitid(which, pid, (siginfo_t __user *) &info,
+                        options,
+                        uru ? (struct rusage __user *) &ru : NULL);
+       set_fs (old_fs);
+
+       if (ret < 0 || info.si_signo == 0)
+               return ret;
+
+       if (uru) {
+               ret = put_compat_rusage(&ru, uru);
+               if (ret)
+                       return ret;
+       }
+
+       BUG_ON(info.si_code & __SI_MASK);
+       info.si_code |= __SI_CHLD;
+       return copy_siginfo_to_user32(uinfo, &info);
+}