Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Jul 2013 19:40:31 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253529 - in head/sys: compat/freebsd32 kern
Message-ID:  <201307211940.r6LJeVMs052054@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Jul 21 19:40:30 2013
New Revision: 253529
URL: http://svnweb.freebsd.org/changeset/base/253529

Log:
  Wrap kmq_notify(2) for compat32 to properly consume struct sigevent32
  argument.
  
  Reviewed and tested by:	Petr Salinger <Petr.Salinger@seznam.cz>
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/compat/freebsd32/syscalls.master
  head/sys/kern/uipc_mqueue.c

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Sun Jul 21 19:36:53 2013	(r253528)
+++ head/sys/compat/freebsd32/syscalls.master	Sun Jul 21 19:40:30 2013	(r253529)
@@ -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); }

Modified: head/sys/kern/uipc_mqueue.c
==============================================================================
--- head/sys/kern/uipc_mqueue.c	Sun Jul 21 19:36:53 2013	(r253528)
+++ head/sys/kern/uipc_mqueue.c	Sun Jul 21 19:40:30 2013	(r253529)
@@ -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,34 +2245,31 @@ 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;
 		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_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>
 
@@ -2763,12 +2777,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
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307211940.r6LJeVMs052054>