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