Add recvmmsg and sendmmsg to the generic glibc API.

This commit is contained in:
Thomas Schwinge 2012-11-03 18:29:46 +01:00
parent cf9a5d1861
commit 123be9deda
13 changed files with 147 additions and 60 deletions

View File

@ -1,3 +1,28 @@
2012-11-20 Thomas Schwinge <thomas@codesourcery.com>
* 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 <joseph@codesourcery.com>
* sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl): Mark

View File

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

View File

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

View File

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

View File

@ -34,4 +34,10 @@ libc {
GLIBC_2.10 {
accept4;
}
GLIBC_2.17 {
recvmmsg; sendmmsg;
}
GLIBC_PRIVATE {
__sendmmsg;
}
}

31
socket/recvmmsg.c Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <sys/socket.h>
/* 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)

32
socket/sendmmsg.c Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <sys/socket.h>
/* 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)

View File

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

View File

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

View File

@ -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 */

View File

@ -2,13 +2,14 @@
#include <sys/syscall.h>
#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 <socket.S>
# ifdef __ASSUME_SENDMMSG
libc_hidden_def (__sendmmsg)
# endif
#endif

View File

@ -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 <schwab@redhat.com>, 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 <socket/recvmmsg.c>
#endif

View File

@ -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 <drepper@gmail.com>, 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 <socket/sendmmsg.c>
#endif