mqueue: Introduce kern_kmq_timedreceive & kern_kmq_timedsend

Reviewed by: imp, kib
Pull Request: https://github.com/freebsd/freebsd-src/pull/1248
This commit is contained in:
Ricardo Branco 2024-05-18 17:19:39 +02:00 committed by Warner Losh
parent 289b2d6a79
commit e30621d58f
3 changed files with 63 additions and 59 deletions

View file

@ -2275,29 +2275,57 @@ sys_kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
}
int
sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
kern_kmq_timedreceive(struct thread *td, int mqd, char *msg_ptr,
size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout)
{
struct mqueue *mq;
struct file *fp;
int error, waitok;
AUDIT_ARG_FD(mqd);
error = getmq_read(td, mqd, &fp, NULL, &mq);
if (error != 0)
return (error);
waitok = (fp->f_flag & O_NONBLOCK) == 0;
error = mqueue_receive(mq, msg_ptr, msg_len, msg_prio, waitok,
abs_timeout);
fdrop(fp, td);
return (error);
}
int
sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
{
struct timespec *abs_timeout, ets;
int error;
int waitok;
AUDIT_ARG_FD(uap->mqd);
error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
if (uap->abs_timeout != NULL) {
error = copyin(uap->abs_timeout, &ets, sizeof(ets));
if (error != 0)
goto out;
return (error);
abs_timeout = &ets;
} else
abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
uap->msg_prio, waitok, abs_timeout);
out:
return (kern_kmq_timedreceive(td, uap->mqd, uap->msg_ptr, uap->msg_len,
uap->msg_prio, abs_timeout));
}
int
kern_kmq_timedsend(struct thread *td, int mqd, const char *msg_ptr,
size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
{
struct mqueue *mq;
struct file *fp;
int error, waitok;
AUDIT_ARG_FD(mqd);
error = getmq_write(td, mqd, &fp, NULL, &mq);
if (error != 0)
return (error);
waitok = (fp->f_flag & O_NONBLOCK) == 0;
error = mqueue_send(mq, msg_ptr, msg_len, msg_prio, waitok,
abs_timeout);
fdrop(fp, td);
return (error);
}
@ -2305,28 +2333,19 @@ sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
int
sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
{
struct mqueue *mq;
struct file *fp;
struct timespec *abs_timeout, ets;
int error, waitok;
int error;
AUDIT_ARG_FD(uap->mqd);
error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
if (uap->abs_timeout != NULL) {
error = copyin(uap->abs_timeout, &ets, sizeof(ets));
if (error != 0)
goto out;
return (error);
abs_timeout = &ets;
} else
abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
uap->msg_prio, waitok, abs_timeout);
out:
fdrop(fp, td);
return (error);
return (kern_kmq_timedsend(td, uap->mqd, uap->msg_ptr, uap->msg_len,
uap->msg_prio, abs_timeout));
}
int
@ -2801,63 +2820,44 @@ int
freebsd32_kmq_timedsend(struct thread *td,
struct freebsd32_kmq_timedsend_args *uap)
{
struct mqueue *mq;
struct file *fp;
struct timespec32 ets32;
struct timespec *abs_timeout, ets;
int error;
int waitok;
AUDIT_ARG_FD(uap->mqd);
error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
if (uap->abs_timeout != NULL) {
error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
if (error != 0)
goto out;
return (error);
CP(ets32, ets, tv_sec);
CP(ets32, ets, tv_nsec);
abs_timeout = &ets;
} else
abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
uap->msg_prio, waitok, abs_timeout);
out:
fdrop(fp, td);
return (error);
return (kern_kmq_timedsend(td, uap->mqd, uap->msg_ptr, uap->msg_len,
uap->msg_prio, abs_timeout));
}
int
freebsd32_kmq_timedreceive(struct thread *td,
struct freebsd32_kmq_timedreceive_args *uap)
{
struct mqueue *mq;
struct file *fp;
struct timespec32 ets32;
struct timespec *abs_timeout, ets;
int error, waitok;
int error;
AUDIT_ARG_FD(uap->mqd);
error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
if (uap->abs_timeout != NULL) {
error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
if (error != 0)
goto out;
return (error);
CP(ets32, ets, tv_sec);
CP(ets32, ets, tv_nsec);
abs_timeout = &ets;
} else
abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
uap->msg_prio, waitok, abs_timeout);
out:
fdrop(fp, td);
return (error);
return (kern_kmq_timedreceive(td, uap->mqd, uap->msg_ptr, uap->msg_len,
uap->msg_prio, abs_timeout));
}
int

View file

@ -38,14 +38,8 @@ struct mq_attr {
};
#ifdef _KERNEL
struct sigevent;
struct thread;
struct file;
extern void (*mq_fdclose)(struct thread *td, int fd, struct file *fp);
int kern_kmq_notify(struct thread *, int, struct sigevent *);
int kern_kmq_open(struct thread *, const char *, int, mode_t,
const struct mq_attr *);
int kern_kmq_setattr(struct thread *, int, const struct mq_attr *,
struct mq_attr *);
#endif
#endif

View file

@ -49,6 +49,7 @@ struct kevent_copyops;
struct kld_file_stat;
struct ksiginfo;
struct mbuf;
struct mq_attr;
struct msghdr;
struct msqid_ds;
struct pollfd;
@ -385,6 +386,15 @@ int kern_writev(struct thread *td, int fd, struct uio *auio);
int kern_socketpair(struct thread *td, int domain, int type, int protocol,
int *rsv);
int kern_unmount(struct thread *td, const char *path, int flags);
int kern_kmq_notify(struct thread *, int, struct sigevent *);
int kern_kmq_open(struct thread *, const char *, int, mode_t,
const struct mq_attr *);
int kern_kmq_setattr(struct thread *, int, const struct mq_attr *,
struct mq_attr *);
int kern_kmq_timedreceive(struct thread *, int, char *,
size_t, unsigned int *, const struct timespec *);
int kern_kmq_timedsend(struct thread *td, int, const char *,
size_t, unsigned int, const struct timespec *);
/* flags for kern_sigaction */
#define KSA_OSIGSET 0x0001 /* uses osigact_t */