public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg
  2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
@ 2016-03-21 20:41 ` Adhemerval Zanella
  2016-03-21 23:26   ` Joseph Myers
  2016-03-21 20:42 ` [PATCH 1/4] Add architecture specific socket.h header Adhemerval Zanella
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 20:41 UTC (permalink / raw)
  To: libc-alpha

This patch cleanups the __ASSUME_RECVMMSG_* and __ASSUME_SENDMMSG_*
usage in linux recvmmsg and sendmmsg implementation.  It also fixes
a bug on i686/x86_64 when building with 2.6.32 kernel support.  The
changes in this patches are the following:

 * Remove the __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL for ports that
   for current minimum supported kernel already have direct recvmmsg
   syscall support (microblaze, powerpc, and spart).

 * Add __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL define for ports that
   still uses socketcall interface (i386, m68k, s390).

 * Remove the __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL for ports that
   for current minimum supported kernel alread have direct sendmmsg
   syscall support (powerpc, sparc).

 * Add __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL define for ports that
   still uses socketcall interface (i386, m68k, microblaze, and s390)

Along with the define changes, the linux recvmmsg and sendmmsg implementation
now uses a different strategy to use direct syscall, socketcall, runtime
socketcall (which issues a socketcall and update have_*), and stub function:

 1. If the architecture defines __ASSUME_{RECVMMSG,SENDMMSG}_SYSCALL the
    direct syscall is used instead.  This is the default behavior for most
    ports that do not support socketcall.

 2. Otherwise, if the architecture defines
    __ASSUME_{RECVMMSG,SENDMMSG}_SYSCALL_WITH_SOCKETCALL the socketcall
    interface will be used instead.  Different than the default
    __ASSUME_{RECVMMSG,SENDMMSG}_SOCKETCALL, this define is set per
    architecture.

 3. Otherwise, if the architecure define __ASSUME_SOCKETCALL the
    runtime socketcall call will be used which will test if the kernel
    supports {sendmmsg,recvmmsg} and set have_{recvmmsg,sendmmsg}
    accordingly.

 4. Otherwise the stub warning implementation will be use.

This approach also fixes the following i386/x86_64 issue:

 * For i686 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
   supported kernel) will use direct syscall where it should use runtime
   socketcall

 * For x86_64 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
   kernel) will use syscall where it should use stub.

Tested on i686, x86_64, aarch64, armhf, and powerpc64le.

	* sysdeps/unix/sysv/linux/i386/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	[__LINUX_KERNEL_VERSION > 0x030000]
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Add define.
	* sysdeps/unix/sysv/linux/m68k/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/microblaze/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	* sysdeps/unix/sysv/linux/powerpc/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/s390/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Add define.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/sh/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	* sysdeps/unix/sysv/linux/sparc/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c: Remove file.
	* sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c: Likewise.
	* sysdeps/unix/sysv/linux/recvmmsg.c (recvmmsg): Refactor
	__ASSUME macro usage.
	* sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
---
 ChangeLog                                          | 26 +++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/kernel-features.h     |  8 ++++--
 sysdeps/unix/sysv/linux/m68k/kernel-features.h     |  2 ++
 .../unix/sysv/linux/microblaze/kernel-features.h   |  4 +--
 sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c     | 29 ----------------------
 sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c     | 29 ----------------------
 sysdeps/unix/sysv/linux/powerpc/kernel-features.h  |  3 ---
 sysdeps/unix/sysv/linux/recvmmsg.c                 | 26 +++++--------------
 sysdeps/unix/sysv/linux/s390/kernel-features.h     |  2 ++
 sysdeps/unix/sysv/linux/sendmmsg.c                 | 27 ++++++--------------
 sysdeps/unix/sysv/linux/sparc/kernel-features.h    |  6 -----
 11 files changed, 50 insertions(+), 112 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c

diff --git a/sysdeps/unix/sysv/linux/i386/kernel-features.h b/sysdeps/unix/sysv/linux/i386/kernel-features.h
index 148963c..3e25476 100644
--- a/sysdeps/unix/sysv/linux/i386/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/i386/kernel-features.h
@@ -21,10 +21,14 @@
 #define __ASSUME_SOCKETCALL		1
 
 /* The recvmmsg syscall was added for i386 in 2.6.33.  */
-#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
+#if __LINUX_KERNEL_VERSION >= 0x020621
+# define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
+#endif
 
 /* The sendmmsg syscall was added for i386 in 3.0.  */
-#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
+#if __LINUX_KERNEL_VERSION >= 0x030000
+# define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
+#endif
 
 /* Direct socketcalls available with kernel 4.3.  */
 #if __LINUX_KERNEL_VERSION >= 0x040300
diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h
index dec04f0..0945779 100644
--- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h
@@ -19,6 +19,8 @@
 
 /* m68k uses socketcall.  */
 #define __ASSUME_SOCKETCALL	1
+#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
 
 /* Direct socketcalls available with kernel 4.3.  */
 #if __LINUX_KERNEL_VERSION >= 0x040300
diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
index db471ef..e25b6ed 100644
--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
@@ -18,6 +18,7 @@
 
 /* MicroBlaze uses socketcall.  */
 #define __ASSUME_SOCKETCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
 
 /* All supported kernel versions for MicroBlaze have these syscalls.  */
 #define __ASSUME_SOCKET_SYSCALL		1
@@ -36,9 +37,6 @@
 #define __ASSUME_GETSOCKOPT_SYSCALL	1
 #define __ASSUME_SETSOCKOPT_SYSCALL	1
 
-/* Support for the accept4 and recvmmsg syscalls was added in 2.6.33.  */
-#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL      1
-
 /* Support for the futimesat syscall was added in 2.6.33.  */
 #define __ASSUME_FUTIMESAT              1
 
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c b/sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c
deleted file mode 100644
index c2a3440..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2010-2016 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/>.  */
-
-/* Avoid recvmmsg.c trying to use a definition based on the socketcall
-   syscall and internal_recvmmsg.S.  */
-
-#include <errno.h>
-#include <sys/socket.h>
-
-#include <sysdep-cancel.h>
-#include <sys/syscall.h>
-
-#undef __NR_socketcall
-
-#include <sysdeps/unix/sysv/linux/recvmmsg.c>
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c b/sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c
deleted file mode 100644
index 7cd4e15..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2011-2016 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/>.  */
-
-/* Avoid sendmmsg.c trying to use a definition based on the socketcall
-   syscall and internal_sendmmsg.S.  */
-
-#include <errno.h>
-#include <sys/socket.h>
-
-#include <sysdep-cancel.h>
-#include <sys/syscall.h>
-
-#undef __NR_socketcall
-
-#include <sysdeps/unix/sysv/linux/sendmmsg.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
index 5449f18..825c0f0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
@@ -37,7 +37,4 @@
 #define __ASSUME_GETSOCKOPT_SYSCALL	1
 #define __ASSUME_SETSOCKOPT_SYSCALL	1
 
-/* The sendmmsg syscall was added for PowerPC in 3.0.  */
-#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
-
 #include_next <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index bf18260..fb3f325 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -16,39 +16,26 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <sys/socket.h>
-
 #include <sysdep-cancel.h>
-#include <sys/syscall.h>
-#include <kernel-features.h>
-
-/* Do not use the recvmmsg syscall on socketcall architectures unless
-   it was added at the same time as the socketcall support or can be
-   assumed to be present.  */
-#if defined __ASSUME_SOCKETCALL \
-    && !defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL \
-    && !defined __ASSUME_RECVMMSG_SYSCALL
-# undef __NR_recvmmsg
-#endif
+#include <socketcall.h>
+#include <shlib-compat.h>
 
-#ifdef __NR_recvmmsg
+#ifdef __ASSUME_RECVMMSG_SYSCALL
 int
 recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
 	  struct timespec *tmo)
 {
   return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
 }
-#elif defined __NR_socketcall
-# include <socketcall.h>
-# ifdef __ASSUME_RECVMMSG_SOCKETCALL
+#elif defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL
 int
 recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
 	  struct timespec *tmo)
 {
   return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
 }
-# else
+#elif defined __ASSUME_SOCKETCALL
 static int have_recvmmsg;
 
 int
@@ -87,7 +74,6 @@ recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
   __set_errno (ENOSYS);
   return -1;
 }
-# endif /* __ASSUME_RECVMMSG_SOCKETCALL  */
-#else
+#else /* __ASSUME_RECVMMSG_SOCKETCALL  */
 # include <socket/recvmmsg.c>
 #endif
diff --git a/sysdeps/unix/sysv/linux/s390/kernel-features.h b/sysdeps/unix/sysv/linux/s390/kernel-features.h
index b3edee4..4656c4a 100644
--- a/sysdeps/unix/sysv/linux/s390/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h
@@ -19,6 +19,8 @@
 
 /* S/390 uses socketcall.  */
 #define __ASSUME_SOCKETCALL		1
+#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
 
 /* Direct socketcalls available with kernel 4.3.  */
 #if __LINUX_KERNEL_VERSION >= 0x040300
diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c
index 6e0d46b..37f0ec9 100644
--- a/sysdeps/unix/sysv/linux/sendmmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmmsg.c
@@ -16,23 +16,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <sys/socket.h>
-
 #include <sysdep-cancel.h>
-#include <sys/syscall.h>
-#include <kernel-features.h>
-
-/* Do not use the sendmmsg syscall on socketcall architectures unless
-   it was added at the same time as the socketcall support or can be
-   assumed to be present.  */
-#if defined __ASSUME_SOCKETCALL \
-    && !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \
-    && !defined __ASSUME_SENDMMSG_SYSCALL
-# undef __NR_sendmmsg
-#endif
+#include <socketcall.h>
 
-#ifdef __NR_sendmmsg
+#ifdef __ASSUME_SENDMMSG_SYSCALL
 int
 __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
@@ -40,15 +28,15 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 }
 libc_hidden_def (__sendmmsg)
 weak_alias (__sendmmsg, sendmmsg)
-#elif defined __NR_socketcall
-# include <socketcall.h>
-# ifdef __ASSUME_SENDMMSG_SOCKETCALL
+#elif defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL
 int
 __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
   return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
 }
-# else
+libc_hidden_def (__sendmmsg)
+weak_alias (__sendmmsg, sendmmsg)
+#elif defined __ASSUME_SOCKETCALL
 static int have_sendmmsg;
 
 int
@@ -85,9 +73,8 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
   __set_errno (ENOSYS);
   return -1;
 }
-# endif /* __ASSUME_SENDMMSG_SOCKETCALL  */
 libc_hidden_def (__sendmmsg)
 weak_alias (__sendmmsg, sendmmsg)
-#else
+#else /* __ASSUME_SENDMMSG_SOCKETCALL  */
 # include <socket/sendmmsg.c>
 #endif
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel-features.h b/sysdeps/unix/sysv/linux/sparc/kernel-features.h
index 386f230..486036d 100644
--- a/sysdeps/unix/sysv/linux/sparc/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/sparc/kernel-features.h
@@ -23,12 +23,6 @@
 /* The accept4 syscall was added for SPARC in 2.6.28.  */
 #define __ASSUME_ACCEPT4_SYSCALL_WITH_SOCKETCALL	1
 
-/* The recvmmsg syscall was added for SPARC in 2.6.33.  */
-#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
-
-/* The sendmmsg syscall was added for SPARC in 3.0.  */
-#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
-
 #include_next <kernel-features.h>
 
 /* 32-bit SPARC kernels do not support
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919)
@ 2016-03-21 20:41 Adhemerval Zanella
  2016-03-21 20:41 ` [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg Adhemerval Zanella
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 20:41 UTC (permalink / raw)
  To: libc-alpha

This is an attempt of fixing the BZ#16919, recvmsg standard compliance,
where Linux and POSIX differs in the msghdr and mmsghdr internal struct
sizes.  The issue is POSIX defines [1] both msghdr.msg_namelen,
msghdr.controllen, and cmsghdr.cmsg_len as socklen_t, where Linux uses
size_t.  So for 64-bits architectures where size_t is larger sockelen_t
it leads to standard inconsistence.  Linux also added recvmmsg and
sendmmsg, which uses a composite struct based on msghdr (mmsghdr).

As stated in comment 6 at bugzilla report, both recvmsg and recvmmsg
uses the msghdr structures which lie in memory that's (by the interface
contract) writable by the function, so the adjustment is just to patch
with zero the padding memebers.  However sendmmsg's msghdr points to
an already-filled control buffer containing cmsghdr structures that
is not writable by the function's contract.

So the proposed solutions follow four patches:

 1. Add architecture specific socket.h header: splits the Linux
    socket.h definition in a platform specific one for the new
    msghdr and cmsghdr defition.  The is just a functional change
    to lay the required headers (more rationale where it is not
    possible to support only on header on the patch comments).

 2. Adjust kernel-features.h for sendmmsg/recvmmsg: this try to
    simplify the sendmmsg/recvmmsg __ASSUME definition and also
    fixes some x86 bugs when building using old kernel definitions.

 3. network: recvmsg and sendmsg standard compliance: this is the
    first patch of the BZ#16919 fix where it handle both recvmsg
    and sendmsg.

 4. network: recvmmsg and sendmmsg standard compliance: the second
    patch where is handles both recvmmsg and sendmmsg.

This current solutions have some open spots that I would like to
discuss:

 1. Current sendmsg fix does not handle larger msg_control neither
    pads the cmsghdr associated.  The problem with this approach
    is to accomplish a complete fix it will require to allocate
    a limited buffer, copying the incoming struct and zero pad.
    Although it tend to work it also add some limitation of total
    msg_control length.
    The general usage for such facily is passing file descriptors
    and permissions between processes over unix sockets so it might
    be factible to use a large stack allocated buffer (1024, 2048
    or large) and return ENOMEM for larger buffers.

 2. Current approach adds symbol versioning for older implementation
    which uses the syscall directly.  This is the default GLIBC
    policy for such changes, whoever I am not sure if there is any
    realword application that might break with this new implementation.
    So one option could get rid of the compatbility symbols.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/

