Hello, I removed the pthread_testcancel() calls and cut the interposing stuff from my patch as suggested. I extended the send/recv(2) manpages regarding the mm calls. Comments and suggestions?
Best regards, Boris Astardzhiev On Mon, Jan 18, 2016 at 4:08 PM, Konstantin Belousov <kostik...@gmail.com> wrote: > On Mon, Jan 18, 2016 at 12:37:01PM +0200, Boris Astardzhiev wrote: > > Hello, > > > > Sorry for the delay of my reply. As far as I understand > pthread_testcancel() > > is not necessary in the recvmmsg syscall since cancellation is not quite > > common > > among apps. But if there is cancellation attempts as long as I use > > __sys_recvmsg() instead > > of the interposing approach on a cancel attempt recvmmsg() will return > > EINTR which will get > > me out? > Yes. > > The corner case is the cancellation attempt (SIGCANCEL == SIGTHR) coming > while the thread is executing code around the syscall. > > > > > Secondly, I guess it's better to use __sys_sendmmsg() similarly instead > of > > the > > insterposing table regarding sendmmsg(). > Sure, sendmmsg and recvmmsg are same. > > > > > Lastly, regarding the manpage - should I extend send/recv(2) for the new > > calls or > > create new manpage files? > IMO it is more logical to extend the existing page than write a new one. >
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h index 739d7b1..c95829e 100644 --- a/lib/libc/include/namespace.h +++ b/lib/libc/include/namespace.h @@ -208,6 +208,7 @@ #define readv _readv #define recvfrom _recvfrom #define recvmsg _recvmsg +#define recvmmsg _recvmmsg #define select _select #define sem_close _sem_close #define sem_destroy _sem_destroy @@ -220,6 +221,7 @@ #define sem_unlink _sem_unlink #define sem_wait _sem_wait #define sendmsg _sendmsg +#define sendmmsg _sendmmsg #define sendto _sendto #define setsockopt _setsockopt /*#define sigaction _sigaction*/ diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h index f31fa7a..0233348 100644 --- a/lib/libc/include/un-namespace.h +++ b/lib/libc/include/un-namespace.h @@ -189,6 +189,7 @@ #undef readv #undef recvfrom #undef recvmsg +#undef recvmmsg #undef select #undef sem_close #undef sem_destroy @@ -201,6 +202,7 @@ #undef sem_unlink #undef sem_wait #undef sendmsg +#undef sendmmsg #undef sendto #undef setsockopt #undef sigaction diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index e4fe1b2..5f8b699 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -28,6 +28,8 @@ SRCS+= futimens.c utimensat.c NOASM+= futimens.o utimensat.o PSEUDO+= _futimens.o _utimensat.o +SRCS+= recvmmsg.c sendmmsg.c + INTERPOSED = \ accept \ accept4 \ diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 7b3257c..724e1b4 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -399,6 +399,8 @@ FBSD_1.4 { utimensat; numa_setaffinity; numa_getaffinity; + sendmmsg; + recvmmsg; }; FBSDprivate_1.0 { @@ -1051,4 +1053,6 @@ FBSDprivate_1.0 { gssd_syscall; __libc_interposing_slot; __libc_sigwait; + _sendmmsg; + _recvmmsg; }; diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2 index 326e7ff..81a0201 100644 --- a/lib/libc/sys/recv.2 +++ b/lib/libc/sys/recv.2 @@ -34,8 +34,9 @@ .Sh NAME .Nm recv , .Nm recvfrom , -.Nm recvmsg -.Nd receive a message from a socket +.Nm recvmsg , +.Nm recvmmsg +.Nd receive message(s) from a socket .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -47,11 +48,15 @@ .Fn recvfrom "int s" "void *buf" "size_t len" "int flags" "struct sockaddr * restrict from" "socklen_t * restrict fromlen" .Ft ssize_t .Fn recvmsg "int s" "struct msghdr *msg" "int flags" +.Ft int +.Fn recvmmsg "int s" "struct mmsghdr *msgvec" "int vlen" "int flags" .Sh DESCRIPTION The .Fn recvfrom and .Fn recvmsg +and +.Fn recvmmsg system calls are used to receive messages from a socket, and may be used to receive data on a socket whether or not @@ -84,8 +89,25 @@ null pointer passed as its .Fa from argument. .Pp -All three routines return the length of the message on successful -completion. +The +.Fn recvmmsg +function is used to receive multiple +messages at a call. +Their number +is supplied by +.Fa vlen +(limited to 1024). +The messages are placed in the +.Fa msgvec +vector after reception. +The size of each received message is placed in the +.Fa msg_len +field of each element of the vector. +.Pp +The first three routines return the length of the message on successful +completion whereas +.Fn recvmmsg +returns the number of received messages. If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from (see @@ -100,7 +122,9 @@ in which case the value .Va errno is set to .Er EAGAIN . -The receive calls normally return any data available, +The receive calls except +.Fn recvmmsg +normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested; this behavior is affected by the socket-level options @@ -290,9 +314,34 @@ control data were discarded due to lack of space in the buffer for ancillary data. .Dv MSG_OOB is returned to indicate that expedited or out-of-band data were received. +.Pp +The +.Fn recvmmsg +system call uses the +.Fa mmsghdr +structure. Its form is as follows, as defined in +.In sys/socket.h : +.Bd -literal +struct mmsghdr { + struct msghdr msg_hdr; /* message header */ + unsigned int msg_len; /* message length */ +}; +.Ed +.Pp +For +.Fa msg_hdr +see above. On data reception the +.Fa msg_len +field is updated to the length of the received message. On +data transmission it is updated to the number of +characters sent. .Sh RETURN VALUES -These calls return the number of bytes received, or -1 -if an error occurred. +These calls except +.Fn recvmmsg +return the number of bytes received. +.Fn recvmmsg +returns the number of messages received. +A value of -1 is returned if an error occurred. .Sh ERRORS The calls fail if: .Bl -tag -width Er diff --git a/lib/libc/sys/recvmmsg.c b/lib/libc/sys/recvmmsg.c new file mode 100644 index 0000000..6b5158a --- /dev/null +++ b/lib/libc/sys/recvmmsg.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/socket.h> +#include <pthread.h> +#include "libc_private.h" + +#define VLEN_MAX 1024 + +int +recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags) +{ + int i, ret, rcvd; + + if (vlen > VLEN_MAX) + vlen = VLEN_MAX; + + rcvd = 0; + for (i = 0; i < vlen; i++) { + errno = 0; + ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags); + if (ret < 0 || errno != 0) { + if (rcvd != 0) { + /* We've received messages. Let caller know. */ + errno = 0; + return (rcvd); + } + return (-1); + } + + /* Save received bytes */ + msgvec[i].msg_len = ret; + + rcvd++; + } + + return (rcvd); +} + +#undef VLEN_MAX diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2 index 8fa2c64..6c14a60 100644 --- a/lib/libc/sys/send.2 +++ b/lib/libc/sys/send.2 @@ -34,8 +34,9 @@ .Sh NAME .Nm send , .Nm sendto , -.Nm sendmsg -.Nd send a message from a socket +.Nm sendmsg , +.Nm sendmmsg +.Nd send message(s) from a socket .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -47,6 +48,8 @@ .Fn sendto "int s" "const void *msg" "size_t len" "int flags" "const struct sockaddr *to" "socklen_t tolen" .Ft ssize_t .Fn sendmsg "int s" "const struct msghdr *msg" "int flags" +.Ft int +.Fn sendmmsg "int s" "struct mmsghdr *msgvec" "int vlen" "int flags" .Sh DESCRIPTION The .Fn send @@ -55,8 +58,10 @@ and .Fn sendto and .Fn sendmsg +and +.Fn sendmmsg system calls -are used to transmit a message to another socket. +are used to transmit one or multiple messages (with the latter call) to another socket. The .Fn send function @@ -66,6 +71,8 @@ state, while .Fn sendto and .Fn sendmsg +and +.Fn sendmmsg may be used at any time. .Pp The address of the target is given by @@ -81,6 +88,18 @@ underlying protocol, the error is returned, and the message is not transmitted. .Pp +The +.Fn sendmmsg +function sends multiple messages at a call. +They are given by the +.Fa msgvec +vector along with +.Fa vlen +specifying its size (limited to 1024). The number of +characters sent per each message is placed in the +.Fa msg_len +field of each element of the vector after transmission. +.Pp No indication of failure to deliver is implicit in a .Fn send . Locally detected errors are indicated by a return value of -1. @@ -138,10 +157,16 @@ See .Xr recv 2 for a description of the .Fa msghdr +structure and the +.Fa mmsghdr structure. .Sh RETURN VALUES -The call returns the number of characters sent, or -1 -if an error occurred. +All calls except +.Fn sendmmsg +return the number of characters sent. The +.Fn sendmmsg +call returns the number of messages sent. +If an error occurred a value of -1 is returned. .Sh ERRORS The .Fn send @@ -149,6 +174,8 @@ function and .Fn sendto and .Fn sendmsg +and +.Fn sendmmsg system calls fail if: .Bl -tag -width Er diff --git a/lib/libc/sys/sendmmsg.c b/lib/libc/sys/sendmmsg.c new file mode 100644 index 0000000..3b90b90 --- /dev/null +++ b/lib/libc/sys/sendmmsg.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/socket.h> +#include <pthread.h> +#include "libc_private.h" + +#define VLEN_MAX 1024 + +int +sendmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags) +{ + int i, ret, sent; + + if (vlen > VLEN_MAX) + vlen = VLEN_MAX; + + sent = 0; + for (i = 0; i < vlen; i++) { + errno = 0; + ret = __sys_sendmsg(s, &msgvec[i].msg_hdr, flags); + if (ret < 0 || errno != 0) { + if (sent != 0) { + /* We have sent messages. Let caller know. */ + errno = 0; + return (sent); + } + return (-1); + } + + /* Save sent bytes */ + msgvec[i].msg_len = ret; + + sent++; + } + + return (sent); +} + +#undef VLEN_MAX diff --git a/sys/sys/socket.h b/sys/sys/socket.h index 18e2de1..f70dced 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -595,6 +595,18 @@ struct sf_hdtr { #endif /* _KERNEL */ #endif /* __BSD_VISIBLE */ +#ifndef _KERNEL +#ifdef __BSD_VISIBLE +/* + * Send/recvmmsg specific structure(s) + */ +struct mmsghdr { + struct msghdr msg_hdr; /* message header */ + unsigned int msg_len; /* message length */ +}; +#endif /* __BSD_VISIBLE */ +#endif /* !_KERNEL */ + #ifndef _KERNEL #include <sys/cdefs.h> @@ -615,11 +627,17 @@ 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 +int recvmmsg(int, struct mmsghdr *, unsigned int, int); +#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 +int sendmmsg(int, struct mmsghdr *, unsigned int, int); +#endif +#if __BSD_VISIBLE int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); int setfib(int); #endif
_______________________________________________ freebsd-net@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"