From 123be9deda8eb24ef15fb889248984e6d23bb8b4 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Sat, 3 Nov 2012 18:29:46 +0100 Subject: [PATCH] Add recvmmsg and sendmmsg to the generic glibc API. --- ChangeLog | 25 ++++++++++++++++++++++ include/sys/socket.h | 4 ++++ resolv/res_send.c | 2 +- socket/Makefile | 2 +- socket/Versions | 6 ++++++ socket/recvmmsg.c | 31 +++++++++++++++++++++++++++ socket/sendmmsg.c | 32 ++++++++++++++++++++++++++++ socket/sys/socket.h | 31 +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/Makefile | 3 +-- sysdeps/unix/sysv/linux/bits/socket.h | 33 ----------------------------- sysdeps/unix/sysv/linux/internal_sendmmsg.S | 9 ++++---- sysdeps/unix/sysv/linux/recvmmsg.c | 11 ++-------- sysdeps/unix/sysv/linux/sendmmsg.c | 18 +++++++--------- 13 files changed, 147 insertions(+), 60 deletions(-) create mode 100644 socket/recvmmsg.c create mode 100644 socket/sendmmsg.c diff --git a/ChangeLog b/ChangeLog index 44a0ff1..ba42534 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2012-11-20 Thomas Schwinge + + * sysdeps/unix/sysv/linux/bits/socket.h (struct mmsghdr, recvmmsg) + (sendmmsg): Move declarations... + * socket/sys/socket.h: ... here. + * sysdeps/unix/sysv/linux/recvmmsg.c [!defined __NR_recvmmsg && + !defined __NR_socketcall] (recvmmsg): Move ENOSYS stub into and + include it from... + * socket/recvmmsg.c: ... this new file. + * sysdeps/unix/sysv/linux/internal_sendmmsg.S [__ASSUME_SENDMMSG] + (sendmmsg): Rename to __sendmmsg, create weak alias and make + definition of __sendmmsg hidden. + * sysdeps/unix/sysv/linux/sendmmsg.c (sendmmsg): Likewise. + [!defined __NR_sendmmsg && !defined __NR_socketcall] (sendmmsg): + Move ENOSYS stub into and include it from... + * socket/sendmmsg.c: ... this new file. + * sysdeps/unix/sysv/linux/Makefile [subdir=socket] + (sysdep_routines): Move recvmmsg and sendmmsg... + * socket/Makefile (routines): ... here. + * socket/Versions (GLIBC_2.17): Add recvmmsg and sendmmsg. + (GLIBC_PRIVATE): Add __sendmmsg. + * include/sys/socket.h (__sendmmsg): Add declarations. + * resolv/res_send.c (send_dg): Invoke __sendmmsg instead of + sendmmsg. + 2012-11-20 Joseph Myers * sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl): Mark diff --git a/include/sys/socket.h b/include/sys/socket.h index ec08857..9caf1bb 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -91,6 +91,10 @@ extern ssize_t __libc_sendmsg (int __fd, const struct msghdr *__message, extern ssize_t __sendmsg (int __fd, const struct msghdr *__message, int __flags) attribute_hidden; +extern int __sendmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); +libc_hidden_proto (__sendmmsg) + /* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors. */ extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message, diff --git a/resolv/res_send.c b/resolv/res_send.c index 0a28cd7..c790031 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -1129,7 +1129,7 @@ send_dg(res_state statp, reqs[1].msg_hdr.msg_control = NULL; reqs[1].msg_hdr.msg_controllen = 0; - int ndg = sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL); + int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL); if (__builtin_expect (ndg == 2, 1)) { if (reqs[0].msg_len != buflen diff --git a/socket/Makefile b/socket/Makefile index e3a90b8..6037f3f 100644 --- a/socket/Makefile +++ b/socket/Makefile @@ -26,7 +26,7 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \ routines := accept bind connect getpeername getsockname getsockopt \ listen recv recvfrom recvmsg send sendmsg sendto \ setsockopt shutdown socket socketpair isfdtype opensock \ - sockatmark accept4 + sockatmark accept4 recvmmsg sendmmsg aux := have_sock_cloexec diff --git a/socket/Versions b/socket/Versions index 7a96b1e..dcad329 100644 --- a/socket/Versions +++ b/socket/Versions @@ -34,4 +34,10 @@ libc { GLIBC_2.10 { accept4; } + GLIBC_2.17 { + recvmmsg; sendmmsg; + } + GLIBC_PRIVATE { + __sendmmsg; + } } diff --git a/socket/recvmmsg.c b/socket/recvmmsg.c new file mode 100644 index 0000000..2d6d474 --- /dev/null +++ b/socket/recvmmsg.c @@ -0,0 +1,31 @@ +/* Receive multiple messages on a socket. Stub version. + Copyright (C) 2010-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +/* Receive up to VLEN messages as described by VMESSAGES from socket FD. + Returns the number of bytes read or -1 for errors. */ +int +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, + const struct timespec *tmo) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (recvmmsg) diff --git a/socket/sendmmsg.c b/socket/sendmmsg.c new file mode 100644 index 0000000..ed93f49 --- /dev/null +++ b/socket/sendmmsg.c @@ -0,0 +1,32 @@ +/* Send multiple messages on a socket. Stub version. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +/* Send a VLEN messages as described by VMESSAGES to socket FD. + Returns the number of datagrams successfully written or -1 for errors. */ +int +__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +{ + __set_errno (ENOSYS); + return -1; +} +libc_hidden_def (__sendmmsg) +weak_alias (__sendmmsg, sendmmsg) +stub_warning (sendmmsg) diff --git a/socket/sys/socket.h b/socket/sys/socket.h index 787c2b9..3810a37 100644 --- a/socket/sys/socket.h +++ b/socket/sys/socket.h @@ -97,6 +97,16 @@ typedef union { __SOCKADDR_ALLTYPES # undef __SOCKADDR_ONETYPE #endif +#ifdef __USE_GNU +/* For `recvmmsg' and `sendmmsg'. */ +struct mmsghdr + { + struct msghdr msg_hdr; /* Actual message header. */ + unsigned int msg_len; /* Number of received or sent bytes for the + entry. */ + }; +#endif + /* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. @@ -175,6 +185,16 @@ extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, extern ssize_t sendmsg (int __fd, const struct msghdr *__message, int __flags); +#ifdef __USE_GNU +/* Send a VLEN messages as described by VMESSAGES to socket FD. + Returns the number of datagrams successfully written or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern int sendmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); +#endif + /* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors. @@ -182,6 +202,17 @@ extern ssize_t sendmsg (int __fd, const struct msghdr *__message, __THROW. */ extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); +#ifdef __USE_GNU +/* Receive up to VLEN messages as described by VMESSAGES from socket FD. + Returns the number of bytes read or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern int recvmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags, + const struct timespec *__tmo); +#endif + /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 8e5361c..ecd9c2c 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -12,8 +12,7 @@ CFLAGS-malloc.c += -DMORECORE_CLEARS=2 endif ifeq ($(subdir),socket) -sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg sendmmsg \ - internal_sendmmsg +sysdep_routines += internal_accept4 internal_recvmmsg internal_sendmmsg endif ifeq ($(subdir),misc) diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h index 309cba7..df8f167 100644 --- a/sysdeps/unix/sysv/linux/bits/socket.h +++ b/sysdeps/unix/sysv/linux/bits/socket.h @@ -235,16 +235,6 @@ struct msghdr int msg_flags; /* Flags on received message. */ }; -#ifdef __USE_GNU -/* For `recvmmsg' and 'sendmmsg'. */ -struct mmsghdr - { - struct msghdr msg_hdr; /* Actual message header. */ - unsigned int msg_len; /* Number of received or sent bytes - for the entry. */ - }; -#endif - /* Structure used for storage of ancillary data object information. */ struct cmsghdr { @@ -389,27 +379,4 @@ struct linger int l_linger; /* Time to linger. */ }; - -__BEGIN_DECLS - -#ifdef __USE_GNU -/* Receive up to VLEN messages as described by VMESSAGES from socket FD. - Returns the number of bytes read or -1 for errors. - - This function is a cancellation point and therefore not marked with - __THROW. */ -extern int recvmmsg (int __fd, struct mmsghdr *__vmessages, - unsigned int __vlen, int __flags, - const struct timespec *__tmo); - -/* Send a VLEN messages as described by VMESSAGES to socket FD. - Return the number of datagrams successfully written or -1 for errors. -This function is a cancellation point and therefore not marked with - __THROW. */ -extern int sendmmsg (int __fd, struct mmsghdr *__vmessages, - unsigned int __vlen, int __flags); -#endif - -__END_DECLS - #endif /* bits/socket.h */ diff --git a/sysdeps/unix/sysv/linux/internal_sendmmsg.S b/sysdeps/unix/sysv/linux/internal_sendmmsg.S index f5152c9..e6681f0 100644 --- a/sysdeps/unix/sysv/linux/internal_sendmmsg.S +++ b/sysdeps/unix/sysv/linux/internal_sendmmsg.S @@ -2,13 +2,14 @@ #include #if !defined __NR_sendmmsg && defined __NR_socketcall # define socket sendmmsg -# ifdef __ASSUME_SENDMMSG -# define __socket sendmmsg -# else +# ifndef __ASSUME_SENDMMSG # define __socket __internal_sendmmsg +# define NO_WEAK_ALIAS # endif # define NARGS 4 # define NEED_CANCELLATION -# define NO_WEAK_ALIAS # include +# ifdef __ASSUME_SENDMMSG +libc_hidden_def (__sendmmsg) +# endif #endif diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c index 32fc8df..009d868 100644 --- a/sysdeps/unix/sysv/linux/recvmmsg.c +++ b/sysdeps/unix/sysv/linux/recvmmsg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Free Software Foundation, Inc. +/* Copyright (C) 2010-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Schwab , 2010. @@ -88,12 +88,5 @@ recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, /* When __ASSUME_RECVMMSG recvmmsg is defined in internal_recvmmsg.S. */ # endif #else -int -recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, - const struct timespec *tmo) -{ - __set_errno (ENOSYS); - return -1; -} -stub_warning (recvmmsg) +# include #endif diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c index 0674419..a6daff1 100644 --- a/sysdeps/unix/sysv/linux/sendmmsg.c +++ b/sysdeps/unix/sysv/linux/sendmmsg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Free Software Foundation, Inc. +/* Copyright (C) 2011-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2011. @@ -26,7 +26,7 @@ #ifdef __NR_sendmmsg int -sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) { if (SINGLE_THREAD_P) return INLINE_SYSCALL (sendmmsg, 4, fd, vmessages, vlen, flags); @@ -39,6 +39,8 @@ sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) return result; } +libc_hidden_def (__sendmmsg) +weak_alias (__sendmmsg, sendmmsg) #elif defined __NR_socketcall # ifndef __ASSUME_SENDMMSG extern int __internal_sendmmsg (int fd, struct mmsghdr *vmessages, @@ -48,7 +50,7 @@ extern int __internal_sendmmsg (int fd, struct mmsghdr *vmessages, static int have_sendmmsg; int -sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) { if (__builtin_expect (have_sendmmsg >= 0, 1)) { @@ -81,15 +83,11 @@ sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) __set_errno (ENOSYS); return -1; } +libc_hidden_def (__sendmmsg) +weak_alias (__sendmmsg, sendmmsg) # else /* When __ASSUME_SENDMMSG sendmmsg is defined in internal_sendmmsg.S. */ # endif #else -int -sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) -{ - __set_errno (ENOSYS); - return -1; -} -stub_warning (sendmmsg) +# include #endif -- 2.7.4