Author: kib
Date: Fri Aug  9 06:25:31 2013
New Revision: 254128
URL: http://svnweb.freebsd.org/changeset/base/254128

Log:
  MFC r253529:
  Wrap kmq_notify(2) for compat32 to properly consume struct sigevent32
  argument.

Modified:
  stable/9/sys/compat/freebsd32/syscalls.master
  stable/9/sys/kern/uipc_mqueue.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/compat/freebsd32/syscalls.master
==============================================================================
--- stable/9/sys/compat/freebsd32/syscalls.master       Fri Aug  9 06:23:22 
2013        (r254127)
+++ stable/9/sys/compat/freebsd32/syscalls.master       Fri Aug  9 06:25:31 
2013        (r254128)
@@ -820,8 +820,8 @@
                                    const char *msg_ptr, size_t msg_len,\
                                    unsigned msg_prio,                  \
                                    const struct timespec32 *abs_timeout);}
-461    AUE_NULL        NOPROTO|NOSTD   { int kmq_notify(int mqd,       \
-                                   const struct sigevent *sigev); }
+461    AUE_NULL        NOSTD   { int freebsd32_kmq_notify(int mqd,     \
+                                   const struct sigevent32 *sigev); }
 462    AUE_NULL        NOPROTO|NOSTD   { int kmq_unlink(const char *path); }
 463    AUE_NULL        NOPROTO { int abort2(const char *why, int nargs, void 
**args); }
 464    AUE_NULL        NOPROTO { int thr_set_name(long id, const char *name); }

Modified: stable/9/sys/kern/uipc_mqueue.c
==============================================================================
--- stable/9/sys/kern/uipc_mqueue.c     Fri Aug  9 06:23:22 2013        
(r254127)
+++ stable/9/sys/kern/uipc_mqueue.c     Fri Aug  9 06:25:31 2013        
(r254128)
@@ -2235,10 +2235,9 @@ sys_kmq_timedsend(struct thread *td, str
        return (error);
 }
 
-int
-sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
+static int
+kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
 {
-       struct sigevent ev;
        struct filedesc *fdp;
        struct proc *p;
        struct mqueue *mq;
@@ -2246,27 +2245,24 @@ sys_kmq_notify(struct thread *td, struct
        struct mqueue_notifier *nt, *newnt = NULL;
        int error;
 
-       p = td->td_proc;
-       fdp = td->td_proc->p_fd;
-       if (uap->sigev) {
-               error = copyin(uap->sigev, &ev, sizeof(ev));
-               if (error)
-                       return (error);
-               if (ev.sigev_notify != SIGEV_SIGNAL &&
-                   ev.sigev_notify != SIGEV_THREAD_ID &&
-                   ev.sigev_notify != SIGEV_NONE)
+       if (sigev != NULL) {
+               if (sigev->sigev_notify != SIGEV_SIGNAL &&
+                   sigev->sigev_notify != SIGEV_THREAD_ID &&
+                   sigev->sigev_notify != SIGEV_NONE)
                        return (EINVAL);
-               if ((ev.sigev_notify == SIGEV_SIGNAL ||
-                    ev.sigev_notify == SIGEV_THREAD_ID) &&
-                       !_SIG_VALID(ev.sigev_signo))
+               if ((sigev->sigev_notify == SIGEV_SIGNAL ||
+                   sigev->sigev_notify == SIGEV_THREAD_ID) &&
+                   !_SIG_VALID(sigev->sigev_signo))
                        return (EINVAL);
        }
-       error = getmq(td, uap->mqd, &fp, NULL, &mq);
+       p = td->td_proc;
+       fdp = td->td_proc->p_fd;
+       error = getmq(td, mqd, &fp, NULL, &mq);
        if (error)
                return (error);
 again:
        FILEDESC_SLOCK(fdp);
-       fp2 = fget_locked(fdp, uap->mqd);
+       fp2 = fget_locked(fdp, mqd);
        if (fp2 == NULL) {
                FILEDESC_SUNLOCK(fdp);
                error = EBADF;
@@ -2284,12 +2280,12 @@ again:
        }
        mtx_lock(&mq->mq_mutex);
        FILEDESC_SUNLOCK(fdp);
-       if (uap->sigev != NULL) {
+       if (sigev != NULL) {
                if (mq->mq_notifier != NULL) {
                        error = EBUSY;
                } else {
                        PROC_LOCK(p);
-                       nt = notifier_search(p, uap->mqd);
+                       nt = notifier_search(p, mqd);
                        if (nt == NULL) {
                                if (newnt == NULL) {
                                        PROC_UNLOCK(p);
@@ -2312,10 +2308,10 @@ again:
                                nt->nt_ksi.ksi_flags |= KSI_INS | KSI_EXT;
                                nt->nt_ksi.ksi_code = SI_MESGQ;
                                nt->nt_proc = p;
-                               nt->nt_ksi.ksi_mqd = uap->mqd;
+                               nt->nt_ksi.ksi_mqd = mqd;
                                notifier_insert(p, nt);
                        }
-                       nt->nt_sigev = ev;
+                       nt->nt_sigev = *sigev;
                        mq->mq_notifier = nt;
                        PROC_UNLOCK(p);
                        /*
@@ -2328,7 +2324,7 @@ again:
                                mqueue_send_notification(mq);
                }
        } else {
-               notifier_remove(p, mq, uap->mqd);
+               notifier_remove(p, mq, mqd);
        }
        mtx_unlock(&mq->mq_mutex);
 
@@ -2339,6 +2335,23 @@ out:
        return (error);
 }
 
+int
+sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
+{
+       struct sigevent ev, *evp;
+       int error;
+
+       if (uap->sigev == NULL) {
+               evp = NULL;
+       } else {
+               error = copyin(uap->sigev, &ev, sizeof(ev));
+               if (error != 0)
+                       return (error);
+               evp = &ev;
+       }
+       return (kern_kmq_notify(td, uap->mqd, evp));
+}
+
 static void
 mqueue_fdclose(struct thread *td, int fd, struct file *fp)
 {
@@ -2635,6 +2648,7 @@ static struct syscall_helper_data mq_sys
 #ifdef COMPAT_FREEBSD32
 #include <compat/freebsd32/freebsd32.h>
 #include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
 #include <compat/freebsd32/freebsd32_syscall.h>
 #include <compat/freebsd32/freebsd32_util.h>
 
@@ -2761,12 +2775,33 @@ freebsd32_kmq_timedreceive(struct thread
        return (error);
 }
 
+int
+freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *uap)
+{
+       struct sigevent ev, *evp;
+       struct sigevent32 ev32;
+       int error;
+
+       if (uap->sigev == NULL) {
+               evp = NULL;
+       } else {
+               error = copyin(uap->sigev, &ev32, sizeof(ev32));
+               if (error != 0)
+                       return (error);
+               error = convert_sigevent32(&ev32, &ev);
+               if (error != 0)
+                       return (error);
+               evp = &ev;
+       }
+       return (kern_kmq_notify(td, uap->mqd, evp));
+}
+
 static struct syscall_helper_data mq32_syscalls[] = {
        SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
        SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
        SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
        SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
-       SYSCALL32_INIT_HELPER_COMPAT(kmq_notify),
+       SYSCALL32_INIT_HELPER(freebsd32_kmq_notify),
        SYSCALL32_INIT_HELPER_COMPAT(kmq_unlink),
        SYSCALL_INIT_LAST
 };
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to