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 --- |