diff options
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 4 | ||||
-rw-r--r-- | sys/kern/uipc_mqueue.c | 83 |
2 files changed, 61 insertions, 26 deletions
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index d9a73d9..e058f6a 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -825,8 +825,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); } diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 73579d3..11acedb 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2235,10 +2235,9 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap) 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,34 +2245,31 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap) 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; goto out; } #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, uap->mqd), CAP_POLL_EVENT); + error = cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT); if (error) { FILEDESC_SUNLOCK(fdp); goto out; @@ -2286,12 +2282,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); @@ -2314,10 +2310,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); /* @@ -2330,7 +2326,7 @@ again: mqueue_send_notification(mq); } } else { - notifier_remove(p, mq, uap->mqd); + notifier_remove(p, mq, mqd); } mtx_unlock(&mq->mq_mutex); @@ -2341,6 +2337,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) { @@ -2637,6 +2650,7 @@ static struct syscall_helper_data mq_syscalls[] = { #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> @@ -2763,12 +2777,33 @@ freebsd32_kmq_timedreceive(struct thread *td, 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 }; |