94084c
commit e09e7b1492b2d5c2f68ddf81f8f58e093dd4df6d
94084c
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
94084c
Date:   Mon Dec 13 11:36:42 2021 -0300
94084c
94084c
    support: Add support_socket_so_timestamp_time64
94084c
    
94084c
    Check if the socket support 64-bit network packages timestamps
94084c
    (SO_TIMESTAMP and SO_TIMESTAMPNS).  This will be used on recvmsg
94084c
    and recvmmsg tests to check if the timestamp should be generated.
94084c
    
94084c
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
94084c
    
94084c
    (cherry picked from 38bc0f4e78934aab455b31af05cefcbf3c22bece)
94084c
94084c
diff --git a/support/Makefile b/support/Makefile
94084c
index 3c941e1ba9e29aa4..6a5fc9faf2ca2e2d 100644
94084c
--- a/support/Makefile
94084c
+++ b/support/Makefile
94084c
@@ -79,6 +79,7 @@ libsupport-routines = \
94084c
   support_set_small_thread_stack_size \
94084c
   support_shared_allocate \
94084c
   support_small_stack_thread_attribute \
94084c
+  support_socket_so_timestamp_time64 \
94084c
   support_stat_nanoseconds \
94084c
   support_subprocess \
94084c
   support_test_compare_blob \
94084c
diff --git a/support/support.h b/support/support.h
94084c
index 29d56c7c891ee34b..ecfc9a336d272a30 100644
94084c
--- a/support/support.h
94084c
+++ b/support/support.h
94084c
@@ -170,6 +170,10 @@ extern bool support_select_modifies_timeout (void);
94084c
    tv_usec larger than 1000000.  */
94084c
 extern bool support_select_normalizes_timeout (void);
94084c
 
94084c
+/* Return true if socket FD supports 64-bit timestamps with the SOL_SOCKET
94084c
+   and SO_TIMESTAMP/SO_TIMESTAMPNS.  */
94084c
+extern bool support_socket_so_timestamp_time64 (int fd);
94084c
+
94084c
 /* Create a timer that trigger after SEC seconds and NSEC nanoseconds.  If
94084c
    REPEAT is true the timer will repeat indefinitely.  If CALLBACK is not
94084c
    NULL, the function will be called when the timer expires; otherwise a
94084c
diff --git a/support/support_socket_so_timestamp_time64.c b/support/support_socket_so_timestamp_time64.c
94084c
new file mode 100644
94084c
index 0000000000000000..54bf3f42724566f5
94084c
--- /dev/null
94084c
+++ b/support/support_socket_so_timestamp_time64.c
94084c
@@ -0,0 +1,48 @@
94084c
+/* Return whether socket supports 64-bit timestamps.
94084c
+   Copyright (C) 2022 Free Software Foundation, Inc.
94084c
+   This file is part of the GNU C Library.
94084c
+
94084c
+   The GNU C Library is free software; you can redistribute it and/or
94084c
+   modify it under the terms of the GNU Lesser General Public
94084c
+   License as published by the Free Software Foundation; either
94084c
+   version 2.1 of the License, or (at your option) any later version.
94084c
+
94084c
+   The GNU C Library is distributed in the hope that it will be useful,
94084c
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
94084c
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
94084c
+   Lesser General Public License for more details.
94084c
+
94084c
+   You should have received a copy of the GNU Lesser General Public
94084c
+   License along with the GNU C Library; if not, see
94084c
+   <https://www.gnu.org/licenses/>.  */
94084c
+
94084c
+#include <errno.h>
94084c
+#include <unistd.h>
94084c
+#include <sys/syscall.h>
94084c
+#include <sys/socket.h>
94084c
+#include <support/support.h>
94084c
+#ifdef __linux__
94084c
+# include <socket-constants-time64.h>
94084c
+#endif
94084c
+
94084c
+bool
94084c
+support_socket_so_timestamp_time64 (int fd)
94084c
+{
94084c
+#ifdef __linux__
94084c
+# if __LINUX_KERNEL_VERSION >= 0x050100                          \
94084c
+   || __WORDSIZE == 64                                           \
94084c
+   || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64)
94084c
+  return true;
94084c
+# else
94084c
+  int level = SOL_SOCKET;
94084c
+  int optname = COMPAT_SO_TIMESTAMP_NEW;
94084c
+  int optval;
94084c
+  socklen_t len = sizeof (optval);
94084c
+
94084c
+  int r = syscall (__NR_getsockopt, fd, level, optname, &optval, &len;;
94084c
+  return r != -1;
94084c
+# endif
94084c
+#else
94084c
+  return false;
94084c
+#endif
94084c
+}