Adhemerval Zanella (4):
  Add architecture specific socket.h header
  Adjust kernel-features.h for sendmmsg/recvmmsg
  network: recvmsg and sendmsg standard compliance (BZ#16919)
  network: recvmmsg and sendmmsg standard compliance (BZ#16919)

 ChangeLog                                          | 211 +++++++++++
 conform/data/sys/socket.h-data                     |   8 +-
 nptl/Makefile                                      |   1 +
 sysdeps/unix/sysv/linux/Makefile                   |   5 +-
 sysdeps/unix/sysv/linux/aarch64/Versions           |   9 +
 sysdeps/unix/sysv/linux/aarch64/bits/socket.h      |  87 +++++
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |   5 +
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist |   3 +
 sysdeps/unix/sysv/linux/alpha/Versions             |   6 +
 sysdeps/unix/sysv/linux/alpha/bits/socket.h        |  66 ++++
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |   5 +
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist   |   3 +
 sysdeps/unix/sysv/linux/arm/bits/socket.h          |  64 ++++
 sysdeps/unix/sysv/linux/bits/socket-linux.h        | 355 +++++++++++++++++++
 sysdeps/unix/sysv/linux/bits/socket.h              | 389 ---------------------
 sysdeps/unix/sysv/linux/check_native.c             |  11 +-
 sysdeps/unix/sysv/linux/check_pf.c                 |  11 +-
 sysdeps/unix/sysv/linux/hppa/bits/socket.h         |  64 ++++
 sysdeps/unix/sysv/linux/i386/bits/socket.h         |  71 ++++
 sysdeps/unix/sysv/linux/i386/kernel-features.h     |   8 +-
 sysdeps/unix/sysv/linux/ia64/Versions              |   6 +
 sysdeps/unix/sysv/linux/ia64/bits/socket.h         |  70 ++++
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |   5 +
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |   3 +
 sysdeps/unix/sysv/linux/ifaddrs.c                  |  11 +-
 sysdeps/unix/sysv/linux/m68k/bits/socket.h         |  64 ++++
 sysdeps/unix/sysv/linux/m68k/kernel-features.h     |   2 +
 sysdeps/unix/sysv/linux/microblaze/bits/socket.h   |  71 ++++
 .../unix/sysv/linux/microblaze/kernel-features.h   |   6 +-
 sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h  |  64 ++++
 sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c     |  29 --
 sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c     |  29 --
 sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h  |  87 +++++
 .../unix/sysv/linux/mips/mips64/libpthread.abilist |   3 +
 .../sysv/linux/mips/mips64/n32/libpthread.abilist  | 256 ++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips64/n64/Versions   |  10 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |   5 +
 sysdeps/unix/sysv/linux/nios2/bits/socket.h        |  64 ++++
 sysdeps/unix/sysv/linux/oldrecvmmsg.c              |  91 +++++
 sysdeps/unix/sysv/linux/oldrecvmsg.c               |  42 +++
 sysdeps/unix/sysv/linux/oldsendmmsg.c              |  90 +++++
 sysdeps/unix/sysv/linux/oldsendmsg.c               |  42 +++
 sysdeps/unix/sysv/linux/powerpc/kernel-features.h  |   3 -
 .../sysv/linux/powerpc/powerpc32/bits/socket.h     |  64 ++++
 sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions |   6 +
 .../sysv/linux/powerpc/powerpc64/bits/socket.h     |  87 +++++
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |   5 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |   5 +
 .../linux/powerpc/powerpc64/libpthread-le.abilist  |   3 +
 .../linux/powerpc/powerpc64/libpthread.abilist     |   3 +
 sysdeps/unix/sysv/linux/recvmmsg.c                 |  71 ++--
 sysdeps/unix/sysv/linux/recvmsg.c                  |  40 ++-
 sysdeps/unix/sysv/linux/s390/kernel-features.h     |   5 +
 sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h |  64 ++++
 sysdeps/unix/sysv/linux/s390/s390-64/Versions      |   9 +
 sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h |  70 ++++
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |   5 +
 .../sysv/linux/s390/s390-64/libpthread.abilist     |   3 +
 sysdeps/unix/sysv/linux/sendmmsg.c                 |  77 ++--
 sysdeps/unix/sysv/linux/sendmsg.c                  |  27 +-
 sysdeps/unix/sysv/linux/sh/bits/socket.h           |  64 ++++
 sysdeps/unix/sysv/linux/sh/kernel-features.h       |   3 -
 sysdeps/unix/sysv/linux/sparc/kernel-features.h    |   6 -
 .../unix/sysv/linux/sparc/sparc32/bits/socket.h    |  64 ++++
 sysdeps/unix/sysv/linux/sparc/sparc64/Versions     |   9 +
 .../unix/sysv/linux/sparc/sparc64/bits/socket.h    |  70 ++++
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |   5 +
 .../sysv/linux/sparc/sparc64/libpthread.abilist    |   3 +
 sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h  |  87 +++++
 .../unix/sysv/linux/tile/tilegx/tilegx64/Versions  |   5 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |   5 +
 .../linux/tile/tilegx/tilegx64/libpthread.abilist  |   3 +
 sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h |  64 ++++
 sysdeps/unix/sysv/linux/x86_64/64/Versions         |  10 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |   5 +
 .../unix/sysv/linux/x86_64/64/libpthread.abilist   |   3 +
 sysdeps/unix/sysv/linux/x86_64/bits/socket.h       |  70 ++++
 77 files changed, 2913 insertions(+), 542 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/alpha/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/arm/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/bits/socket-linux.h
 delete mode 100644 sysdeps/unix/sysv/linux/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/m68k/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libpthread.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/Versions
 create mode 100644 sysdeps/unix/sysv/linux/nios2/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/oldrecvmmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/oldrecvmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/oldsendmmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/oldsendmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sh/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/Versions
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/bits/socket.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] Add architecture specific socket.h header
  2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
  2016-03-21 20:41 ` [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg Adhemerval Zanella
@ 2016-03-21 20:42 ` Adhemerval Zanella
  2016-03-21 23:11   ` Joseph Myers
  2016-03-21 20:42 ` [PATCH 3/4] network: recvmsg and sendmsg standard compliance (BZ#16919) Adhemerval Zanella
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 20:42 UTC (permalink / raw)
  To: libc-alpha

This patch adds architecture specific socket.h header for Linux,
move the default socket.h header to socket-linux.h (in a similar
way done for fcntl.h header), and move the msghdr and cmsghdr
definitions to the architecture specific header.  No functional
changes are done so no code changes are expected.

The rationale is to to fix BZ#16919 (recvmsg standard compliance)
where it requires to change both the msghdr and cmsghdr internal
fields to add padding members if the size_t for the architecture
is larger than the POSIX defined int and socklen_t for the
msg_namelen, msg_controllen, and cmsg_len.

To avoid namespace pollution socket.h can not include limits.h to
get LONG_MAX and INT_MAX, so the option is either using compiler
builtin defintions (__LONG_MAX__ and __INT_MAX__) or by creating
archicteture specific headers.  The first option has the downside
of relying on existense of builtin, which might not be true for all
current compilers.

	* sysdeps/unix/sysv/linux/Makefile
	[$(subdir) = io] (sysdep_headers): Add socket-linux.h.
	* sysdeps/unix/sysv/linux/bits/socket.h: Move to ...
	* sysdeps/unix/sysv/linux/bits/socket-linux.h: ... here.
	* sysdeps/unix/sysv/linux/aarch64/bits/socket.h: New file.
	* sysdeps/unix/sysv/linux/alpha/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/arm/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/hppa/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/ia64/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/m68k/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/nios2/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/sh/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/bits/socket.h: Likewise.
---
 sysdeps/unix/sysv/linux/Makefile                   |   2 +-
 sysdeps/unix/sysv/linux/aarch64/bits/socket.h      |  69 ++++
 sysdeps/unix/sysv/linux/alpha/bits/socket.h        |  69 ++++
 sysdeps/unix/sysv/linux/arm/bits/socket.h          |  64 ++++
 sysdeps/unix/sysv/linux/bits/socket-linux.h        | 355 +++++++++++++++++++
 sysdeps/unix/sysv/linux/bits/socket.h              | 389 ---------------------
 sysdeps/unix/sysv/linux/hppa/bits/socket.h         |  64 ++++
 sysdeps/unix/sysv/linux/i386/bits/socket.h         |  71 ++++
 sysdeps/unix/sysv/linux/ia64/bits/socket.h         |  69 ++++
 sysdeps/unix/sysv/linux/m68k/bits/socket.h         |  64 ++++
 sysdeps/unix/sysv/linux/microblaze/bits/socket.h   |  71 ++++
 sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h  |  64 ++++
 sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h  |  69 ++++
 sysdeps/unix/sysv/linux/nios2/bits/socket.h        |  64 ++++
 .../sysv/linux/powerpc/powerpc32/bits/socket.h     |  64 ++++
 .../sysv/linux/powerpc/powerpc64/bits/socket.h     |  69 ++++
 sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h |  64 ++++
 sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h |  69 ++++
 sysdeps/unix/sysv/linux/sh/bits/socket.h           |  64 ++++
 .../unix/sysv/linux/sparc/sparc32/bits/socket.h    |  64 ++++
 .../unix/sysv/linux/sparc/sparc64/bits/socket.h    |  69 ++++
 sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h  |  69 ++++
 sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h |  64 ++++
 sysdeps/unix/sysv/linux/x86_64/bits/socket.h       |  69 ++++
 25 files changed, 1785 insertions(+), 390 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/alpha/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/arm/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/bits/socket-linux.h
 delete mode 100644 sysdeps/unix/sysv/linux/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/m68k/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/nios2/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sh/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/bits/socket.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 9999600..b75a53b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -169,7 +169,7 @@ endif
 ifeq ($(subdir),io)
 sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
 		   sync_file_range fallocate fallocate64
-sysdep_headers += bits/fcntl-linux.h
+sysdep_headers += bits/fcntl-linux.h bits/socket-linux.h
 endif
 
 ifeq ($(subdir),elf)
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/socket.h b/sysdeps/unix/sysv/linux/aarch64/bits/socket.h
new file mode 100644
index 0000000..7f6bf84
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  AArch64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_AARCH64_SOCKET_H
+#define __BITS_AARCH64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/socket.h b/sysdeps/unix/sysv/linux/alpha/bits/socket.h
new file mode 100644
index 0000000..bec9330
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  Alpha Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_ALPHA_SOCKET_H
+#define __BITS_ALPHA_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/arm/bits/socket.h b/sysdeps/unix/sysv/linux/arm/bits/socket.h
new file mode 100644
index 0000000..4d141d6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  ARM Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_ARM_SOCKET_H
+#define __BITS_ARM_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/bits/socket-linux.h b/sysdeps/unix/sysv/linux/bits/socket-linux.h
new file mode 100644
index 0000000..0b1b15d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/socket-linux.h
@@ -0,0 +1,355 @@
+/* System-specific socket constants and types.  Linux version.
+   Copyright (C) 1991-2016 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/>.  */
+
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define __need_size_t
+#include <stddef.h>
+
+#include <sys/types.h>
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Get the architecture-dependent definition of enum __socket_type.  */
+#include <bits/socket_type.h>
+
+/* Protocol families.  */
+#define PF_UNSPEC	0	/* Unspecified.  */
+#define PF_LOCAL	1	/* Local to host (pipes and file-domain).  */
+#define PF_UNIX		PF_LOCAL /* POSIX name for PF_LOCAL.  */
+#define PF_FILE		PF_LOCAL /* Another non-standard name for PF_LOCAL.  */
+#define PF_INET		2	/* IP protocol family.  */
+#define PF_AX25		3	/* Amateur Radio AX.25.  */
+#define PF_IPX		4	/* Novell Internet Protocol.  */
+#define PF_APPLETALK	5	/* Appletalk DDP.  */
+#define PF_NETROM	6	/* Amateur radio NetROM.  */
+#define PF_BRIDGE	7	/* Multiprotocol bridge.  */
+#define PF_ATMPVC	8	/* ATM PVCs.  */
+#define PF_X25		9	/* Reserved for X.25 project.  */
+#define PF_INET6	10	/* IP version 6.  */
+#define PF_ROSE		11	/* Amateur Radio X.25 PLP.  */
+#define PF_DECnet	12	/* Reserved for DECnet project.  */
+#define PF_NETBEUI	13	/* Reserved for 802.2LLC project.  */
+#define PF_SECURITY	14	/* Security callback pseudo AF.  */
+#define PF_KEY		15	/* PF_KEY key management API.  */
+#define PF_NETLINK	16
+#define PF_ROUTE	PF_NETLINK /* Alias to emulate 4.4BSD.  */
+#define PF_PACKET	17	/* Packet family.  */
+#define PF_ASH		18	/* Ash.  */
+#define PF_ECONET	19	/* Acorn Econet.  */
+#define PF_ATMSVC	20	/* ATM SVCs.  */
+#define PF_RDS		21	/* RDS sockets.  */
+#define PF_SNA		22	/* Linux SNA Project */
+#define PF_IRDA		23	/* IRDA sockets.  */
+#define PF_PPPOX	24	/* PPPoX sockets.  */
+#define PF_WANPIPE	25	/* Wanpipe API sockets.  */
+#define PF_LLC		26	/* Linux LLC.  */
+#define PF_IB		27	/* Native InfiniBand address.  */
+#define PF_MPLS		28	/* MPLS.  */
+#define PF_CAN		29	/* Controller Area Network.  */
+#define PF_TIPC		30	/* TIPC sockets.  */
+#define PF_BLUETOOTH	31	/* Bluetooth sockets.  */
+#define PF_IUCV		32	/* IUCV sockets.  */
+#define PF_RXRPC	33	/* RxRPC sockets.  */
+#define PF_ISDN		34	/* mISDN sockets.  */
+#define PF_PHONET	35	/* Phonet sockets.  */
+#define PF_IEEE802154	36	/* IEEE 802.15.4 sockets.  */
+#define PF_CAIF		37	/* CAIF sockets.  */
+#define PF_ALG		38	/* Algorithm sockets.  */
+#define PF_NFC		39	/* NFC sockets.  */
+#define PF_VSOCK	40	/* vSockets.  */
+#define PF_MAX		41	/* For now..  */
+
+/* Address families.  */
+#define AF_UNSPEC	PF_UNSPEC
+#define AF_LOCAL	PF_LOCAL
+#define AF_UNIX		PF_UNIX
+#define AF_FILE		PF_FILE
+#define AF_INET		PF_INET
+#define AF_AX25		PF_AX25
+#define AF_IPX		PF_IPX
+#define AF_APPLETALK	PF_APPLETALK
+#define AF_NETROM	PF_NETROM
+#define AF_BRIDGE	PF_BRIDGE
+#define AF_ATMPVC	PF_ATMPVC
+#define AF_X25		PF_X25
+#define AF_INET6	PF_INET6
+#define AF_ROSE		PF_ROSE
+#define AF_DECnet	PF_DECnet
+#define AF_NETBEUI	PF_NETBEUI
+#define AF_SECURITY	PF_SECURITY
+#define AF_KEY		PF_KEY
+#define AF_NETLINK	PF_NETLINK
+#define AF_ROUTE	PF_ROUTE
+#define AF_PACKET	PF_PACKET
+#define AF_ASH		PF_ASH
+#define AF_ECONET	PF_ECONET
+#define AF_ATMSVC	PF_ATMSVC
+#define AF_RDS		PF_RDS
+#define AF_SNA		PF_SNA
+#define AF_IRDA		PF_IRDA
+#define AF_PPPOX	PF_PPPOX
+#define AF_WANPIPE	PF_WANPIPE
+#define AF_LLC		PF_LLC
+#define AF_IB		PF_IB
+#define AF_MPLS		PF_MPLS
+#define AF_CAN		PF_CAN
+#define AF_TIPC		PF_TIPC
+#define AF_BLUETOOTH	PF_BLUETOOTH
+#define AF_IUCV		PF_IUCV
+#define AF_RXRPC	PF_RXRPC
+#define AF_ISDN		PF_ISDN
+#define AF_PHONET	PF_PHONET
+#define AF_IEEE802154	PF_IEEE802154
+#define AF_CAIF		PF_CAIF
+#define AF_ALG		PF_ALG
+#define AF_NFC		PF_NFC
+#define AF_VSOCK	PF_VSOCK
+#define AF_MAX		PF_MAX
+
+/* Socket level values.  Others are defined in the appropriate headers.
+
+   XXX These definitions also should go into the appropriate headers as
+   far as they are available.  */
+#define SOL_RAW		255
+#define SOL_DECNET      261
+#define SOL_X25         262
+#define SOL_PACKET	263
+#define SOL_ATM		264	/* ATM layer (cell level).  */
+#define SOL_AAL		265	/* ATM Adaption Layer (packet level).  */
+#define SOL_IRDA	266
+
+/* Maximum queue length specifiable by listen.  */
+#define SOMAXCONN	128
+
+/* Get the definition of the macro to define the common sockaddr members.  */
+#include <bits/sockaddr.h>
+
+/* Structure describing a generic socket address.  */
+struct sockaddr
+  {
+    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
+    char sa_data[14];		/* Address data.  */
+  };
+
+
+/* Structure large enough to hold any socket address (with the historical
+   exception of AF_UNIX).  We reserve 128 bytes.  */
+#define __ss_aligntype	unsigned long int
+#define _SS_SIZE	128
+#define _SS_PADSIZE	(_SS_SIZE - (2 * sizeof (__ss_aligntype)))
+
+struct sockaddr_storage
+  {
+    __SOCKADDR_COMMON (ss_);	/* Address family, etc.  */
+    __ss_aligntype __ss_align;	/* Force desired alignment.  */
+    char __ss_padding[_SS_PADSIZE];
+  };
+
+
+/* Bits in the FLAGS argument to `send', `recv', et al.  */
+enum
+  {
+    MSG_OOB		= 0x01,	/* Process out-of-band data.  */
+#define MSG_OOB		MSG_OOB
+    MSG_PEEK		= 0x02,	/* Peek at incoming messages.  */
+#define MSG_PEEK	MSG_PEEK
+    MSG_DONTROUTE	= 0x04,	/* Don't use local routing.  */
+#define MSG_DONTROUTE	MSG_DONTROUTE
+#ifdef __USE_GNU
+    /* DECnet uses a different name.  */
+    MSG_TRYHARD		= MSG_DONTROUTE,
+# define MSG_TRYHARD	MSG_DONTROUTE
+#endif
+    MSG_CTRUNC		= 0x08,	/* Control data lost before delivery.  */
+#define MSG_CTRUNC	MSG_CTRUNC
+    MSG_PROXY		= 0x10,	/* Supply or ask second address.  */
+#define MSG_PROXY	MSG_PROXY
+    MSG_TRUNC		= 0x20,
+#define MSG_TRUNC	MSG_TRUNC
+    MSG_DONTWAIT	= 0x40, /* Nonblocking IO.  */
+#define MSG_DONTWAIT	MSG_DONTWAIT
+    MSG_EOR		= 0x80, /* End of record.  */
+#define MSG_EOR		MSG_EOR
+    MSG_WAITALL		= 0x100, /* Wait for a full request.  */
+#define MSG_WAITALL	MSG_WAITALL
+    MSG_FIN		= 0x200,
+#define MSG_FIN		MSG_FIN
+    MSG_SYN		= 0x400,
+#define MSG_SYN		MSG_SYN
+    MSG_CONFIRM		= 0x800, /* Confirm path validity.  */
+#define MSG_CONFIRM	MSG_CONFIRM
+    MSG_RST		= 0x1000,
+#define MSG_RST		MSG_RST
+    MSG_ERRQUEUE	= 0x2000, /* Fetch message from error queue.  */
+#define MSG_ERRQUEUE	MSG_ERRQUEUE
+    MSG_NOSIGNAL	= 0x4000, /* Do not generate SIGPIPE.  */
+#define MSG_NOSIGNAL	MSG_NOSIGNAL
+    MSG_MORE		= 0x8000,  /* Sender will send more.  */
+#define MSG_MORE	MSG_MORE
+    MSG_WAITFORONE	= 0x10000, /* Wait for at least one packet to return.*/
+#define MSG_WAITFORONE	MSG_WAITFORONE
+    MSG_FASTOPEN	= 0x20000000, /* Send data in TCP SYN.  */
+#define MSG_FASTOPEN	MSG_FASTOPEN
+
+    MSG_CMSG_CLOEXEC	= 0x40000000	/* Set close_on_exit for file
+					   descriptor received through
+					   SCM_RIGHTS.  */
+#define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC
+  };
+
+
+/* Ancillary data object manipulation macros.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
+#else
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+#endif
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
+#define CMSG_FIRSTHDR(mhdr) \
+  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr)		      \
+   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
+			 & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
+			 + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+				      struct cmsghdr *__cmsg) __THROW;
+#ifdef __USE_EXTERN_INLINES
+# ifndef _EXTERN_INLINE
+#  define _EXTERN_INLINE __extern_inline
+# endif
+_EXTERN_INLINE struct cmsghdr *
+__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+{
+  if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+    /* The kernel header does this so there may be a reason.  */
+    return (struct cmsghdr *) 0;
+
+  __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+			       + CMSG_ALIGN (__cmsg->cmsg_len));
+  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+					+ __mhdr->msg_controllen)
+      || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+	  > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+    /* No more entries.  */
+    return (struct cmsghdr *) 0;
+  return __cmsg;
+}
+#endif	/* Use `extern inline'.  */
+
+/* Socket level message types.  This must match the definitions in
+   <linux/socket.h>.  */
+enum
+  {
+    SCM_RIGHTS = 0x01		/* Transfer file descriptors.  */
+#define SCM_RIGHTS SCM_RIGHTS
+#ifdef __USE_GNU
+    , SCM_CREDENTIALS = 0x02	/* Credentials passing.  */
+# define SCM_CREDENTIALS SCM_CREDENTIALS
+#endif
+  };
+
+#ifdef __USE_GNU
+/* User visible structure for SCM_CREDENTIALS message */
+struct ucred
+{
+  pid_t pid;			/* PID of sending process.  */
+  uid_t uid;			/* UID of sending process.  */
+  gid_t gid;			/* GID of sending process.  */
+};
+#endif
+
+/* Ugly workaround for unclean kernel headers.  */
+#ifndef __USE_MISC
+# ifndef FIOGETOWN
+#  define __SYS_SOCKET_H_undef_FIOGETOWN
+# endif
+# ifndef FIOSETOWN
+#  define __SYS_SOCKET_H_undef_FIOSETOWN
+# endif
+# ifndef SIOCATMARK
+#  define __SYS_SOCKET_H_undef_SIOCATMARK
+# endif
+# ifndef SIOCGPGRP
+#  define __SYS_SOCKET_H_undef_SIOCGPGRP
+# endif
+# ifndef SIOCGSTAMP
+#  define __SYS_SOCKET_H_undef_SIOCGSTAMP
+# endif
+# ifndef SIOCGSTAMPNS
+#  define __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+# endif
+# ifndef SIOCSPGRP
+#  define __SYS_SOCKET_H_undef_SIOCSPGRP
+# endif
+#endif
+
+/* Get socket manipulation related informations from kernel headers.  */
+#include <asm/socket.h>
+
+#ifndef __USE_MISC
+# ifdef __SYS_SOCKET_H_undef_FIOGETOWN
+#  undef __SYS_SOCKET_H_undef_FIOGETOWN
+#  undef FIOGETOWN
+# endif
+# ifdef __SYS_SOCKET_H_undef_FIOSETOWN
+#  undef __SYS_SOCKET_H_undef_FIOSETOWN
+#  undef FIOSETOWN
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCATMARK
+#  undef __SYS_SOCKET_H_undef_SIOCATMARK
+#  undef SIOCATMARK
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGPGRP
+#  undef __SYS_SOCKET_H_undef_SIOCGPGRP
+#  undef SIOCGPGRP
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMP
+#  undef __SYS_SOCKET_H_undef_SIOCGSTAMP
+#  undef SIOCGSTAMP
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+#  undef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+#  undef SIOCGSTAMPNS
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCSPGRP
+#  undef __SYS_SOCKET_H_undef_SIOCSPGRP
+#  undef SIOCSPGRP
+# endif
+#endif
+
+/* Structure used to manipulate the SO_LINGER option.  */
+struct linger
+  {
+    int l_onoff;		/* Nonzero to linger on close.  */
+    int l_linger;		/* Time to linger.  */
+  };
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
deleted file mode 100644
index 0581c79..0000000
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/* System-specific socket constants and types.  Linux version.
-   Copyright (C) 1991-2016 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/>.  */
-
-#ifndef __BITS_SOCKET_H
-#define __BITS_SOCKET_H
-
-#ifndef _SYS_SOCKET_H
-# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
-#endif
-
-#define __need_size_t
-#include <stddef.h>
-
-#include <sys/types.h>
-
-/* Type for length arguments in socket calls.  */
-#ifndef __socklen_t_defined
-typedef __socklen_t socklen_t;
-# define __socklen_t_defined
-#endif
-
-/* Get the architecture-dependent definition of enum __socket_type.  */
-#include <bits/socket_type.h>
-
-/* Protocol families.  */
-#define PF_UNSPEC	0	/* Unspecified.  */
-#define PF_LOCAL	1	/* Local to host (pipes and file-domain).  */
-#define PF_UNIX		PF_LOCAL /* POSIX name for PF_LOCAL.  */
-#define PF_FILE		PF_LOCAL /* Another non-standard name for PF_LOCAL.  */
-#define PF_INET		2	/* IP protocol family.  */
-#define PF_AX25		3	/* Amateur Radio AX.25.  */
-#define PF_IPX		4	/* Novell Internet Protocol.  */
-#define PF_APPLETALK	5	/* Appletalk DDP.  */
-#define PF_NETROM	6	/* Amateur radio NetROM.  */
-#define PF_BRIDGE	7	/* Multiprotocol bridge.  */
-#define PF_ATMPVC	8	/* ATM PVCs.  */
-#define PF_X25		9	/* Reserved for X.25 project.  */
-#define PF_INET6	10	/* IP version 6.  */
-#define PF_ROSE		11	/* Amateur Radio X.25 PLP.  */
-#define PF_DECnet	12	/* Reserved for DECnet project.  */
-#define PF_NETBEUI	13	/* Reserved for 802.2LLC project.  */
-#define PF_SECURITY	14	/* Security callback pseudo AF.  */
-#define PF_KEY		15	/* PF_KEY key management API.  */
-#define PF_NETLINK	16
-#define PF_ROUTE	PF_NETLINK /* Alias to emulate 4.4BSD.  */
-#define PF_PACKET	17	/* Packet family.  */
-#define PF_ASH		18	/* Ash.  */
-#define PF_ECONET	19	/* Acorn Econet.  */
-#define PF_ATMSVC	20	/* ATM SVCs.  */
-#define PF_RDS		21	/* RDS sockets.  */
-#define PF_SNA		22	/* Linux SNA Project */
-#define PF_IRDA		23	/* IRDA sockets.  */
-#define PF_PPPOX	24	/* PPPoX sockets.  */
-#define PF_WANPIPE	25	/* Wanpipe API sockets.  */
-#define PF_LLC		26	/* Linux LLC.  */
-#define PF_IB		27	/* Native InfiniBand address.  */
-#define PF_MPLS		28	/* MPLS.  */
-#define PF_CAN		29	/* Controller Area Network.  */
-#define PF_TIPC		30	/* TIPC sockets.  */
-#define PF_BLUETOOTH	31	/* Bluetooth sockets.  */
-#define PF_IUCV		32	/* IUCV sockets.  */
-#define PF_RXRPC	33	/* RxRPC sockets.  */
-#define PF_ISDN		34	/* mISDN sockets.  */
-#define PF_PHONET	35	/* Phonet sockets.  */
-#define PF_IEEE802154	36	/* IEEE 802.15.4 sockets.  */
-#define PF_CAIF		37	/* CAIF sockets.  */
-#define PF_ALG		38	/* Algorithm sockets.  */
-#define PF_NFC		39	/* NFC sockets.  */
-#define PF_VSOCK	40	/* vSockets.  */
-#define PF_MAX		41	/* For now..  */
-
-/* Address families.  */
-#define AF_UNSPEC	PF_UNSPEC
-#define AF_LOCAL	PF_LOCAL
-#define AF_UNIX		PF_UNIX
-#define AF_FILE		PF_FILE
-#define AF_INET		PF_INET
-#define AF_AX25		PF_AX25
-#define AF_IPX		PF_IPX
-#define AF_APPLETALK	PF_APPLETALK
-#define AF_NETROM	PF_NETROM
-#define AF_BRIDGE	PF_BRIDGE
-#define AF_ATMPVC	PF_ATMPVC
-#define AF_X25		PF_X25
-#define AF_INET6	PF_INET6
-#define AF_ROSE		PF_ROSE
-#define AF_DECnet	PF_DECnet
-#define AF_NETBEUI	PF_NETBEUI
-#define AF_SECURITY	PF_SECURITY
-#define AF_KEY		PF_KEY
-#define AF_NETLINK	PF_NETLINK
-#define AF_ROUTE	PF_ROUTE
-#define AF_PACKET	PF_PACKET
-#define AF_ASH		PF_ASH
-#define AF_ECONET	PF_ECONET
-#define AF_ATMSVC	PF_ATMSVC
-#define AF_RDS		PF_RDS
-#define AF_SNA		PF_SNA
-#define AF_IRDA		PF_IRDA
-#define AF_PPPOX	PF_PPPOX
-#define AF_WANPIPE	PF_WANPIPE
-#define AF_LLC		PF_LLC
-#define AF_IB		PF_IB
-#define AF_MPLS		PF_MPLS
-#define AF_CAN		PF_CAN
-#define AF_TIPC		PF_TIPC
-#define AF_BLUETOOTH	PF_BLUETOOTH
-#define AF_IUCV		PF_IUCV
-#define AF_RXRPC	PF_RXRPC
-#define AF_ISDN		PF_ISDN
-#define AF_PHONET	PF_PHONET
-#define AF_IEEE802154	PF_IEEE802154
-#define AF_CAIF		PF_CAIF
-#define AF_ALG		PF_ALG
-#define AF_NFC		PF_NFC
-#define AF_VSOCK	PF_VSOCK
-#define AF_MAX		PF_MAX
-
-/* Socket level values.  Others are defined in the appropriate headers.
-
-   XXX These definitions also should go into the appropriate headers as
-   far as they are available.  */
-#define SOL_RAW		255
-#define SOL_DECNET      261
-#define SOL_X25         262
-#define SOL_PACKET	263
-#define SOL_ATM		264	/* ATM layer (cell level).  */
-#define SOL_AAL		265	/* ATM Adaption Layer (packet level).  */
-#define SOL_IRDA	266
-
-/* Maximum queue length specifiable by listen.  */
-#define SOMAXCONN	128
-
-/* Get the definition of the macro to define the common sockaddr members.  */
-#include <bits/sockaddr.h>
-
-/* Structure describing a generic socket address.  */
-struct sockaddr
-  {
-    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
-    char sa_data[14];		/* Address data.  */
-  };
-
-
-/* Structure large enough to hold any socket address (with the historical
-   exception of AF_UNIX).  We reserve 128 bytes.  */
-#define __ss_aligntype	unsigned long int
-#define _SS_SIZE	128
-#define _SS_PADSIZE	(_SS_SIZE - (2 * sizeof (__ss_aligntype)))
-
-struct sockaddr_storage
-  {
-    __SOCKADDR_COMMON (ss_);	/* Address family, etc.  */
-    __ss_aligntype __ss_align;	/* Force desired alignment.  */
-    char __ss_padding[_SS_PADSIZE];
-  };
-
-
-/* Bits in the FLAGS argument to `send', `recv', et al.  */
-enum
-  {
-    MSG_OOB		= 0x01,	/* Process out-of-band data.  */
-#define MSG_OOB		MSG_OOB
-    MSG_PEEK		= 0x02,	/* Peek at incoming messages.  */
-#define MSG_PEEK	MSG_PEEK
-    MSG_DONTROUTE	= 0x04,	/* Don't use local routing.  */
-#define MSG_DONTROUTE	MSG_DONTROUTE
-#ifdef __USE_GNU
-    /* DECnet uses a different name.  */
-    MSG_TRYHARD		= MSG_DONTROUTE,
-# define MSG_TRYHARD	MSG_DONTROUTE
-#endif
-    MSG_CTRUNC		= 0x08,	/* Control data lost before delivery.  */
-#define MSG_CTRUNC	MSG_CTRUNC
-    MSG_PROXY		= 0x10,	/* Supply or ask second address.  */
-#define MSG_PROXY	MSG_PROXY
-    MSG_TRUNC		= 0x20,
-#define MSG_TRUNC	MSG_TRUNC
-    MSG_DONTWAIT	= 0x40, /* Nonblocking IO.  */
-#define MSG_DONTWAIT	MSG_DONTWAIT
-    MSG_EOR		= 0x80, /* End of record.  */
-#define MSG_EOR		MSG_EOR
-    MSG_WAITALL		= 0x100, /* Wait for a full request.  */
-#define MSG_WAITALL	MSG_WAITALL
-    MSG_FIN		= 0x200,
-#define MSG_FIN		MSG_FIN
-    MSG_SYN		= 0x400,
-#define MSG_SYN		MSG_SYN
-    MSG_CONFIRM		= 0x800, /* Confirm path validity.  */
-#define MSG_CONFIRM	MSG_CONFIRM
-    MSG_RST		= 0x1000,
-#define MSG_RST		MSG_RST
-    MSG_ERRQUEUE	= 0x2000, /* Fetch message from error queue.  */
-#define MSG_ERRQUEUE	MSG_ERRQUEUE
-    MSG_NOSIGNAL	= 0x4000, /* Do not generate SIGPIPE.  */
-#define MSG_NOSIGNAL	MSG_NOSIGNAL
-    MSG_MORE		= 0x8000,  /* Sender will send more.  */
-#define MSG_MORE	MSG_MORE
-    MSG_WAITFORONE	= 0x10000, /* Wait for at least one packet to return.*/
-#define MSG_WAITFORONE	MSG_WAITFORONE
-    MSG_FASTOPEN	= 0x20000000, /* Send data in TCP SYN.  */
-#define MSG_FASTOPEN	MSG_FASTOPEN
-
-    MSG_CMSG_CLOEXEC	= 0x40000000	/* Set close_on_exit for file
-					   descriptor received through
-					   SCM_RIGHTS.  */
-#define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC
-  };
-
-
-/* Structure describing messages sent by
-   `sendmsg' and received by `recvmsg'.  */
-struct msghdr
-  {
-    void *msg_name;		/* Address to send to/receive from.  */
-    socklen_t msg_namelen;	/* Length of address data.  */
-
-    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
-
-    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
-
-    int msg_flags;		/* Flags on received message.  */
-  };
-
-/* Structure used for storage of ancillary data object information.  */
-struct cmsghdr
-  {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
-    int cmsg_level;		/* Originating protocol.  */
-    int cmsg_type;		/* Protocol specific type.  */
-#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
-    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
-#endif
-  };
-
-/* Ancillary data object manipulation macros.  */
-#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
-# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
-#else
-# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
-#endif
-#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
-#define CMSG_FIRSTHDR(mhdr) \
-  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr)		      \
-   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
-#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
-			 & (size_t) ~(sizeof (size_t) - 1))
-#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
-			 + CMSG_ALIGN (sizeof (struct cmsghdr)))
-#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
-
-extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
-				      struct cmsghdr *__cmsg) __THROW;
-#ifdef __USE_EXTERN_INLINES
-# ifndef _EXTERN_INLINE
-#  define _EXTERN_INLINE __extern_inline
-# endif
-_EXTERN_INLINE struct cmsghdr *
-__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
-{
-  if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
-    /* The kernel header does this so there may be a reason.  */
-    return (struct cmsghdr *) 0;
-
-  __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
-			       + CMSG_ALIGN (__cmsg->cmsg_len));
-  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
-					+ __mhdr->msg_controllen)
-      || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
-	  > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
-    /* No more entries.  */
-    return (struct cmsghdr *) 0;
-  return __cmsg;
-}
-#endif	/* Use `extern inline'.  */
-
-/* Socket level message types.  This must match the definitions in
-   <linux/socket.h>.  */
-enum
-  {
-    SCM_RIGHTS = 0x01		/* Transfer file descriptors.  */
-#define SCM_RIGHTS SCM_RIGHTS
-#ifdef __USE_GNU
-    , SCM_CREDENTIALS = 0x02	/* Credentials passing.  */
-# define SCM_CREDENTIALS SCM_CREDENTIALS
-#endif
-  };
-
-#ifdef __USE_GNU
-/* User visible structure for SCM_CREDENTIALS message */
-struct ucred
-{
-  pid_t pid;			/* PID of sending process.  */
-  uid_t uid;			/* UID of sending process.  */
-  gid_t gid;			/* GID of sending process.  */
-};
-#endif
-
-/* Ugly workaround for unclean kernel headers.  */
-#ifndef __USE_MISC
-# ifndef FIOGETOWN
-#  define __SYS_SOCKET_H_undef_FIOGETOWN
-# endif
-# ifndef FIOSETOWN
-#  define __SYS_SOCKET_H_undef_FIOSETOWN
-# endif
-# ifndef SIOCATMARK
-#  define __SYS_SOCKET_H_undef_SIOCATMARK
-# endif
-# ifndef SIOCGPGRP
-#  define __SYS_SOCKET_H_undef_SIOCGPGRP
-# endif
-# ifndef SIOCGSTAMP
-#  define __SYS_SOCKET_H_undef_SIOCGSTAMP
-# endif
-# ifndef SIOCGSTAMPNS
-#  define __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-# endif
-# ifndef SIOCSPGRP
-#  define __SYS_SOCKET_H_undef_SIOCSPGRP
-# endif
-#endif
-
-/* Get socket manipulation related informations from kernel headers.  */
-#include <asm/socket.h>
-
-#ifndef __USE_MISC
-# ifdef __SYS_SOCKET_H_undef_FIOGETOWN
-#  undef __SYS_SOCKET_H_undef_FIOGETOWN
-#  undef FIOGETOWN
-# endif
-# ifdef __SYS_SOCKET_H_undef_FIOSETOWN
-#  undef __SYS_SOCKET_H_undef_FIOSETOWN
-#  undef FIOSETOWN
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCATMARK
-#  undef __SYS_SOCKET_H_undef_SIOCATMARK
-#  undef SIOCATMARK
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGPGRP
-#  undef __SYS_SOCKET_H_undef_SIOCGPGRP
-#  undef SIOCGPGRP
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMP
-#  undef __SYS_SOCKET_H_undef_SIOCGSTAMP
-#  undef SIOCGSTAMP
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-#  undef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-#  undef SIOCGSTAMPNS
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCSPGRP
-#  undef __SYS_SOCKET_H_undef_SIOCSPGRP
-#  undef SIOCSPGRP
-# endif
-#endif
-
-/* Structure used to manipulate the SO_LINGER option.  */
-struct linger
-  {
-    int l_onoff;		/* Nonzero to linger on close.  */
-    int l_linger;		/* Time to linger.  */
-  };
-
-#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket.h b/sysdeps/unix/sysv/linux/hppa/bits/socket.h
new file mode 100644
index 0000000..4702324
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  HPPA Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_HPPA_SOCKET_H
+#define __BITS_HPPA_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/i386/bits/socket.h b/sysdeps/unix/sysv/linux/i386/bits/socket.h
new file mode 100644
index 0000000..2ce4737
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/bits/socket.h
@@ -0,0 +1,71 @@
+/* System-specific socket constants and types.  i386 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_I386_SOCKET_H
+#define __BITS_I386_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/socket.h b/sysdeps/unix/sysv/linux/ia64/bits/socket.h
new file mode 100644
index 0000000..9606973
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  IA64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_IA64_SOCKET_H
+#define __BITS_IA64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/m68k/bits/socket.h b/sysdeps/unix/sysv/linux/m68k/bits/socket.h
new file mode 100644
index 0000000..7048cc5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  m68k Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_M68K_SOCKET_H
+#define __BITS_M68K_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/socket.h b/sysdeps/unix/sysv/linux/microblaze/bits/socket.h
new file mode 100644
index 0000000..57ff1d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/bits/socket.h
@@ -0,0 +1,71 @@
+/* System-specific socket constants and types.  Microblaze Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_MICROBLAZE_SOCKET_H
+#define __BITS_MICROBLAZE_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h b/sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h
new file mode 100644
index 0000000..ac59a9f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  MIPS32 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_MIPS32_SOCKET_H
+#define __BITS_MIPS32_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h b/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
new file mode 100644
index 0000000..f5f735d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  MIPS64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_MIPS64_SOCKET_H
+#define __BITS_MIPS64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/nios2/bits/socket.h b/sysdeps/unix/sysv/linux/nios2/bits/socket.h
new file mode 100644
index 0000000..eaa51e8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nios2/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  NIOS2 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_NIOS2_SOCKET_H
+#define __BITS_NIOS2_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h
new file mode 100644
index 0000000..9e128d7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  PowerPC32 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_POWERPC32_SOCKET_H
+#define __BITS_POWERPC32_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
new file mode 100644
index 0000000..008f34a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  PowerPC64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_POWERPC64_SOCKET_H
+#define __BITS_POWERPC64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h b/sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h
new file mode 100644
index 0000000..ead5727
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  S390 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_S390_SOCKET_H
+#define __BITS_S390_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h b/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
new file mode 100644
index 0000000..3b7fe04
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  S390x Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_S390X_SOCKET_H
+#define __BITS_S390X_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/sh/bits/socket.h b/sysdeps/unix/sysv/linux/sh/bits/socket.h
new file mode 100644
index 0000000..04008ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  SH Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_SH_SOCKET_H
+#define __BITS_SH_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h b/sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h
new file mode 100644
index 0000000..85e6d12
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  SPARC32 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_SPARC32_SOCKET_H
+#define __BITS_SPARC32_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
new file mode 100644
index 0000000..2910f68
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  SPARC64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_SPARC64_SOCKET_H
+#define __BITS_SPARC64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h b/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
new file mode 100644
index 0000000..b434819
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  TileGX Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_TILEGX_SOCKET_H
+#define __BITS_TILEGX_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h b/sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h
new file mode 100644
index 0000000..9bf74f2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/bits/socket.h
@@ -0,0 +1,64 @@
+/* System-specific socket constants and types.  Tile Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_TILE_SOCKET_H
+#define __BITS_TILE_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by `sendmsg' and received by 
+   `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/socket.h b/sysdeps/unix/sysv/linux/x86_64/bits/socket.h
new file mode 100644
index 0000000..ab935f5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/socket.h
@@ -0,0 +1,69 @@
+/* System-specific socket constants and types.  x86_64 Linux.
+   Copyright (C) 2016 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/>.  */
+
+#ifndef __BITS_X86_64_SOCKET_H
+#define __BITS_X86_64_SOCKET_H
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Type for length arguments in socket calls.  */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Structure describing messages sent by
+   `sendmsg' and received by `recvmsg'.  */
+struct msghdr
+  {
+    void *msg_name;		/* Address to send to/receive from.  */
+    socklen_t msg_namelen;	/* Length of address data.  */
+
+    struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
+    size_t msg_iovlen;		/* Number of elements in the vector.  */
+
+    void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
+    size_t msg_controllen;	/* Ancillary data buffer length.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+
+    int msg_flags;		/* Flags on received message.  */
+  };
+
+/* Structure used for storage of ancillary data object information.  */
+struct cmsghdr
+  {
+    size_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.
+				   !! The type should be socklen_t but the
+				   definition of the kernel is incompatible
+				   with this.  */
+    int cmsg_level;		/* Originating protocol.  */
+    int cmsg_type;		/* Protocol specific type.  */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
+#endif
+  };
+
+/* Include generic Linux declarations.  */
+#include <bits/socket-linux.h>
+
+#endif	/* bits/socket.h */
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/4] network: recvmsg and sendmsg standard compliance (BZ#16919)
  2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
  2016-03-21 20:41 ` [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg Adhemerval Zanella
  2016-03-21 20:42 ` [PATCH 1/4] Add architecture specific socket.h header Adhemerval Zanella
@ 2016-03-21 20:42 ` Adhemerval Zanella
  2016-03-21 20:42 ` [PATCH 4/4] network: recvmmsg and sendmmsg " Adhemerval Zanella
  2016-03-21 21:24 ` [PATCH 0/4] Fix {recv,send}{m}msg " Adhemerval Zanella
  4 siblings, 0 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 20:42 UTC (permalink / raw)
  To: libc-alpha

POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
to be of size int and socklen_t respectively.  However Linux defines it as
both size_t and for 64-bit it requires some adjustments to make the
functions standard compliance.

This patch fixes it by creating a temporary header and zeroing the pad
fields for 64-bits architecture where size of size_t exceeds the size of
the int.  Also for such architectures the old recvmsg and sendmsg is
exported as a compatibility version.

Tested on x86_64, i686, aarch64, armhf, and powerpc64le.

	* conform/data/sys/socket.h-data (msghdr.msg_iovlen): Remove xfail-
	and change to correct expected type.
	(msghdr.msg_controllen): Likewise.
	(cmsghdr.cmsg_len): Likewise.
	* nptl/Makefile (libpthread-routines): Add ptw-oldrecvmsg and
	ptw-oldsendmsg.
	* sysdeps/unix/sysv/linux/aarch64/Version [libc] (GLIBC_2.24):
	Add recvmsg and sendmsg.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/alpha/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/ia64/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions [libc]
	(GLIBC_2.24): Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions [libc]
	(GLIBC_2.24): Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/x84_64/Versions [libc] (GLIBC_2.24):
	Likewise.
	[libpthread] (GLIBC_2.24): Likewise.
	* sysdeps/unix/sysv/linux/Makefile
	[$(subdir) = socket)] (sysdep_headers): Add oldrecvmsg and oldsendmsg.
	* sysdeps/unix/sysv/linux/aarch64/bits/socket.h (msghdr.msg_iovlen):
	Fix expected POSIX assumption about the size.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/alpha/bits/socket.h (msghdr.msg_iovlen):
	Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/ia64/bits/socket.h (msghdr.msg_iovlen):
	Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
	(msghdr.msg_iovlen): Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
	(msghdr.msg_iovlen): Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
	(msghdr.msg_iovlen): Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
	(msghdr.msg_iovlen): Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
	(msghdr.msg_iovlen): Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/bits/socket.h (msghdr.msg_iovlen):
	Likewise.
	(msghdr.msg_controllen): Likewise.
	(msghdr.__glibc_reserved1): Likewise.
	(msghdr.__glibc_reserved2): Likewise.
	* sysdeps/unix/sysv/linux/check_native.c (__check_native): Fix msghdr
	initialization.
	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Likewise.
	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Likewise.
	* sysdeps/unix/sysv/linux/oldrecvmsg.c: New file.
	* sysdeps/unix/sysv/linux/oldsendmsg.c: Likewise.
	* sysdeps/unix/sysv/linux/recvmsg.c (__libc_recvmsg): Adjust msghdr
	iovlen and controllen fields to adjust to POSIX specification.
	* sysdeps/unix/sysv/linux/sendmsg.c (__libc_sendmsg): Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libc.abilist: New version and
	added recvmsg and sendmsg.
	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise.
	* sysdepe/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libpthread.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist: Likewise.
---
 conform/data/sys/socket.h-data                     |   8 +-
 nptl/Makefile                                      |   1 +
 sysdeps/unix/sysv/linux/Makefile                   |   2 +-
 sysdeps/unix/sysv/linux/aarch64/Versions           |   9 +
 sysdeps/unix/sysv/linux/aarch64/bits/socket.h      |  38 ++-
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |   3 +
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist |   3 +
 sysdeps/unix/sysv/linux/alpha/Versions             |   6 +
 sysdeps/unix/sysv/linux/alpha/bits/socket.h        |  17 +-
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |   3 +
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist   |   3 +
 sysdeps/unix/sysv/linux/check_native.c             |  11 +-
 sysdeps/unix/sysv/linux/check_pf.c                 |  11 +-
 sysdeps/unix/sysv/linux/ia64/Versions              |   6 +
 sysdeps/unix/sysv/linux/ia64/bits/socket.h         |  21 +-
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |   3 +
 sysdeps/unix/sysv/linux/ifaddrs.c                  |  11 +-
 sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h  |  38 ++-
 .../unix/sysv/linux/mips/mips64/libpthread.abilist |   3 +
 .../sysv/linux/mips/mips64/n32/libpthread.abilist  | 256 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips64/n64/Versions   |  10 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/oldrecvmsg.c               |  42 ++++
 sysdeps/unix/sysv/linux/oldsendmsg.c               |  42 ++++
 sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions |   6 +
 .../sysv/linux/powerpc/powerpc64/bits/socket.h     |  38 ++-
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |   3 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |   3 +
 .../linux/powerpc/powerpc64/libpthread-le.abilist  |   3 +
 .../linux/powerpc/powerpc64/libpthread.abilist     |   3 +
 sysdeps/unix/sysv/linux/recvmsg.c                  |  40 +++-
 sysdeps/unix/sysv/linux/s390/s390-64/Versions      |   9 +
 sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h |  21 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |   3 +
 .../sysv/linux/s390/s390-64/libpthread.abilist     |   3 +
 sysdeps/unix/sysv/linux/sendmsg.c                  |  27 ++-
 sysdeps/unix/sysv/linux/sparc/sparc64/Versions     |   9 +
 .../unix/sysv/linux/sparc/sparc64/bits/socket.h    |  21 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |   3 +
 .../sysv/linux/sparc/sparc64/libpthread.abilist    |   3 +
 sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h  |  38 ++-
 .../unix/sysv/linux/tile/tilegx/tilegx64/Versions  |   5 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |   3 +
 .../linux/tile/tilegx/tilegx64/libpthread.abilist  |   3 +
 sysdeps/unix/sysv/linux/x86_64/64/Versions         |  10 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |   3 +
 .../unix/sysv/linux/x86_64/64/libpthread.abilist   |   3 +
 sysdeps/unix/sysv/linux/x86_64/bits/socket.h       |  21 +-
 50 files changed, 826 insertions(+), 122 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libpthread.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/Versions
 create mode 100644 sysdeps/unix/sysv/linux/oldrecvmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/oldsendmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/Versions

diff --git a/conform/data/sys/socket.h-data b/conform/data/sys/socket.h-data
index 442d4d2..3a6cf7c 100644
--- a/conform/data/sys/socket.h-data
+++ b/conform/data/sys/socket.h-data
@@ -22,10 +22,9 @@ type {struct msghdr}
 element {struct msghdr} {void*} msg_name
 element {struct msghdr} socklen_t msg_namelen
 element {struct msghdr} {struct iovec*} msg_iov
-// Bug 16919: wrong type for msg_iovlen and msg_controllen members.
-xfail-element {struct msghdr} int msg_iovlen
+element {struct msghdr} int msg_iovlen
 element {struct msghdr} {void*} msg_control
-xfail-element {struct msghdr} socklen_t msg_controllen
+element {struct msghdr} socklen_t msg_controllen
 element {struct msghdr} int msg_flags
 
 type {struct iovec}
@@ -35,8 +34,7 @@ element {struct iovec} size_t iov_len
 
 type {struct cmsghdr}
 
-// Bug 16919: wrong type for cmsg_len member.
-xfail-element {struct cmsghdr} socklen_t cmsg_len
+element {struct cmsghdr} socklen_t cmsg_len
 element {struct cmsghdr} int cmsg_level
 element {struct cmsghdr} int cmsg_type
 
diff --git a/nptl/Makefile b/nptl/Makefile
index dc3ccab..28604f6 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -115,6 +115,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
 		      ptw-pread ptw-pread64 ptw-pwrite ptw-pwrite64 \
 		      ptw-tcdrain ptw-wait ptw-waitpid ptw-msgrcv ptw-msgsnd \
 		      ptw-sigwait ptw-sigsuspend \
+		      ptw-oldrecvmsg ptw-oldsendmsg \
 		      pt-raise pt-system \
 		      flockfile ftrylockfile funlockfile \
 		      sigaction \
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index b75a53b..4475a5c 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -124,7 +124,7 @@ ifeq ($(subdir),socket)
 sysdep_headers += net/if_ppp.h net/ppp-comp.h \
 		  net/ppp_defs.h net/if_arp.h net/route.h net/ethernet.h \
 		  net/if_slip.h net/if_packet.h net/if_shaper.h
-sysdep_routines += cmsg_nxthdr
+sysdep_routines += cmsg_nxthdr oldrecvmsg oldsendmsg
 endif
 
 ifeq ($(subdir),sunrpc)
diff --git a/sysdeps/unix/sysv/linux/aarch64/Versions b/sysdeps/unix/sysv/linux/aarch64/Versions
index 9bd87fe..73ca6fc 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Versions
+++ b/sysdeps/unix/sysv/linux/aarch64/Versions
@@ -5,8 +5,17 @@ ld {
   }
 }
 libc {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+
   GLIBC_PRIVATE {
     __vdso_clock_gettime;
     __vdso_clock_getres;
   }
 }
+libpthread {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/socket.h b/sysdeps/unix/sysv/linux/aarch64/bits/socket.h
index 7f6bf84..37cf719 100644
--- a/sysdeps/unix/sysv/linux/aarch64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/socket.h
@@ -23,6 +23,8 @@
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <endian.h>
+
 /* Type for length arguments in socket calls.  */
 #ifndef __socklen_t_defined
 typedef __socklen_t socklen_t;
@@ -37,13 +39,24 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+#else
+    int msg_iovlen;
+    int __glibc_reserved1;
+#endif
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+#else
+    socklen_t msg_controllen;
+    int __glibc_reserved2;
+#endif
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +64,16 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 5799239..c3f2346 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2087,3 +2087,6 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 0cf30ee..e33401a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -224,3 +224,6 @@ GLIBC_2.17 write F
 GLIBC_2.18 GLIBC_2.18 A
 GLIBC_2.18 pthread_getattr_default_np F
 GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/alpha/Versions b/sysdeps/unix/sysv/linux/alpha/Versions
index 29b82f9..72fac79 100644
--- a/sysdeps/unix/sysv/linux/alpha/Versions
+++ b/sysdeps/unix/sysv/linux/alpha/Versions
@@ -85,6 +85,9 @@ libc {
     #errlist-compat	140
     _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
   GLIBC_PRIVATE {
     __libc_alpha_cache_shape;
   }
@@ -99,6 +102,9 @@ libpthread {
     # Changed PTHREAD_STACK_MIN.
     pthread_attr_setstack; pthread_attr_setstacksize;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 librt {
   GLIBC_2.3 {
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/socket.h b/sysdeps/unix/sysv/linux/alpha/bits/socket.h
index bec9330..833ae5f 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/socket.h
@@ -37,13 +37,12 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+    int msg_iovlen;
+    int __glibc_reserved1;
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t msg_controllen;
+    int __glibc_reserved2;
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +50,9 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 0fa4ee9..7822242 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -1998,6 +1998,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index 7e121d4..65cb648 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -216,6 +216,9 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
 GLIBC_2.2.3 pthread_getattr_np F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/check_native.c b/sysdeps/unix/sysv/linux/check_native.c
index b3cbbe3..a8e447e 100644
--- a/sysdeps/unix/sysv/linux/check_native.c
+++ b/sysdeps/unix/sysv/linux/check_native.c
@@ -111,10 +111,13 @@ __check_native (uint32_t a1_index, int *a1_native,
     {
       struct msghdr msg =
 	{
-	  (void *) &nladdr, sizeof (nladdr),
-	  &iov, 1,
-	  NULL, 0,
-	  0
+	  .msg_name = (void *) &nladdr,
+	  .msg_namelen =  sizeof (nladdr),
+	  .msg_iov = &iov,
+	  .msg_iovlen = 1,
+	  .msg_control = NULL,
+	  .msg_controllen = 0,
+	  .msg_flags = 0
 	};
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index d55953a..89e9031 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -158,10 +158,13 @@ make_request (int fd, pid_t pid)
     {
       struct msghdr msg =
 	{
-	  (void *) &nladdr, sizeof (nladdr),
-	  &iov, 1,
-	  NULL, 0,
-	  0
+	  .msg_name = (void *) &nladdr,
+	  .msg_namelen =  sizeof (nladdr),
+	  .msg_iov = &iov,
+	  .msg_iovlen = 1,
+	  .msg_control = NULL,
+	  .msg_controllen = 0,
+	  .msg_flags = 0
 	};
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
diff --git a/sysdeps/unix/sysv/linux/ia64/Versions b/sysdeps/unix/sysv/linux/ia64/Versions
index b38d6ef..cac811c 100644
--- a/sysdeps/unix/sysv/linux/ia64/Versions
+++ b/sysdeps/unix/sysv/linux/ia64/Versions
@@ -22,12 +22,18 @@ libc {
   GLIBC_2.2.6 {
     getunwind;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 libpthread {
   GLIBC_2.3.3 {
     # Changed PTHREAD_STACK_MIN.
     pthread_attr_setstack; pthread_attr_setstacksize;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 librt {
   GLIBC_2.3.3 {
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/socket.h b/sysdeps/unix/sysv/linux/ia64/bits/socket.h
index 9606973..fa12404 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/socket.h
@@ -37,13 +37,14 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +52,11 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 921ec55..f5739b4 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1874,6 +1874,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index d4c8ded..0f3c4c2 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -204,6 +204,9 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
 GLIBC_2.2.3 pthread_getattr_np F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index ca38d1a..54f1124 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -161,10 +161,13 @@ __netlink_request (struct netlink_handle *h, int type)
     {
       struct msghdr msg =
 	{
-	  (void *) &nladdr, sizeof (nladdr),
-	  &iov, 1,
-	  NULL, 0,
-	  0
+	  .msg_name = (void *) &nladdr,
+	  .msg_namelen =  sizeof (nladdr),
+	  .msg_iov = &iov,
+	  .msg_iovlen = 1,
+	  .msg_control = NULL,
+	  .msg_controllen = 0,
+	  .msg_flags = 0
 	};
 
       read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h b/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
index f5f735d..46235c0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/bits/socket.h
@@ -23,6 +23,8 @@
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <endian.h>
+
 /* Type for length arguments in socket calls.  */
 #ifndef __socklen_t_defined
 typedef __socklen_t socklen_t;
@@ -37,13 +39,24 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+#else
+    int msg_iovlen;
+    int __glibc_reserved1;
+#endif
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+#else
+    socklen_t msg_controllen;
+    int __glibc_reserved2;
+#endif
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +64,16 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index ad55bdd..6098136 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -213,6 +213,9 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
 GLIBC_2.2.3 pthread_getattr_np F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libpthread.abilist
new file mode 100644
index 0000000..ad55bdd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libpthread.abilist
@@ -0,0 +1,256 @@
+GLIBC_2.0 GLIBC_2.0 A
+GLIBC_2.0 _IO_flockfile F
+GLIBC_2.0 _IO_ftrylockfile F
+GLIBC_2.0 _IO_funlockfile F
+GLIBC_2.0 __close F
+GLIBC_2.0 __connect F
+GLIBC_2.0 __errno_location F
+GLIBC_2.0 __fcntl F
+GLIBC_2.0 __fork F
+GLIBC_2.0 __h_errno_location F
+GLIBC_2.0 __lseek F
+GLIBC_2.0 __open F
+GLIBC_2.0 __pthread_getspecific F
+GLIBC_2.0 __pthread_key_create F
+GLIBC_2.0 __pthread_mutex_destroy F
+GLIBC_2.0 __pthread_mutex_init F
+GLIBC_2.0 __pthread_mutex_lock F
+GLIBC_2.0 __pthread_mutex_trylock F
+GLIBC_2.0 __pthread_mutex_unlock F
+GLIBC_2.0 __pthread_mutexattr_destroy F
+GLIBC_2.0 __pthread_mutexattr_init F
+GLIBC_2.0 __pthread_mutexattr_settype F
+GLIBC_2.0 __pthread_once F
+GLIBC_2.0 __pthread_setspecific F
+GLIBC_2.0 __read F
+GLIBC_2.0 __send F
+GLIBC_2.0 __sigaction F
+GLIBC_2.0 __wait F
+GLIBC_2.0 __write F
+GLIBC_2.0 _pthread_cleanup_pop F
+GLIBC_2.0 _pthread_cleanup_pop_restore F
+GLIBC_2.0 _pthread_cleanup_push F
+GLIBC_2.0 _pthread_cleanup_push_defer F
+GLIBC_2.0 accept F
+GLIBC_2.0 close F
+GLIBC_2.0 connect F
+GLIBC_2.0 fcntl F
+GLIBC_2.0 flockfile F
+GLIBC_2.0 fork F
+GLIBC_2.0 fsync F
+GLIBC_2.0 ftrylockfile F
+GLIBC_2.0 funlockfile F
+GLIBC_2.0 longjmp F
+GLIBC_2.0 lseek F
+GLIBC_2.0 msync F
+GLIBC_2.0 nanosleep F
+GLIBC_2.0 open F
+GLIBC_2.0 pause F
+GLIBC_2.0 pthread_atfork F
+GLIBC_2.0 pthread_attr_destroy F
+GLIBC_2.0 pthread_attr_getdetachstate F
+GLIBC_2.0 pthread_attr_getinheritsched F
+GLIBC_2.0 pthread_attr_getschedparam F
+GLIBC_2.0 pthread_attr_getschedpolicy F
+GLIBC_2.0 pthread_attr_getscope F
+GLIBC_2.0 pthread_attr_init F
+GLIBC_2.0 pthread_attr_setdetachstate F
+GLIBC_2.0 pthread_attr_setinheritsched F
+GLIBC_2.0 pthread_attr_setschedparam F
+GLIBC_2.0 pthread_attr_setschedpolicy F
+GLIBC_2.0 pthread_attr_setscope F
+GLIBC_2.0 pthread_cancel F
+GLIBC_2.0 pthread_cond_broadcast F
+GLIBC_2.0 pthread_cond_destroy F
+GLIBC_2.0 pthread_cond_init F
+GLIBC_2.0 pthread_cond_signal F
+GLIBC_2.0 pthread_cond_timedwait F
+GLIBC_2.0 pthread_cond_wait F
+GLIBC_2.0 pthread_condattr_destroy F
+GLIBC_2.0 pthread_condattr_init F
+GLIBC_2.0 pthread_create F
+GLIBC_2.0 pthread_detach F
+GLIBC_2.0 pthread_equal F
+GLIBC_2.0 pthread_exit F
+GLIBC_2.0 pthread_getschedparam F
+GLIBC_2.0 pthread_getspecific F
+GLIBC_2.0 pthread_join F
+GLIBC_2.0 pthread_key_create F
+GLIBC_2.0 pthread_key_delete F
+GLIBC_2.0 pthread_kill F
+GLIBC_2.0 pthread_kill_other_threads_np F
+GLIBC_2.0 pthread_mutex_destroy F
+GLIBC_2.0 pthread_mutex_init F
+GLIBC_2.0 pthread_mutex_lock F
+GLIBC_2.0 pthread_mutex_trylock F
+GLIBC_2.0 pthread_mutex_unlock F
+GLIBC_2.0 pthread_mutexattr_destroy F
+GLIBC_2.0 pthread_mutexattr_getkind_np F
+GLIBC_2.0 pthread_mutexattr_init F
+GLIBC_2.0 pthread_mutexattr_setkind_np F
+GLIBC_2.0 pthread_once F
+GLIBC_2.0 pthread_self F
+GLIBC_2.0 pthread_setcancelstate F
+GLIBC_2.0 pthread_setcanceltype F
+GLIBC_2.0 pthread_setschedparam F
+GLIBC_2.0 pthread_setspecific F
+GLIBC_2.0 pthread_sigmask F
+GLIBC_2.0 pthread_testcancel F
+GLIBC_2.0 raise F
+GLIBC_2.0 read F
+GLIBC_2.0 recv F
+GLIBC_2.0 recvfrom F
+GLIBC_2.0 recvmsg F
+GLIBC_2.0 sem_destroy F
+GLIBC_2.0 sem_getvalue F
+GLIBC_2.0 sem_init F
+GLIBC_2.0 sem_post F
+GLIBC_2.0 sem_trywait F
+GLIBC_2.0 sem_wait F
+GLIBC_2.0 send F
+GLIBC_2.0 sendmsg F
+GLIBC_2.0 sendto F
+GLIBC_2.0 sigaction F
+GLIBC_2.0 siglongjmp F
+GLIBC_2.0 sigwait F
+GLIBC_2.0 system F
+GLIBC_2.0 tcdrain F
+GLIBC_2.0 vfork F
+GLIBC_2.0 wait F
+GLIBC_2.0 waitpid F
+GLIBC_2.0 write F
+GLIBC_2.11 GLIBC_2.11 A
+GLIBC_2.11 pthread_sigqueue F
+GLIBC_2.12 GLIBC_2.12 A
+GLIBC_2.12 pthread_getname_np F
+GLIBC_2.12 pthread_mutex_consistent F
+GLIBC_2.12 pthread_mutexattr_getrobust F
+GLIBC_2.12 pthread_mutexattr_setrobust F
+GLIBC_2.12 pthread_setname_np F
+GLIBC_2.18 GLIBC_2.18 A
+GLIBC_2.18 pthread_getattr_default_np F
+GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.2 GLIBC_2.2 A
+GLIBC_2.2 __libc_allocate_rtsig F
+GLIBC_2.2 __libc_current_sigrtmax F
+GLIBC_2.2 __libc_current_sigrtmin F
+GLIBC_2.2 __open64 F
+GLIBC_2.2 __pread64 F
+GLIBC_2.2 __pthread_rwlock_destroy F
+GLIBC_2.2 __pthread_rwlock_init F
+GLIBC_2.2 __pthread_rwlock_rdlock F
+GLIBC_2.2 __pthread_rwlock_tryrdlock F
+GLIBC_2.2 __pthread_rwlock_trywrlock F
+GLIBC_2.2 __pthread_rwlock_unlock F
+GLIBC_2.2 __pthread_rwlock_wrlock F
+GLIBC_2.2 __pwrite64 F
+GLIBC_2.2 __res_state F
+GLIBC_2.2 __vfork F
+GLIBC_2.2 lseek64 F
+GLIBC_2.2 open64 F
+GLIBC_2.2 pread F
+GLIBC_2.2 pread64 F
+GLIBC_2.2 pthread_attr_getguardsize F
+GLIBC_2.2 pthread_attr_getstack F
+GLIBC_2.2 pthread_attr_getstackaddr F
+GLIBC_2.2 pthread_attr_getstacksize F
+GLIBC_2.2 pthread_attr_init F
+GLIBC_2.2 pthread_attr_setguardsize F
+GLIBC_2.2 pthread_attr_setstack F
+GLIBC_2.2 pthread_attr_setstackaddr F
+GLIBC_2.2 pthread_attr_setstacksize F
+GLIBC_2.2 pthread_barrier_destroy F
+GLIBC_2.2 pthread_barrier_init F
+GLIBC_2.2 pthread_barrier_wait F
+GLIBC_2.2 pthread_barrierattr_destroy F
+GLIBC_2.2 pthread_barrierattr_init F
+GLIBC_2.2 pthread_barrierattr_setpshared F
+GLIBC_2.2 pthread_condattr_getpshared F
+GLIBC_2.2 pthread_condattr_setpshared F
+GLIBC_2.2 pthread_create F
+GLIBC_2.2 pthread_getconcurrency F
+GLIBC_2.2 pthread_getcpuclockid F
+GLIBC_2.2 pthread_mutex_timedlock F
+GLIBC_2.2 pthread_mutexattr_getpshared F
+GLIBC_2.2 pthread_mutexattr_gettype F
+GLIBC_2.2 pthread_mutexattr_setpshared F
+GLIBC_2.2 pthread_mutexattr_settype F
+GLIBC_2.2 pthread_rwlock_destroy F
+GLIBC_2.2 pthread_rwlock_init F
+GLIBC_2.2 pthread_rwlock_rdlock F
+GLIBC_2.2 pthread_rwlock_timedrdlock F
+GLIBC_2.2 pthread_rwlock_timedwrlock F
+GLIBC_2.2 pthread_rwlock_tryrdlock F
+GLIBC_2.2 pthread_rwlock_trywrlock F
+GLIBC_2.2 pthread_rwlock_unlock F
+GLIBC_2.2 pthread_rwlock_wrlock F
+GLIBC_2.2 pthread_rwlockattr_destroy F
+GLIBC_2.2 pthread_rwlockattr_getkind_np F
+GLIBC_2.2 pthread_rwlockattr_getpshared F
+GLIBC_2.2 pthread_rwlockattr_init F
+GLIBC_2.2 pthread_rwlockattr_setkind_np F
+GLIBC_2.2 pthread_rwlockattr_setpshared F
+GLIBC_2.2 pthread_setconcurrency F
+GLIBC_2.2 pthread_spin_destroy F
+GLIBC_2.2 pthread_spin_init F
+GLIBC_2.2 pthread_spin_lock F
+GLIBC_2.2 pthread_spin_trylock F
+GLIBC_2.2 pthread_spin_unlock F
+GLIBC_2.2 pthread_yield F
+GLIBC_2.2 pwrite F
+GLIBC_2.2 pwrite64 F
+GLIBC_2.2 sem_close F
+GLIBC_2.2 sem_destroy F
+GLIBC_2.2 sem_getvalue F
+GLIBC_2.2 sem_init F
+GLIBC_2.2 sem_open F
+GLIBC_2.2 sem_post F
+GLIBC_2.2 sem_timedwait F
+GLIBC_2.2 sem_trywait F
+GLIBC_2.2 sem_unlink F
+GLIBC_2.2 sem_wait F
+GLIBC_2.2.3 GLIBC_2.2.3 A
+GLIBC_2.2.3 pthread_getattr_np F
+GLIBC_2.2.6 GLIBC_2.2.6 A
+GLIBC_2.2.6 __nanosleep F
+GLIBC_2.3.2 GLIBC_2.3.2 A
+GLIBC_2.3.2 pthread_cond_broadcast F
+GLIBC_2.3.2 pthread_cond_destroy F
+GLIBC_2.3.2 pthread_cond_init F
+GLIBC_2.3.2 pthread_cond_signal F
+GLIBC_2.3.2 pthread_cond_timedwait F
+GLIBC_2.3.2 pthread_cond_wait F
+GLIBC_2.3.3 GLIBC_2.3.3 A
+GLIBC_2.3.3 __pthread_cleanup_routine F
+GLIBC_2.3.3 __pthread_register_cancel F
+GLIBC_2.3.3 __pthread_register_cancel_defer F
+GLIBC_2.3.3 __pthread_unregister_cancel F
+GLIBC_2.3.3 __pthread_unregister_cancel_restore F
+GLIBC_2.3.3 __pthread_unwind_next F
+GLIBC_2.3.3 pthread_attr_getaffinity_np F
+GLIBC_2.3.3 pthread_attr_setaffinity_np F
+GLIBC_2.3.3 pthread_attr_setstack F
+GLIBC_2.3.3 pthread_attr_setstacksize F
+GLIBC_2.3.3 pthread_barrierattr_getpshared F
+GLIBC_2.3.3 pthread_condattr_getclock F
+GLIBC_2.3.3 pthread_condattr_setclock F
+GLIBC_2.3.3 pthread_getaffinity_np F
+GLIBC_2.3.3 pthread_setaffinity_np F
+GLIBC_2.3.3 pthread_timedjoin_np F
+GLIBC_2.3.3 pthread_tryjoin_np F
+GLIBC_2.3.4 GLIBC_2.3.4 A
+GLIBC_2.3.4 pthread_attr_getaffinity_np F
+GLIBC_2.3.4 pthread_attr_setaffinity_np F
+GLIBC_2.3.4 pthread_getaffinity_np F
+GLIBC_2.3.4 pthread_setaffinity_np F
+GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.4 GLIBC_2.4 A
+GLIBC_2.4 pthread_mutex_consistent_np F
+GLIBC_2.4 pthread_mutex_getprioceiling F
+GLIBC_2.4 pthread_mutex_setprioceiling F
+GLIBC_2.4 pthread_mutexattr_getprioceiling F
+GLIBC_2.4 pthread_mutexattr_getprotocol F
+GLIBC_2.4 pthread_mutexattr_getrobust_np F
+GLIBC_2.4 pthread_mutexattr_setprioceiling F
+GLIBC_2.4 pthread_mutexattr_setprotocol F
+GLIBC_2.4 pthread_mutexattr_setrobust_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/Versions b/sysdeps/unix/sysv/linux/mips/mips64/n64/Versions
new file mode 100644
index 0000000..f6ac045
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/Versions
@@ -0,0 +1,10 @@
+libc {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
+libpthread {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 53e0c9a..6722f90 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1932,6 +1932,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/oldrecvmsg.c b/sysdeps/unix/sysv/linux/oldrecvmsg.c
new file mode 100644
index 0000000..fef55dd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/oldrecvmsg.c
@@ -0,0 +1,42 @@
+/* Compatibility version of recvmsg.
+   Copyright (C) 2016 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 <sys/socket.h>
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <shlib-compat.h>
+
+#if LONG_MAX > INT_MAX
+/* Both libc.so and libpthread.so provides sendmsg, so we need to
+   provide the compat symbol for both libraries.  */
+# if SHLIB_COMPAT (MODULE_NAME, GLIBC_2_0, GLIBC_2_24)
+
+/* We can use the same struct layout for old symbol version since
+   size is the same.  */
+ssize_t
+__old_recvmsg (int fd, struct msghdr *msg, int flags)
+{
+#  ifdef __ASSUME_RECVMSG_SYSCALL
+  return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
+#  else
+  return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
+#  endif
+}
+compat_symbol (MODULE_NAME, __old_recvmsg, recvmsg, GLIBC_2_0);
+# endif
+#endif /* LONG_MAX > INT_MAX  */
diff --git a/sysdeps/unix/sysv/linux/oldsendmsg.c b/sysdeps/unix/sysv/linux/oldsendmsg.c
new file mode 100644
index 0000000..7d533c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/oldsendmsg.c
@@ -0,0 +1,42 @@
+/* Compatibility implementation of sendmsg.
+   Copyright (C) 2016 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 <sys/socket.h>
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <shlib-compat.h>
+
+#if LONG_MAX > INT_MAX
+/* Both libc.so and libpthread.so provides sendmsg, so we need to
+   provide the compat symbol for both libraries.  */
+# if SHLIB_COMPAT (MODULE_NAME, GLIBC_2_0, GLIBC_2_24)
+
+/* We can use the same struct layout for old symbol version since
+   size is the same.  */
+ssize_t
+__old_sendmsg (int fd, const struct msghdr *msg, int flags)
+{
+#  ifdef __ASSUME_SENDMSG_SYSCALL
+  return SYSCALL_CANCEL (sendmsg, fd, msg, flags);
+#  else
+  return SOCKETCALL_CANCEL (sendmsg, fd, msg, flags);
+#  endif
+}
+compat_symbol (MODULE_NAME, __old_sendmsg, sendmsg, GLIBC_2_0);
+# endif
+#endif /* LONG_MAX > INT_MAX  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
index a8e88b8..4dc8d57 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
@@ -22,6 +22,9 @@ libc {
   GLIBC_2.17 {
     __ppc_get_timebase_freq;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 
 librt {
@@ -40,4 +43,7 @@ libpthread {
     # Changed PTHREAD_STACK_MIN.
     pthread_attr_setstack; pthread_attr_setstacksize;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
index 008f34a..3d3fa95 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/socket.h
@@ -23,6 +23,8 @@
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <endian.h>
+
 /* Type for length arguments in socket calls.  */
 #ifndef __socklen_t_defined
 typedef __socklen_t socklen_t;
@@ -37,13 +39,24 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+#else
+    int msg_iovlen;
+    int __glibc_reserved1;
+#endif
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+#else
+    socklen_t msg_controllen;
+    int __glibc_reserved2;
+#endif
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +64,16 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index a97bd43..7839b5a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2175,3 +2175,6 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 00772cb..20d5a19 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -89,6 +89,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
index 0cf30ee..e33401a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
@@ -224,3 +224,6 @@ GLIBC_2.17 write F
 GLIBC_2.18 GLIBC_2.18 A
 GLIBC_2.18 pthread_getattr_default_np F
 GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
index 464b91a..4a845a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
@@ -9,6 +9,9 @@ GLIBC_2.12 pthread_setname_np F
 GLIBC_2.18 GLIBC_2.18 A
 GLIBC_2.18 pthread_getattr_default_np F
 GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _IO_flockfile F
 GLIBC_2.3 _IO_ftrylockfile F
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index 4caf22e..fa3a46e 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -15,23 +15,47 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <signal.h>
 #include <sys/socket.h>
-
 #include <sysdep-cancel.h>
 #include <socketcall.h>
-#include <kernel-features.h>
-#include <sys/syscall.h>
+#include <shlib-compat.h>
 
 ssize_t
 __libc_recvmsg (int fd, struct msghdr *msg, int flags)
 {
+  ssize_t ret;
+
+  /* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
+     to be int and socklen_t respectively.  However Linux defines it as
+     both size_t.  So for 64-bit it requires some adjustments by copying to
+     temporary header and zeroing the pad fields.  */
+#if LONG_MAX > INT_MAX
+  struct msghdr hdr, *orig = msg;
+  if (msg != NULL)
+    {
+      hdr = *msg;
+      hdr.__glibc_reserved1 = 0;
+      hdr.__glibc_reserved2 = 0;
+      msg = &hdr;
+    }
+#endif
+
 #ifdef __ASSUME_RECVMSG_SYSCALL
-  return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
+  ret = SYSCALL_CANCEL (recvmsg, fd, msg, flags);
 #else
-  return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
+  ret = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
+#endif
+
+#if LONG_MAX > INT_MAX
+  if (orig != NULL)
+    *orig = hdr;
 #endif
+
+  return ret;
 }
-weak_alias (__libc_recvmsg, recvmsg)
 weak_alias (__libc_recvmsg, __recvmsg)
+#if LONG_MAX > INT_MAX
+versioned_symbol (libc, __libc_recvmsg, recvmsg, GLIBC_2_24);
+#else
+weak_alias (__libc_recvmsg, recvmsg)
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/Versions b/sysdeps/unix/sysv/linux/s390/s390-64/Versions
index 3f4d960..708028f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/Versions
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/Versions
@@ -4,6 +4,9 @@ libc {
     __register_frame; __register_frame_table; __deregister_frame;
     __frame_state_for; __register_frame_info_table;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 
 librt {
@@ -13,3 +16,9 @@ librt {
     timer_settime;
   }
 }
+
+libpthread {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h b/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
index 3b7fe04..90d9aac 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/bits/socket.h
@@ -37,13 +37,14 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +52,11 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 1af185f..5892fcd 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1871,6 +1871,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index 83a1fcd..152bfb5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -207,6 +207,9 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
 GLIBC_2.2.3 pthread_getattr_np F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/sendmsg.c b/sysdeps/unix/sysv/linux/sendmsg.c
index 5b2741a..10cded4 100644
--- a/sysdeps/unix/sysv/linux/sendmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmsg.c
@@ -15,23 +15,38 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <signal.h>
 #include <sys/socket.h>
-
 #include <sysdep-cancel.h>
 #include <socketcall.h>
-#include <kernel-features.h>
-#include <sys/syscall.h>
+#include <shlib-compat.h>
 
 ssize_t
 __libc_sendmsg (int fd, const struct msghdr *msg, int flags)
 {
+  /* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
+     to be int and socklen_t respectively.  However Linux defines it as
+     both size_t.  So for 64-bit it requires some adjustments by copying to
+     temporary header and zeroing the pad fields.  */
+#if LONG_MAX > INT_MAX
+  struct msghdr hdr;
+  if (msg != NULL)
+    {
+      hdr = *msg;
+      hdr.__glibc_reserved1 = 0;
+      hdr.__glibc_reserved2 = 0;
+      msg = &hdr;
+    }
+#endif
+
 #ifdef __ASSUME_SENDMSG_SYSCALL
   return SYSCALL_CANCEL (sendmsg, fd, msg, flags);
 #else
   return SOCKETCALL_CANCEL (sendmsg, fd, msg, flags);
 #endif
 }
-weak_alias (__libc_sendmsg, sendmsg)
 weak_alias (__libc_sendmsg, __sendmsg)
+#if LONG_MAX > INT_MAX
+versioned_symbol (libc, __libc_sendmsg, sendmsg, GLIBC_2_24);
+#else
+weak_alias (__libc_sendmsg, sendmsg)
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
index fbea1bb..be45683 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
@@ -8,6 +8,9 @@ libc {
     # w*
     wordexp;
   }
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
 }
 
 librt {
@@ -17,3 +20,9 @@ librt {
     timer_settime;
   }
 }
+
+libpthread {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
index 2910f68..69881ff 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/socket.h
@@ -37,13 +37,14 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +52,11 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 91b97ef..015a2f1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1900,6 +1900,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index d4c8ded..0f3c4c2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -204,6 +204,9 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
 GLIBC_2.2.3 pthread_getattr_np F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h b/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
index b434819..d07e0f5 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/bits/socket.h
@@ -23,6 +23,8 @@
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <endian.h>
+
 /* Type for length arguments in socket calls.  */
 #ifndef __socklen_t_defined
 typedef __socklen_t socklen_t;
@@ -37,13 +39,24 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+#else
+    int msg_iovlen;
+    int __glibc_reserved1;
+#endif
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+#else
+    socklen_t msg_controllen;
+    int __glibc_reserved2;
+#endif
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +64,16 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+#else
+    socklen_t cmsg_len;
+    int __glibc_reserved1;
+#endif
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions
new file mode 100644
index 0000000..517d79a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index a66e8ec..1e160bd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2094,3 +2094,6 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libpthread.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libpthread.abilist
index d16158f..3e3dcf7 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libpthread.abilist
@@ -224,3 +224,6 @@ GLIBC_2.12 write F
 GLIBC_2.18 GLIBC_2.18 A
 GLIBC_2.18 pthread_getattr_default_np F
 GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/Versions b/sysdeps/unix/sysv/linux/x86_64/64/Versions
new file mode 100644
index 0000000..f6ac045
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/64/Versions
@@ -0,0 +1,10 @@
+libc {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
+libpthread {
+  GLIBC_2.24 {
+    recvmsg; sendmsg;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index c6e3cd4..175339e 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1851,6 +1851,9 @@ GLIBC_2.23 fts64_close F
 GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 85365c0..b599e47 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -203,6 +203,9 @@ GLIBC_2.2.5 waitpid F
 GLIBC_2.2.5 write F
 GLIBC_2.2.6 GLIBC_2.2.6 A
 GLIBC_2.2.6 __nanosleep F
+GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmsg F
 GLIBC_2.3.2 GLIBC_2.3.2 A
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/socket.h b/sysdeps/unix/sysv/linux/x86_64/bits/socket.h
index ab935f5..469b142 100644
--- a/sysdeps/unix/sysv/linux/x86_64/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/socket.h
@@ -37,13 +37,14 @@ struct msghdr
     socklen_t msg_namelen;	/* Length of address data.  */
 
     struct iovec *msg_iov;	/* Vector of data to send/receive into.  */
-    size_t msg_iovlen;		/* Number of elements in the vector.  */
+    int msg_iovlen;		/* Number of elements in the vector.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
 
     void *msg_control;		/* Ancillary data (eg BSD filedesc passing). */
-    size_t msg_controllen;	/* Ancillary data buffer length.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t msg_controllen;	/* Ancillary data buffer length.  */
+    int __glibc_reserved2;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
 
     int msg_flags;		/* Flags on received message.  */
   };
@@ -51,11 +52,11 @@ struct msghdr
 /* Structure used for storage of ancillary data object information.  */
 struct cmsghdr
   {
-    size_t cmsg_len;		/* Length of data in cmsg_data plus length
-				   of cmsghdr structure.
-				   !! The type should be socklen_t but the
-				   definition of the kernel is incompatible
-				   with this.  */
+    socklen_t cmsg_len;		/* Length of data in cmsg_data plus length
+				   of cmsghdr structure.  */
+    int __glibc_reserved1;	/* Pad to adjust Linux size to POSIX defined
+				   one.  */
+
     int cmsg_level;		/* Originating protocol.  */
     int cmsg_type;		/* Protocol specific type.  */
 #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/4] network: recvmmsg and sendmmsg standard compliance (BZ#16919)
  2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2016-03-21 20:42 ` [PATCH 3/4] network: recvmsg and sendmsg standard compliance (BZ#16919) Adhemerval Zanella
@ 2016-03-21 20:42 ` Adhemerval Zanella
  2016-03-21 21:13   ` Andreas Schwab
  2016-03-21 21:24 ` [PATCH 0/4] Fix {recv,send}{m}msg " Adhemerval Zanella
  4 siblings, 1 reply; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 20:42 UTC (permalink / raw)
  To: libc-alpha

POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
to be of size int and socklen_t respectively, however Linux implements
it as a size_t.  So for 64-bits architecture where sizeof of size_t is
larger than socklen_t, both sendmmsg and recvmmsg need to adjust the
mmsghdr::msg_hdr internal fields before issuing the syscall itself.

This patch fixes it by operating on the padding if it the case.
For recvmmsg, the most straightfoward case, only zero padding the fields
is suffice.  However, for sendmmsg, where adjusting the buffer is out
of the contract (since it may point to a read-only data), the function
is rewritten to use sendmsg instead (which from previous patch
allocates a temporary msghdr to operate on).

Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg
compat version is created (which uses size_t for both cmsghdr::cmsg_len
and internal

Tested on x86_64, i686, aarch64, armhf, and powerpc64le.

	* sysdeps/unix/sysv/linux/Makefile
	[$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and
	oldsendmmsg.
	* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and
	sendmmsg.
	* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
	* sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	[__LINUX_KERNEL_VERSION > 0x030000]
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Add define.
	* sysdeps/unix/sysv/linux/m68k/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/microblaze/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	* sysdeps/unix/sysv/linux/powerpc/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/s390/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Add define.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/sh/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Remove define.
	* sysdeps/unix/sysv/linux/sparc/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	(__ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/recvmmsg.c: Remove file.
	* sysdeps/unix/sysv/linux/mips/mips32/sendmmsg.c: Likewise.
	* sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file.
	* sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise.
	* sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr
	iovlen and controllen fields to adjust to POSIX specification.
	* sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
---
 sysdeps/unix/sysv/linux/Makefile                   |  3 +-
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 .../unix/sysv/linux/microblaze/kernel-features.h   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/oldrecvmmsg.c              | 91 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/oldsendmmsg.c              | 90 +++++++++++++++++++++
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |  2 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/recvmmsg.c                 | 49 ++++++++++--
 sysdeps/unix/sysv/linux/s390/kernel-features.h     |  3 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sendmmsg.c                 | 56 ++++++++++++-
 sysdeps/unix/sysv/linux/sh/kernel-features.h       |  3 -
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 19 files changed, 348 insertions(+), 14 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/oldrecvmmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/oldsendmmsg.c

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 4475a5c..512143c 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -124,7 +124,8 @@ ifeq ($(subdir),socket)
 sysdep_headers += net/if_ppp.h net/ppp-comp.h \
 		  net/ppp_defs.h net/if_arp.h net/route.h net/ethernet.h \
 		  net/if_slip.h net/if_packet.h net/if_shaper.h
-sysdep_routines += cmsg_nxthdr oldrecvmsg oldsendmsg
+sysdep_routines += cmsg_nxthdr oldrecvmsg oldsendmsg \
+		   oldrecvmmsg oldsendmmsg
 endif
 
 ifeq ($(subdir),sunrpc)
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index c3f2346..7981817 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2088,5 +2088,7 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 7822242..0c1e1ac 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -1999,7 +1999,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5739b4..b1388d1 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1875,7 +1875,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
index e25b6ed..b573911 100644
--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
@@ -20,6 +20,8 @@
 #define __ASSUME_SOCKETCALL	1
 #define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
 
+#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
+
 /* All supported kernel versions for MicroBlaze have these syscalls.  */
 #define __ASSUME_SOCKET_SYSCALL		1
 #define __ASSUME_BIND_SYSCALL		1
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 6722f90..0e2ff75 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1933,7 +1933,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/oldrecvmmsg.c b/sysdeps/unix/sysv/linux/oldrecvmmsg.c
new file mode 100644
index 0000000..d01fff7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/oldrecvmmsg.c
@@ -0,0 +1,91 @@
+/* Compatibility version of recvmsg.
+   Copyright (C) 2010-2016 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 <sys/socket.h>
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <shlib-compat.h>
+
+#if LONG_MAX > INT_MAX
+# if SHLIB_COMPAT (libc, GLIBC_2_12, GLIBC_2_24)
+
+#  ifdef __ASSUME_RECVMMSG_SYSCALL
+int
+__old_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags, struct timespec *tmo)
+{
+  return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
+}
+#  elif defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL
+int
+__old_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags, struct timespec *tmo)
+{
+  return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
+}
+#  elif defined __ASSUME_SOCKETCALL
+static int have_recvmmsg;
+
+int
+__old_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags, struct timespec *tmo)
+{
+  if (__glibc_likely (have_recvmmsg >= 0))
+    {
+      int ret = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags,
+				   tmo);
+      /* The kernel returns -EINVAL for unknown socket operations.
+	 We need to convert that error to an ENOSYS error.  */
+      if (__builtin_expect (ret < 0, 0)
+	  && have_recvmmsg == 0
+	  && errno == EINVAL)
+	{
+	  /* Try another call, this time with an invalid file
+	     descriptor and all other parameters cleared.  This call
+	     will not cause any harm and it will return
+	     immediately.  */
+	  ret = SOCKETCALL_CANCEL (invalid, -1);
+	  if (errno == EINVAL)
+	    {
+	      have_recvmmsg = -1;
+	      __set_errno (ENOSYS);
+	    }
+	  else
+	    {
+	      have_recvmmsg = 1;
+	      __set_errno (EINVAL);
+	    }
+	  return -1;
+	}
+      return ret;
+    }
+  __set_errno (ENOSYS);
+  return -1;
+}
+#  else
+int
+__old_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags, struct timespec *tmo)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+#  endif
+compat_symbol (libc, __old_recvmmsg, recvmmsg, GLIBC_2_12);
+# endif /* SHLIB_COMPAT (libc, GLIBC_2_12, GLIBC_2_24)  */
+#endif /* LONG_MAX > INT_MAX  */
diff --git a/sysdeps/unix/sysv/linux/oldsendmmsg.c b/sysdeps/unix/sysv/linux/oldsendmmsg.c
new file mode 100644
index 0000000..7970b73
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/oldsendmmsg.c
@@ -0,0 +1,90 @@
+/* Compatibility implementation of sendmmsg.
+   Copyright (C) 2016 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 <sys/socket.h>
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <shlib-compat.h>
+
+#if LONG_MAX > INT_MAX
+# if SHLIB_COMPAT (libc, GLIBC_2_14, GLIBC_2_24)
+
+#  ifdef __ASSUME_SENDMMSG_SYSCALL
+int
+__old_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags)
+{
+  return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+}
+#  elif defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL
+int
+__old_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags)
+{
+  return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+}
+#  elif defined __ASSUME_SOCKETCALL
+static int have_sendmmsg;
+
+int
+__old_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		int flags)
+{
+  if (__glibc_likely (have_sendmmsg >= 0))
+    {
+      int ret = SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+      /* The kernel returns -EINVAL for unknown socket operations.
+	 We need to convert that error to an ENOSYS error.  */
+      if (__builtin_expect (ret < 0, 0)
+	  && have_sendmmsg == 0
+	  && errno == EINVAL)
+	{
+	  /* Try another call, this time with an invalid file
+	     descriptor and all other parameters cleared.  This call
+	     will not cause any harm and it will return
+	     immediately.  */
+	  ret = SOCKETCALL_CANCEL (invalid, -1);
+	  if (errno == EINVAL)
+	    {
+	      have_sendmmsg = -1;
+	      __set_errno (ENOSYS);
+	    }
+	  else
+	    {
+	      have_sendmmsg = 1;
+	      __set_errno (EINVAL);
+	    }
+	  return -1;
+	}
+      return ret;
+    }
+  __set_errno (ENOSYS);
+  return -1;
+}
+#  else
+#   define __sendmmsg __old_sendmmsg
+#   undef libc_hidden_def
+#   define libc_hidden_def(name)
+#   undef weak_alias
+#   define weak_alias(name, alias)
+#   include <socket/sendmmsg.c>
+#  endif
+
+compat_symbol (libc, __old_sendmmsg, sendmmsg, GLIBC_2_14);
+# endif /* SHLIB_COMPAT (libc, GLIBC_2_14, GLIBC_2_24)  */
+#endif /* LONG_MAX > INT_MAX  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 7839b5a..85286c4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2176,5 +2176,7 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 20d5a19..0abd098 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -90,7 +90,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index fb3f325..9cb03d1 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -21,29 +21,49 @@
 #include <socketcall.h>
 #include <shlib-compat.h>
 
+static inline void
+adjust_mmsghdr (struct mmsghdr *vmessages, unsigned int vlen)
+{
+#if LONG_MAX > INT_MAX
+  /* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
+     to be int and socklen_t respectively.  However Linux defines it as
+     both size_t.  So for 64-bit it requires some adjustments by zeroing
+     the pad fields.  */
+  struct mmsghdr *vmhdr = vmessages;
+  for (unsigned int i = 0; i != 0; i--, vmhdr++)
+    {
+      vmhdr->msg_hdr.__glibc_reserved1 = 0;
+      vmhdr->msg_hdr.__glibc_reserved2 = 0;
+    }
+#endif
+}
+
 #ifdef __ASSUME_RECVMMSG_SYSCALL
 int
-recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
-	  struct timespec *tmo)
+__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		 int flags, struct timespec *tmo)
 {
+  adjust_mmsghdr (vmessages, vlen);
   return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
 }
 #elif defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL
 int
-recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
-	  struct timespec *tmo)
+__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		 int flags, struct timespec *tmo)
 {
+  adjust_mmsghdr (vmessages, vlen);
   return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
 }
 #elif defined __ASSUME_SOCKETCALL
 static int have_recvmmsg;
 
 int
-recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
-	  struct timespec *tmo)
+__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+		 int flags, struct timespec *tmo)
 {
   if (__glibc_likely (have_recvmmsg >= 0))
     {
+      adjust_mmsghdr (vmessages, vlen);
       int ret = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags,
 				   tmo);
       /* The kernel returns -EINVAL for unknown socket operations.
@@ -75,5 +95,20 @@ recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
   return -1;
 }
 #else /* __ASSUME_RECVMMSG_SOCKETCALL  */
-# include <socket/recvmmsg.c>
+/* 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,
+	  struct timespec *tmo)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (recvmmsg)
 #endif
+
+# if LONG_MAX > INT_MAX
+versioned_symbol (libc, __recvmmsg, recvmmsg, GLIBC_2_24);
+# else
+weak_alias (__recvmmsg, recvmmsg)
+# endif
diff --git a/sysdeps/unix/sysv/linux/s390/kernel-features.h b/sysdeps/unix/sysv/linux/s390/kernel-features.h
index 4656c4a..4e7b030 100644
--- a/sysdeps/unix/sysv/linux/s390/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h
@@ -22,6 +22,9 @@
 #define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
 #define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
 
+#define __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
+
 /* Direct socketcalls available with kernel 4.3.  */
 #if __LINUX_KERNEL_VERSION >= 0x040300
 # define __ASSUME_SOCKET_SYSCALL             1
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 5892fcd..03a9b97 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1872,7 +1872,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c
index 37f0ec9..1f40f41 100644
--- a/sysdeps/unix/sysv/linux/sendmmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmmsg.c
@@ -19,23 +19,58 @@
 #include <sys/socket.h>
 #include <sysdep-cancel.h>
 #include <socketcall.h>
+#include <shlib-compat.h>
+
+#if LONG_MAX > INT_MAX
+static inline int
+send_mmsghdr (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
+{
+  /* Emulate kernel interface for vlen size.  */
+  if (vlen > IOV_MAX)
+    vlen = IOV_MAX;
+  if (vlen == 0)
+    return 0;
+  /* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
+     to be int and socklen_t respectively,  however Linux defines it as both
+     size_t.  So for 64-bit it requires some adjustments by copying to
+     temporary header and zeroing the pad fields.
+     The problem is sendmmsg's msghdr may points to an already-filled control
+     buffer and modifying it is not part of sendmmsg contract (the data may
+     be in ro map).  So interact over the msghdr calling the sendmsg that
+     adjust the header using a temporary buffer.  */
+  for (unsigned int i = 0; i < vlen; i++)
+    {
+      ssize_t ret = __sendmsg (fd, &vmessages[i].msg_hdr, flags);
+      if (ret < 0)
+	return -1;
+      vmessages[i].msg_len = ret;
+    }
+  return 1;
+}
+#endif
 
 #ifdef __ASSUME_SENDMMSG_SYSCALL
 int
 __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
+# if LONG_MAX > INT_MAX
+  return send_mmsghdr (fd, vmessages, vlen, flags);
+# else
   return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+# endif
 }
 libc_hidden_def (__sendmmsg)
-weak_alias (__sendmmsg, sendmmsg)
 #elif defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL
 int
 __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
+# if LONG_MAX > INT_MAX
+  return send_mmsghdr (fd, vmessages, vlen, flags);
+# else
   return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+# endif
 }
 libc_hidden_def (__sendmmsg)
-weak_alias (__sendmmsg, sendmmsg)
 #elif defined __ASSUME_SOCKETCALL
 static int have_sendmmsg;
 
@@ -44,7 +79,11 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
   if (__glibc_likely (have_sendmmsg >= 0))
     {
+# if LONG_MAX > INT_MAX
+      int ret = send_mmsghdr (fd, vmessages, vlen, flags);
+# else
       int ret = SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
+# endif
       /* The kernel returns -EINVAL for unknown socket operations.
 	 We need to convert that error to an ENOSYS error.  */
       if (__builtin_expect (ret < 0, 0)
@@ -55,7 +94,11 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 	     descriptor and all other parameters cleared.  This call
 	     will not cause any harm and it will return
 	     immediately.  */
+# if LONG_MAX > INT_MAX
+	  ret = send_mmsghdr (fd, vmessages, vlen, flags);
+# else
 	  ret = SOCKETCALL_CANCEL (invalid, -1);
+# endif
 	  if (errno == EINVAL)
 	    {
 	      have_sendmmsg = -1;
@@ -74,7 +117,14 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
   return -1;
 }
 libc_hidden_def (__sendmmsg)
-weak_alias (__sendmmsg, sendmmsg)
 #else /* __ASSUME_SENDMMSG_SOCKETCALL  */
+# undef weak_alias
+# define weak_alias(name, alias)
 # include <socket/sendmmsg.c>
 #endif
+
+#if LONG_MAX > INT_MAX
+versioned_symbol (libc, __sendmmsg, sendmmsg, GLIBC_2_24);
+#else
+weak_alias (__sendmmsg, sendmmsg)
+#endif
diff --git a/sysdeps/unix/sysv/linux/sh/kernel-features.h b/sysdeps/unix/sysv/linux/sh/kernel-features.h
index ad05fc3..be50320 100644
--- a/sysdeps/unix/sysv/linux/sh/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/sh/kernel-features.h
@@ -37,9 +37,6 @@
 #define __ASSUME_GETSOCKOPT_SYSCALL	1
 #define __ASSUME_SETSOCKOPT_SYSCALL	1
 
-/* The sendmmsg syscall was added for SH in 3.0.  */
-#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL	1
-
 #include_next <kernel-features.h>
 
 /* SH does not have a 64-bit inode field.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 015a2f1..38b976f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1901,7 +1901,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 1e160bd..07b1332 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2095,5 +2095,7 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 175339e..baea1f5 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1852,7 +1852,9 @@ GLIBC_2.23 fts64_open F
 GLIBC_2.23 fts64_read F
 GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 recvmmsg F
 GLIBC_2.24 recvmsg F
+GLIBC_2.24 sendmmsg F
 GLIBC_2.24 sendmsg F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] network: recvmmsg and sendmmsg standard compliance (BZ#16919)
  2016-03-21 20:42 ` [PATCH 4/4] network: recvmmsg and sendmmsg " Adhemerval Zanella
@ 2016-03-21 21:13   ` Andreas Schwab
  2016-03-21 21:22     ` Adhemerval Zanella
  0 siblings, 1 reply; 12+ messages in thread
From: Andreas Schwab @ 2016-03-21 21:13 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:

> @@ -55,7 +94,11 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
>  	     descriptor and all other parameters cleared.  This call
>  	     will not cause any harm and it will return
>  	     immediately.  */
> +# if LONG_MAX > INT_MAX
> +	  ret = send_mmsghdr (fd, vmessages, vlen, flags);
> +# else
>  	  ret = SOCKETCALL_CANCEL (invalid, -1);
> +# endif

That looks wrong, there is nothing to convert.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] network: recvmmsg and sendmmsg standard compliance (BZ#16919)
  2016-03-21 21:13   ` Andreas Schwab
@ 2016-03-21 21:22     ` Adhemerval Zanella
  0 siblings, 0 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 21:22 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: libc-alpha



On 21-03-2016 18:13, Andreas Schwab wrote:
> Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
> 
>> @@ -55,7 +94,11 @@ __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
>>  	     descriptor and all other parameters cleared.  This call
>>  	     will not cause any harm and it will return
>>  	     immediately.  */
>> +# if LONG_MAX > INT_MAX
>> +	  ret = send_mmsghdr (fd, vmessages, vlen, flags);
>> +# else
>>  	  ret = SOCKETCALL_CANCEL (invalid, -1);
>> +# endif
> 
> That looks wrong, there is nothing to convert.
> 
> Andreas.
> 

Indeed, this not required. I will remove it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919)
  2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2016-03-21 20:42 ` [PATCH 4/4] network: recvmmsg and sendmmsg " Adhemerval Zanella
@ 2016-03-21 21:24 ` Adhemerval Zanella
  4 siblings, 0 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-21 21:24 UTC (permalink / raw)
  To: libc-alpha



On 21-03-2016 17:41, Adhemerval Zanella wrote:
> This is an attempt of fixing the BZ#16919, recvmsg standard compliance,
> where Linux and POSIX differs in the msghdr and mmsghdr internal struct
> sizes.  The issue is POSIX defines [1] both msghdr.msg_namelen,
> msghdr.controllen, and cmsghdr.cmsg_len as socklen_t, where Linux uses
> size_t.  So for 64-bits architectures where size_t is larger sockelen_t
> it leads to standard inconsistence.  Linux also added recvmmsg and
> sendmmsg, which uses a composite struct based on msghdr (mmsghdr).
> 
> As stated in comment 6 at bugzilla report, both recvmsg and recvmmsg
> uses the msghdr structures which lie in memory that's (by the interface
> contract) writable by the function, so the adjustment is just to patch
> with zero the padding memebers.  However sendmmsg's msghdr points to
> an already-filled control buffer containing cmsghdr structures that
> is not writable by the function's contract.
> 
> So the proposed solutions follow four patches:
> 
>  1. Add architecture specific socket.h header: splits the Linux
>     socket.h definition in a platform specific one for the new
>     msghdr and cmsghdr defition.  The is just a functional change
>     to lay the required headers (more rationale where it is not
>     possible to support only on header on the patch comments).
> 
>  2. Adjust kernel-features.h for sendmmsg/recvmmsg: this try to
>     simplify the sendmmsg/recvmmsg __ASSUME definition and also
>     fixes some x86 bugs when building using old kernel definitions.
> 
>  3. network: recvmsg and sendmsg standard compliance: this is the
>     first patch of the BZ#16919 fix where it handle both recvmsg
>     and sendmsg.
> 
>  4. network: recvmmsg and sendmmsg standard compliance: the second
>     patch where is handles both recvmmsg and sendmmsg.
> 
> This current solutions have some open spots that I would like to
> discuss:
> 
>  1. Current sendmsg fix does not handle larger msg_control neither
>     pads the cmsghdr associated.  The problem with this approach
>     is to accomplish a complete fix it will require to allocate
>     a limited buffer, copying the incoming struct and zero pad.
>     Although it tend to work it also add some limitation of total
>     msg_control length.
>     The general usage for such facily is passing file descriptors
>     and permissions between processes over unix sockets so it might
>     be factible to use a large stack allocated buffer (1024, 2048
>     or large) and return ENOMEM for larger buffers.
> 
>  2. Current approach adds symbol versioning for older implementation
>     which uses the syscall directly.  This is the default GLIBC
>     policy for such changes, whoever I am not sure if there is any
>     realword application that might break with this new implementation.
>     So one option could get rid of the compatbility symbols.
> 
> [1] http://pubs.opengroup.org/onlinepubs/9699919799/

