]> git.hungrycats.org Git - linux/commitdiff
[SPARC]: Add sys_waitid support.
authorDavid S. Miller <davem@nuts.davemloft.net>
Tue, 31 Aug 2004 11:06:08 +0000 (04:06 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Tue, 31 Aug 2004 11:06:08 +0000 (04:06 -0700)
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/kernel/systbls.S
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
include/asm-sparc/unistd.h
include/asm-sparc64/siginfo.h
include/asm-sparc64/unistd.h

index fd452a6d3b71100ba08a779eb2b8f29d9896f2f8..288a0b44b8480ad879ef775ec86c9d8c78899378 100644 (file)
@@ -74,7 +74,7 @@ sys_call_table:
 /*260*/        .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
 /*265*/        .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
 /*270*/        .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
-/*275*/        .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_ni_syscall
+/*275*/        .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
 /*280*/        .long sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
 
 #ifdef CONFIG_SUNOS_EMUL
index 3333571e736a42f19659e3c362c6dd273db6d51b..f8bf70233fe74b7a82ea6401ffd911f8c5f6f917 100644 (file)
@@ -86,9 +86,62 @@ struct new_signal_frame32 {
        __siginfo_fpu_t         fpu_state;
 };
 
+struct siginfo32 {
+       int si_signo;
+       int si_errno;
+       int si_code;
+
+       union {
+               int _pad[SI_PAD_SIZE32];
+
+               /* kill() */
+               struct {
+                       compat_pid_t _pid;              /* sender's pid */
+                       unsigned int _uid;              /* sender's uid */
+               } _kill;
+
+               /* POSIX.1b timers */
+               struct {
+                       timer_t _tid;                   /* timer id */
+                       int _overrun;                   /* overrun count */
+                       sigval_t32 _sigval;             /* same as below */
+                       int _sys_private;               /* not to be passed to user */
+               } _timer;
+
+               /* POSIX.1b signals */
+               struct {
+                       compat_pid_t _pid;              /* sender's pid */
+                       unsigned int _uid;              /* sender's uid */
+                       sigval_t32 _sigval;
+               } _rt;
+
+               /* SIGCHLD */
+               struct {
+                       compat_pid_t _pid;              /* which child */
+                       unsigned int _uid;              /* sender's uid */
+                       int _status;                    /* exit code */
+                       compat_clock_t _utime;
+                       compat_clock_t _stime;
+                       struct compat_rusage _rusage;
+               } _sigchld;
+
+               /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
+               struct {
+                       u32 _addr; /* faulting insn/memory ref. */
+                       int _trapno;
+               } _sigfault;
+
+               /* SIGPOLL */
+               struct {
+                       int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
+                       int _fd;
+               } _sigpoll;
+       } _sifields;
+};
+
 struct rt_signal_frame32 {
        struct sparc_stackf32   ss;
-       siginfo_t32             info;
+       struct siginfo32        info;
        struct pt_regs32        regs;
        compat_sigset_t         mask;
        /* __siginfo_fpu32_t * */ u32 fpu_save;
@@ -105,11 +158,11 @@ struct rt_signal_frame32 {
 #define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame32) + 7) & (~7)))
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
 
-int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
+int copy_siginfo_to_user32(struct siginfo32 __user *to, siginfo_t *from)
 {
        int err;
 
-       if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t32)))
+       if (!access_ok(VERIFY_WRITE, to, sizeof(struct siginfo32)))
                return -EFAULT;
 
        /* If you change siginfo_t structure, please be sure
@@ -135,6 +188,8 @@ int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
                        err |= __put_user(from->si_utime, &to->si_utime);
                        err |= __put_user(from->si_stime, &to->si_stime);
                        err |= __put_user(from->si_status, &to->si_status);
+                       err |= put_compat_rusage(&from->si_rusage,
+                                                &to->si_rusage);
                default:
                        err |= __put_user(from->si_pid, &to->si_pid);
                        err |= __put_user(from->si_uid, &to->si_uid);
@@ -155,6 +210,22 @@ int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
        return err;
 }
 
+/* CAUTION: This is just a very minimalist implementation for the
+ *          sake of compat_sys_rt_sigqueueinfo()
+ */
+int copy_siginfo_to_kernel32(siginfo_t *to, struct siginfo32 __user *from)
+{
+       if (!access_ok(VERIFY_WRITE, from, sizeof(struct siginfo32)))
+               return -EFAULT;
+
+       if (copy_from_user(to, from, 3*sizeof(int)) ||
+           copy_from_user(to->_sifields._pad, from->_sifields._pad,
+                          SI_PAD_SIZE))
+               return -EFAULT;
+
+       return 0;
+}
+
 /*
  * atomically swap in the new signal mask, and wait for a signal.
  * This is really tricky on the Sparc, watch out...
index 56e277383c36d23f54720502d3d0bc56a1662c56..80d65ffc006677df3cf9bbdb9a9527c1ee8063de 100644 (file)
@@ -1045,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)
 {
@@ -1130,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);
@@ -1736,3 +1736,23 @@ 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)
+{
+       siginfo_t info;
+       long ret;
+       mm_segment_t old_fs = get_fs();
+
+       memset(&info, 0, sizeof(info));
+
+       set_fs (KERNEL_DS);
+       ret = sys_waitid((int)which, (compat_pid_t) pid,
+                        (siginfo_t __user *) &info, (int) options);
+       set_fs (old_fs);
+
+       if (ret < 0 || info.si_signo == 0)
+               return ret;
+       BUG_ON(info.si_code & __SI_MASK);
+       info.si_code |= __SI_CHLD;
+       return copy_siginfo_to_user32(uinfo, &info);
+}
index a937ab7075019e188fb6777258c3869ca59fb6d5..8fe732b3447f13458f4ef78d7d55558c57ff8da0 100644 (file)
@@ -75,7 +75,7 @@ sys_call_table32:
 /*260*/        .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_timer_gettime, sys_timer_getoverrun
        .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
 /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
-       .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, sys_ni_syscall
+       .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
 /*280*/        .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
 
 #endif /* CONFIG_COMPAT */
@@ -141,7 +141,7 @@ sys_call_table:
 /*260*/        .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
        .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
 /*270*/        .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
-       .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_ni_syscall
+       .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
 /*280*/        .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
index 62eaacd9fe2f5fda0c8bc03bdd75758fc318eb3b..f73f7e6601907c122d9137cb3360d84621e0e7a7 100644 (file)
 #define __NR_io_cancel         271
 #define __NR_io_getevents      272
 #define __NR_mq_open           273
-#define __NR_mq_unlink         (__NR_mq_open+1)
-#define __NR_mq_timedsend      (__NR_mq_open+2)
-#define __NR_mq_timedreceive   (__NR_mq_open+3)
-#define __NR_mq_notify         (__NR_mq_open+4)
-#define __NR_mq_getsetattr     (__NR_mq_open+5)
+#define __NR_mq_unlink         274
+#define __NR_mq_timedsend      275
+#define __NR_mq_timedreceive   276
+#define __NR_mq_notify         277
+#define __NR_mq_getsetattr     278
+#define __NR_waitid            279
 
 /* WARNING: You MAY NOT add syscall numbers larger than 282, since
  *          all of the syscall tables in the Sparc kernel are
index fde85211a008ec067df41f71457e9a94df4fda3d..94b272f5d1b3726ddce9fe6934e56c64d3cf162c 100644 (file)
@@ -24,57 +24,8 @@ typedef union sigval32 {
        u32 sival_ptr;
 } sigval_t32;
 
-typedef struct siginfo32 {
-       int si_signo;
-       int si_errno;
-       int si_code;
+struct siginfo32;
 
-       union {
-               int _pad[SI_PAD_SIZE32];
-
-               /* kill() */
-               struct {
-                       compat_pid_t _pid;              /* sender's pid */
-                       unsigned int _uid;              /* sender's uid */
-               } _kill;
-
-               /* POSIX.1b timers */
-               struct {
-                       timer_t _tid;                   /* timer id */
-                       int _overrun;                   /* overrun count */
-                       sigval_t32 _sigval;             /* same as below */
-                       int _sys_private;               /* not to be passed to user */
-               } _timer;
-
-               /* POSIX.1b signals */
-               struct {
-                       compat_pid_t _pid;              /* sender's pid */
-                       unsigned int _uid;              /* sender's uid */
-                       sigval_t32 _sigval;
-               } _rt;
-
-               /* SIGCHLD */
-               struct {
-                       compat_pid_t _pid;              /* which child */
-                       unsigned int _uid;              /* sender's uid */
-                       int _status;                    /* exit code */
-                       compat_clock_t _utime;
-                       compat_clock_t _stime;
-               } _sigchld;
-
-               /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
-               struct {
-                       u32 _addr; /* faulting insn/memory ref. */
-                       int _trapno;
-               } _sigfault;
-
-               /* SIGPOLL */
-               struct {
-                       int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
-                       int _fd;
-               } _sigpoll;
-       } _sifields;
-} siginfo_t32;
 #endif /* CONFIG_COMPAT */
 
 #endif /* __KERNEL__ */
