uipc_mqueue.c (552311f4bb98c81b1b9e0e81d74e0262fc12110b) uipc_mqueue.c (058262c69aa65e1967048c3d5dad15db1e84add4)
1/*-
2 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 2221 unchanged lines hidden (view full) ---

2230 abs_timeout = NULL;
2231 waitok = !(fp->f_flag & O_NONBLOCK);
2232 error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
2233 uap->msg_prio, waitok, abs_timeout);
2234 fdrop(fp, td);
2235 return (error);
2236}
2237
1/*-
2 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 2221 unchanged lines hidden (view full) ---

2230 abs_timeout = NULL;
2231 waitok = !(fp->f_flag & O_NONBLOCK);
2232 error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
2233 uap->msg_prio, waitok, abs_timeout);
2234 fdrop(fp, td);
2235 return (error);
2236}
2237
2238int
2239sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
2238static int
2239kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
2240{
2240{
2241 struct sigevent ev;
2242 struct filedesc *fdp;
2243 struct proc *p;
2244 struct mqueue *mq;
2245 struct file *fp, *fp2;
2246 struct mqueue_notifier *nt, *newnt = NULL;
2247 int error;
2248
2241 struct filedesc *fdp;
2242 struct proc *p;
2243 struct mqueue *mq;
2244 struct file *fp, *fp2;
2245 struct mqueue_notifier *nt, *newnt = NULL;
2246 int error;
2247
2249 p = td->td_proc;
2250 fdp = td->td_proc->p_fd;
2251 if (uap->sigev) {
2252 error = copyin(uap->sigev, &ev, sizeof(ev));
2253 if (error)
2254 return (error);
2255 if (ev.sigev_notify != SIGEV_SIGNAL &&
2256 ev.sigev_notify != SIGEV_THREAD_ID &&
2257 ev.sigev_notify != SIGEV_NONE)
2248 if (sigev != NULL) {
2249 if (sigev->sigev_notify != SIGEV_SIGNAL &&
2250 sigev->sigev_notify != SIGEV_THREAD_ID &&
2251 sigev->sigev_notify != SIGEV_NONE)
2258 return (EINVAL);
2252 return (EINVAL);
2259 if ((ev.sigev_notify == SIGEV_SIGNAL ||
2260 ev.sigev_notify == SIGEV_THREAD_ID) &&
2261 !_SIG_VALID(ev.sigev_signo))
2253 if ((sigev->sigev_notify == SIGEV_SIGNAL ||
2254 sigev->sigev_notify == SIGEV_THREAD_ID) &&
2255 !_SIG_VALID(sigev->sigev_signo))
2262 return (EINVAL);
2263 }
2256 return (EINVAL);
2257 }
2264 error = getmq(td, uap->mqd, &fp, NULL, &mq);
2258 p = td->td_proc;
2259 fdp = td->td_proc->p_fd;
2260 error = getmq(td, mqd, &fp, NULL, &mq);
2265 if (error)
2266 return (error);
2267again:
2268 FILEDESC_SLOCK(fdp);
2261 if (error)
2262 return (error);
2263again:
2264 FILEDESC_SLOCK(fdp);
2269 fp2 = fget_locked(fdp, uap->mqd);
2265 fp2 = fget_locked(fdp, mqd);
2270 if (fp2 == NULL) {
2271 FILEDESC_SUNLOCK(fdp);
2272 error = EBADF;
2273 goto out;
2274 }
2275#ifdef CAPABILITIES
2266 if (fp2 == NULL) {
2267 FILEDESC_SUNLOCK(fdp);
2268 error = EBADF;
2269 goto out;
2270 }
2271#ifdef CAPABILITIES
2276 error = cap_check(cap_rights(fdp, uap->mqd), CAP_POLL_EVENT);
2272 error = cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT);
2277 if (error) {
2278 FILEDESC_SUNLOCK(fdp);
2279 goto out;
2280 }
2281#endif
2282 if (fp2 != fp) {
2283 FILEDESC_SUNLOCK(fdp);
2284 error = EBADF;
2285 goto out;
2286 }
2287 mtx_lock(&mq->mq_mutex);
2288 FILEDESC_SUNLOCK(fdp);
2273 if (error) {
2274 FILEDESC_SUNLOCK(fdp);
2275 goto out;
2276 }
2277#endif
2278 if (fp2 != fp) {
2279 FILEDESC_SUNLOCK(fdp);
2280 error = EBADF;
2281 goto out;
2282 }
2283 mtx_lock(&mq->mq_mutex);
2284 FILEDESC_SUNLOCK(fdp);
2289 if (uap->sigev != NULL) {
2285 if (sigev != NULL) {
2290 if (mq->mq_notifier != NULL) {
2291 error = EBUSY;
2292 } else {
2293 PROC_LOCK(p);
2286 if (mq->mq_notifier != NULL) {
2287 error = EBUSY;
2288 } else {
2289 PROC_LOCK(p);
2294 nt = notifier_search(p, uap->mqd);
2290 nt = notifier_search(p, mqd);
2295 if (nt == NULL) {
2296 if (newnt == NULL) {
2297 PROC_UNLOCK(p);
2298 mtx_unlock(&mq->mq_mutex);
2299 newnt = notifier_alloc();
2300 goto again;
2301 }
2302 }

--- 6 unchanged lines hidden (view full) ---

2309 }
2310 } else {
2311 nt = newnt;
2312 newnt = NULL;
2313 ksiginfo_init(&nt->nt_ksi);
2314 nt->nt_ksi.ksi_flags |= KSI_INS | KSI_EXT;
2315 nt->nt_ksi.ksi_code = SI_MESGQ;
2316 nt->nt_proc = p;
2291 if (nt == NULL) {
2292 if (newnt == NULL) {
2293 PROC_UNLOCK(p);
2294 mtx_unlock(&mq->mq_mutex);
2295 newnt = notifier_alloc();
2296 goto again;
2297 }
2298 }

--- 6 unchanged lines hidden (view full) ---

2305 }
2306 } else {
2307 nt = newnt;
2308 newnt = NULL;
2309 ksiginfo_init(&nt->nt_ksi);
2310 nt->nt_ksi.ksi_flags |= KSI_INS | KSI_EXT;
2311 nt->nt_ksi.ksi_code = SI_MESGQ;
2312 nt->nt_proc = p;
2317 nt->nt_ksi.ksi_mqd = uap->mqd;
2313 nt->nt_ksi.ksi_mqd = mqd;
2318 notifier_insert(p, nt);
2319 }
2314 notifier_insert(p, nt);
2315 }
2320 nt->nt_sigev = ev;
2316 nt->nt_sigev = *sigev;
2321 mq->mq_notifier = nt;
2322 PROC_UNLOCK(p);
2323 /*
2324 * if there is no receivers and message queue
2325 * is not empty, we should send notification
2326 * as soon as possible.
2327 */
2328 if (mq->mq_receivers == 0 &&
2329 !TAILQ_EMPTY(&mq->mq_msgq))
2330 mqueue_send_notification(mq);
2331 }
2332 } else {
2317 mq->mq_notifier = nt;
2318 PROC_UNLOCK(p);
2319 /*
2320 * if there is no receivers and message queue
2321 * is not empty, we should send notification
2322 * as soon as possible.
2323 */
2324 if (mq->mq_receivers == 0 &&
2325 !TAILQ_EMPTY(&mq->mq_msgq))
2326 mqueue_send_notification(mq);
2327 }
2328 } else {
2333 notifier_remove(p, mq, uap->mqd);
2329 notifier_remove(p, mq, mqd);
2334 }
2335 mtx_unlock(&mq->mq_mutex);
2336
2337out:
2338 fdrop(fp, td);
2339 if (newnt != NULL)
2340 notifier_free(newnt);
2341 return (error);
2342}
2343
2330 }
2331 mtx_unlock(&mq->mq_mutex);
2332
2333out:
2334 fdrop(fp, td);
2335 if (newnt != NULL)
2336 notifier_free(newnt);
2337 return (error);
2338}
2339
2340int
2341sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
2342{
2343 struct sigevent ev, *evp;
2344 int error;
2345
2346 if (uap->sigev == NULL) {
2347 evp = NULL;
2348 } else {
2349 error = copyin(uap->sigev, &ev, sizeof(ev));
2350 if (error != 0)
2351 return (error);
2352 evp = &ev;
2353 }
2354 return (kern_kmq_notify(td, uap->mqd, evp));
2355}
2356
2344static void
2345mqueue_fdclose(struct thread *td, int fd, struct file *fp)
2346{
2347 struct filedesc *fdp;
2348 struct mqueue *mq;
2349
2350 fdp = td->td_proc->p_fd;
2351 FILEDESC_LOCK_ASSERT(fdp);

--- 280 unchanged lines hidden (view full) ---

2632 SYSCALL_INIT_HELPER(kmq_notify),
2633 SYSCALL_INIT_HELPER(kmq_unlink),
2634 SYSCALL_INIT_LAST
2635};
2636
2637#ifdef COMPAT_FREEBSD32
2638#include <compat/freebsd32/freebsd32.h>
2639#include <compat/freebsd32/freebsd32_proto.h>
2357static void
2358mqueue_fdclose(struct thread *td, int fd, struct file *fp)
2359{
2360 struct filedesc *fdp;
2361 struct mqueue *mq;
2362
2363 fdp = td->td_proc->p_fd;
2364 FILEDESC_LOCK_ASSERT(fdp);

--- 280 unchanged lines hidden (view full) ---

2645 SYSCALL_INIT_HELPER(kmq_notify),
2646 SYSCALL_INIT_HELPER(kmq_unlink),
2647 SYSCALL_INIT_LAST
2648};
2649
2650#ifdef COMPAT_FREEBSD32
2651#include <compat/freebsd32/freebsd32.h>
2652#include <compat/freebsd32/freebsd32_proto.h>
2653#include <compat/freebsd32/freebsd32_signal.h>
2640#include <compat/freebsd32/freebsd32_syscall.h>
2641#include <compat/freebsd32/freebsd32_util.h>
2642
2643static void
2644mq_attr_from32(const struct mq_attr32 *from, struct mq_attr *to)
2645{
2646
2647 to->mq_flags = from->mq_flags;

--- 110 unchanged lines hidden (view full) ---

2758 abs_timeout = NULL;
2759 waitok = !(fp->f_flag & O_NONBLOCK);
2760 error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
2761 uap->msg_prio, waitok, abs_timeout);
2762 fdrop(fp, td);
2763 return (error);
2764}
2765
2654#include <compat/freebsd32/freebsd32_syscall.h>
2655#include <compat/freebsd32/freebsd32_util.h>
2656
2657static void
2658mq_attr_from32(const struct mq_attr32 *from, struct mq_attr *to)
2659{
2660
2661 to->mq_flags = from->mq_flags;

--- 110 unchanged lines hidden (view full) ---

2772 abs_timeout = NULL;
2773 waitok = !(fp->f_flag & O_NONBLOCK);
2774 error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
2775 uap->msg_prio, waitok, abs_timeout);
2776 fdrop(fp, td);
2777 return (error);
2778}
2779
2780int
2781freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *uap)
2782{
2783 struct sigevent ev, *evp;
2784 struct sigevent32 ev32;
2785 int error;
2786
2787 if (uap->sigev == NULL) {
2788 evp = NULL;
2789 } else {
2790 error = copyin(uap->sigev, &ev32, sizeof(ev32));
2791 if (error != 0)
2792 return (error);
2793 error = convert_sigevent32(&ev32, &ev);
2794 if (error != 0)
2795 return (error);
2796 evp = &ev;
2797 }
2798 return (kern_kmq_notify(td, uap->mqd, evp));
2799}
2800
2766static struct syscall_helper_data mq32_syscalls[] = {
2767 SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
2768 SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
2769 SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
2770 SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
2801static struct syscall_helper_data mq32_syscalls[] = {
2802 SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
2803 SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
2804 SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
2805 SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
2771 SYSCALL32_INIT_HELPER_COMPAT(kmq_notify),
2806 SYSCALL32_INIT_HELPER(freebsd32_kmq_notify),
2772 SYSCALL32_INIT_HELPER_COMPAT(kmq_unlink),
2773 SYSCALL_INIT_LAST
2774};
2775#endif
2776
2777static int
2778mqinit(void)
2779{

--- 55 unchanged lines hidden ---
2807 SYSCALL32_INIT_HELPER_COMPAT(kmq_unlink),
2808 SYSCALL_INIT_LAST
2809};
2810#endif
2811
2812static int
2813mqinit(void)
2814{

--- 55 unchanged lines hidden ---