Something that I forgot to add:

 3. Most of the complication on both recvmsg and sendmsg implementation
    is because GLIBC still sets for x86 and x86_64 2.6.32 as the minimum
    required kernel.  Moving forward to 3.2 will allows up to remove 
    a lot of compatibility code (the stubs parts for instance).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] Add architecture specific socket.h header
  2016-03-21 20:42 ` [PATCH 1/4] Add architecture specific socket.h header Adhemerval Zanella
@ 2016-03-21 23:11   ` Joseph Myers
  2016-03-22 10:27     ` Adhemerval Zanella
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph Myers @ 2016-03-21 23:11 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Mon, 21 Mar 2016, Adhemerval Zanella wrote:

> To avoid namespace pollution socket.h can not include limits.h to
> get LONG_MAX and INT_MAX, so the option is either using compiler
> builtin defintions (__LONG_MAX__ and __INT_MAX__) or by creating
> archicteture specific headers.  The first option has the downside
> of relying on existense of builtin, which might not be true for all
> current compilers.

The normal approach is to include <bits/wordsize.h>.  That should avoid 
any need for architecture-specific variants of socket.h.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg
  2016-03-21 20:41 ` [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg Adhemerval Zanella
@ 2016-03-21 23:26   ` Joseph Myers
  2016-03-22 10:38     ` Adhemerval Zanella
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph Myers @ 2016-03-21 23:26 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Mon, 21 Mar 2016, Adhemerval Zanella wrote:

>  * Remove the __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL for ports that
>    for current minimum supported kernel already have direct recvmmsg
>    syscall support (microblaze, powerpc, and spart).
> 
>  * Add __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL define for ports that
>    still uses socketcall interface (i386, m68k, s390).

This inverts the present semantics for the _WITH_SOCKETCALL macros.  At 
present, it's defined when the syscall should be always preferred to 
socketcall (even if the syscall isn't guaranteed to be available); you're 
changing it to mean that the syscall should never be preferred to 
socketcall unless guaranteed to be available.  Obviously such a change 
requires an update to the comment in the generic kernel-features.h 
defining the semantics of __ASSUME_ACCEPT4_SYSCALL_WITH_SOCKETCALL (and 
that one must be updated with the other two - having different macro 
semantics for the three functions would be excessively confusing).  
However, I think it would be much better to use a clearly different macro 
name if inverting the semantics (again, for all three functions in 
question).  And similarly, any refactoring of implementations should be 
done for all three functions together.

It's true that even with the present semantics, 
__ASSUME_*_SYSCALL_WITH_SOCKETCALL definitions in the 
architecture-specific header are unnecessary but harmless in the case 
where the syscall is assumed to be present with the minimum supported 
kernel.

> This approach also fixes the following i386/x86_64 issue:
> 
>  * For i686 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
>    supported kernel) will use direct syscall where it should use runtime
>    socketcall

Why is this a bug?  For all released i686 kernels, recvmmsg is either 
available through both socketcall and the syscall, or through neither 
socketcall and the syscall, and likewise for sendmmsg.  And where both are 
available, it's better to use the syscall than socketcall (on general 
principles of socketcall being deprecated).  So libc built for i686 should 
never try to use socketcall at all for recvmmsg or sendmmsg under any 
circumstances (it *should* try for accept4 if the minimum kernel is below 
4.3, because accept4 is available through socketcall on more kernels than 
the syscall).

