Does FreeBSD have sendmmsg or recvmmsg system calls?
Konstantin Belousov
kostikbel at gmail.com
Tue Jan 26 13:40:12 UTC 2016
On Mon, Jan 25, 2016 at 11:22:13AM +0200, Boris Astardzhiev wrote:
> +ssize_t
> +recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags,
> + const struct timespec *__restrict timeout)
> +{
> + size_t i, rcvd;
> + ssize_t ret;
> +
> + if (timeout != NULL) {
> + fd_set fds;
> + int res;
Please move all local definitions to the beginning of the function.
> +
> + FD_ZERO(&fds);
> + FD_SET(s, &fds);
> + res = __sys_pselect(s + 1, &fds, NULL, NULL, timeout, NULL);
So why is this __sys_pselect() and not pselect() ?
Note that ppoll() is immune to the issue of s > FD_SETSIZE.
> + if (res == -1 || res == 0)
> + return (res);
> + if (!FD_ISSET(s, &fds))
> + return (-1);
> + }
> +
> + ret = __sys_recvmsg(s, &msgvec[0].msg_hdr, flags);
> + if (ret == -1)
> + return (ret);
> +
> + /* Check initially for the presence of MSG_WAITFORONE.
> + * Turn on MSG_DONTWAIT if set. */
The style-conformant multi-line comment is
/*
* Text.
* More text.
*/
> + if (flags & MSG_WAITFORONE) {
> + flags |= MSG_DONTWAIT;
> + /* The kernel doesn't need to know about this flag. */
> + flags &= ~MSG_WAITFORONE;
You clear MSG_WAITFORONE flag in the calls to recvmsg(), but not at
the first recvmsg() incantation. I think the flag should be just kept alone.
> + }
> +
> + rcvd = 1;
> + for (i = rcvd; i < vlen; i++, rcvd++) {
> + ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags);
> + if (ret == -1) {
> + /* We have received messages. Let caller know. */
> + return (rcvd);
> + }
> +
> + /* Save received bytes */
> + msgvec[i].msg_len = ret;
> + }
> +
> + return (rcvd);
> +}
> diff --git a/sys/sys/socket.h b/sys/sys/socket.h
> index 18e2de1..c7a21cc 100644
> --- a/sys/sys/socket.h
> +++ b/sys/sys/socket.h
> @@ -431,6 +431,9 @@ struct msghdr {
> #define MSG_NBIO 0x4000 /* FIONBIO mode, used by fifofs */
> #define MSG_COMPAT 0x8000 /* used in sendit() */
> #define MSG_CMSG_CLOEXEC 0x40000 /* make received fds close-on-exec */
> +#ifndef _KERNEL
Why is the !KERNEL protection for the definition needed ?
> +#define MSG_WAITFORONE 0x80000 /* for recvmmsg() */
> +#endif /* !_KERNEL */
> #endif
> #ifdef _KERNEL
> #define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */
> @@ -595,6 +598,18 @@ struct sf_hdtr {
> #endif /* _KERNEL */
> #endif /* __BSD_VISIBLE */
>
> +#ifndef _KERNEL
Why is the !KERNEL protection for the definition needed ?
> +#ifdef __BSD_VISIBLE
> +/*
> + * Send/recvmmsg specific structure(s)
> + */
> +struct mmsghdr {
> + struct msghdr msg_hdr; /* message header */
> + ssize_t msg_len; /* message length */
> +};
> +#endif /* __BSD_VISIBLE */
> +#endif /* !_KERNEL */
> +
> #ifndef _KERNEL
>
> #include <sys/cdefs.h>
> @@ -615,11 +630,19 @@ int listen(int, int);
> ssize_t recv(int, void *, size_t, int);
> ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
> ssize_t recvmsg(int, struct msghdr *, int);
> +#if __BSD_VISIBLE
> +struct timespec;
> +ssize_t recvmmsg(int, struct mmsghdr * __restrict, size_t, int,
> + const struct timespec * __restrict);
> +#endif
> ssize_t send(int, const void *, size_t, int);
> ssize_t sendto(int, const void *,
> size_t, int, const struct sockaddr *, socklen_t);
> ssize_t sendmsg(int, const struct msghdr *, int);
> #if __BSD_VISIBLE
> +ssize_t sendmmsg(int, struct mmsghdr * __restrict, size_t, int);
> +#endif
> +#if __BSD_VISIBLE
Again, there is no use in closing __BSD_VISIBLE block only to open
it again on the next line.
> int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
> int setfib(int);
> #endif
More information about the freebsd-net
mailing list