@@ -105,7 +56,8 @@ typedef struct sigevent32 {
        } _sigev_un;
 } sigevent_t32;
 
-extern int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from);
+extern int copy_siginfo_to_user32(struct siginfo32 __user *to, siginfo_t *from);
+extern int copy_siginfo_to_kernel32(siginfo_t *to, struct siginfo32 __user *from);
 
 #endif /* CONFIG_COMPAT */
 
index 0ce57c1b46e9c45f289249cc6962a08fe1a785b4..645cf7208e8ec45bf312c0be69a5a8256dfb17ed 100644 (file)
 #define __NR_io_cancel         271
 #define __NR_io_getevents      272
 #define __NR_mq_open           273
-#define __NR_mq_unlink         (__NR_mq_open+1)
-#define __NR_mq_timedsend      (__NR_mq_open+2)
-#define __NR_mq_timedreceive   (__NR_mq_open+3)
-#define __NR_mq_notify         (__NR_mq_open+4)
-#define __NR_mq_getsetattr     (__NR_mq_open+5)
+#define __NR_mq_unlink         274
+#define __NR_mq_timedsend      275
+#define __NR_mq_timedreceive   276
+#define __NR_mq_notify         277
+#define __NR_mq_getsetattr     278
+#define __NR_waitid            279
+
 /* WARNING: You MAY NOT add syscall numbers larger than 282, since
  *          all of the syscall tables in the Sparc kernel are
  *          sized to have 283 entries (starting at zero).  Therefore