>  * For x86_64 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
>    kernel) will use syscall where it should use stub.

No, it should use the syscall (which might or might not exist at runtime).  
It's always wrong to use the stub implementation if the syscall number is 
known and so the syscall might be available at runtime.

The only reason stubs might be used at all for any of accept4, recvmmsg, 
sendmmsg on any GNU/Linux architecture is on non-socketcall architectures 
where the syscall number is unavailable in the kernel headers used.  Given 
the requirement for >= 3.2 headers on all architectures, this applies to 
accept4 on ia64, and no other cases.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] Add architecture specific socket.h header
  2016-03-21 23:11   ` Joseph Myers
@ 2016-03-22 10:27     ` Adhemerval Zanella
  0 siblings, 0 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-22 10:27 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha



On 21-03-2016 20:11, Joseph Myers wrote:
> On Mon, 21 Mar 2016, Adhemerval Zanella wrote:
> 
>> To avoid namespace pollution socket.h can not include limits.h to
>> get LONG_MAX and INT_MAX, so the option is either using compiler
>> builtin defintions (__LONG_MAX__ and __INT_MAX__) or by creating
>> archicteture specific headers.  The first option has the downside
>> of relying on existense of builtin, which might not be true for all
>> current compilers.
> 
> The normal approach is to include <bits/wordsize.h>.  That should avoid 
> any need for architecture-specific variants of socket.h.
> 

I though about using __WORDSIZE == 64 as the compiler test to check if
sizeof (size_t) is larger than sizeof (socklen_t), but I was not sure
how safe it is for all the architectures.  It seems to be ok for
all current ports though.  I will change that.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg
  2016-03-21 23:26   ` Joseph Myers
@ 2016-03-22 10:38     ` Adhemerval Zanella
  0 siblings, 0 replies; 12+ messages in thread
From: Adhemerval Zanella @ 2016-03-22 10:38 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha



On 21-03-2016 20:26, Joseph Myers wrote:
> On Mon, 21 Mar 2016, Adhemerval Zanella wrote:
> 
>>  * Remove the __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL for ports that
>>    for current minimum supported kernel already have direct recvmmsg
>>    syscall support (microblaze, powerpc, and spart).
>>
>>  * Add __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL define for ports that
>>    still uses socketcall interface (i386, m68k, s390).
> 
> This inverts the present semantics for the _WITH_SOCKETCALL macros.  At 
> present, it's defined when the syscall should be always preferred to 
> socketcall (even if the syscall isn't guaranteed to be available); you're 
> changing it to mean that the syscall should never be preferred to 
> socketcall unless guaranteed to be available.  Obviously such a change 
> requires an update to the comment in the generic kernel-features.h 
> defining the semantics of __ASSUME_ACCEPT4_SYSCALL_WITH_SOCKETCALL (and 
> that one must be updated with the other two - having different macro 
> semantics for the three functions would be excessively confusing).  
> However, I think it would be much better to use a clearly different macro 
> name if inverting the semantics (again, for all three functions in 
> question).  And similarly, any refactoring of implementations should be 
> done for all three functions together.
> 
> It's true that even with the present semantics, 
> __ASSUME_*_SYSCALL_WITH_SOCKETCALL definitions in the 
> architecture-specific header are unnecessary but harmless in the case 
> where the syscall is assumed to be present with the minimum supported 
> kernel.

In fact I wasn't sure which would be best approach, but base on your comments
and the wrong assumptions I had with the x86 'fixes' I think best approach
would be:

  1. Use syscall if __NR_recvmmsg is defined
  2. Otherwise if socketcall is __ASSUME_RECVMMSG_SYSCALL is defined
  3. Otherwise if runtime socketcall tests if __ASSUME_SOCKETCALL

For current support architectures and kernels, only microblaze and
s390 will use 2 (with s390 using 1. with kernel 4.3+).  The tests
3 will be used only for i386 with default minimum kernel version
(2.6.32) and I think we can remove the stub since it will be 
always defined with the minimum kernel headers we are supporting
(3.2).

> 
>> This approach also fixes the following i386/x86_64 issue:
>>
>>  * For i686 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
>>    supported kernel) will use direct syscall where it should use runtime
>>    socketcall
> 
> Why is this a bug?  For all released i686 kernels, recvmmsg is either 
> available through both socketcall and the syscall, or through neither 
> socketcall and the syscall, and likewise for sendmmsg.  And where both are 
> available, it's better to use the syscall than socketcall (on general 
> principles of socketcall being deprecated).  So libc built for i686 should 
> never try to use socketcall at all for recvmmsg or sendmmsg under any 
> circumstances (it *should* try for accept4 if the minimum kernel is below 
> 4.3, because accept4 is available through socketcall on more kernels than 
> the syscall).
> 
>>  * For x86_64 with kernel 3.2.0 but with --enable-kernel=2.6.32 (minimum
>>    kernel) will use syscall where it should use stub.
> 
> No, it should use the syscall (which might or might not exist at runtime).  
> It's always wrong to use the stub implementation if the syscall number is 
> known and so the syscall might be available at runtime.
> 
> The only reason stubs might be used at all for any of accept4, recvmmsg, 
> sendmmsg on any GNU/Linux architecture is on non-socketcall architectures 
> where the syscall number is unavailable in the kernel headers used.  Given 
> the requirement for >= 3.2 headers on all architectures, this applies to 
> accept4 on ia64, and no other cases.
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-03-22 10:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-21 20:41 [PATCH 0/4] Fix {recv,send}{m}msg standard compliance (BZ#16919) Adhemerval Zanella
2016-03-21 20:41 ` [PATCH 2/4] Adjust kernel-features.h for sendmmsg/recvmmsg Adhemerval Zanella
2016-03-21 23:26   ` Joseph Myers
2016-03-22 10:38     ` Adhemerval Zanella
2016-03-21 20:42 ` [PATCH 1/4] Add architecture specific socket.h header Adhemerval Zanella
2016-03-21 23:11   ` Joseph Myers
2016-03-22 10:27     ` Adhemerval Zanella
2016-03-21 20:42 ` [PATCH 3/4] network: recvmsg and sendmsg standard compliance (BZ#16919) Adhemerval Zanella
2016-03-21 20:42 ` [PATCH 4/4] network: recvmmsg and sendmmsg " Adhemerval Zanella
2016-03-21 21:13   ` Andreas Schwab
2016-03-21 21:22     ` Adhemerval Zanella
2016-03-21 21:24 ` [PATCH 0/4] Fix {recv,send}{m}msg " Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).