[glib/wip/smcv/simplify-openpty-linking] tests: Call openpty (if available) without using dlsym




commit d75e0c0471ff235ab24522c8c2edc6026f098992
Author: Simon McVittie <smcv collabora com>
Date:   Sat Mar 19 11:16:46 2022 +0000

    tests: Call openpty (if available) without using dlsym
    
    The SONAME of libutil varies between architectures, so the logic to find
    the SONAME of libutil was only correct for native builds (Linux on
    Linux), not for cross-builds. The regular expression was also not
    sufficiently broad to match the SONAME used on the alpha architecture,
    which is apparently libutil.so.1.1.
    
    Instead of screen-scraping the output of ldconfig and using that to
    dlopen the library that contains openpty, it seems more reliable to
    emit a link-time reference to openpty and let the linker do its job.
    It's also less code.
    
    Bug-Debian: https://bugs.debian.org/1007946
    Signed-off-by: Simon McVittie <smcv collabora com>

 gio/tests/meson.build | 30 +++++++++++++++---------------
 gio/tests/pollable.c  | 36 ++++++++++++++----------------------
 2 files changed, 29 insertions(+), 37 deletions(-)
---
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index c825b0cd7..56a04cce1 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -12,20 +12,20 @@ test_c_args = [
   '-UG_DISABLE_ASSERT',
 ]
 
-# workaround for https://github.com/mesonbuild/meson/issues/6880
-if build_machine.system() == 'linux'
-  libutil_name = 'libutil'
-  libutil = run_command('sh', '-c',
-    '''ldconfig -p | grep -o "[[:space:]]@0@\.so\(\.[0-9]\+\)\?\b"'''
-    .format(libutil_name), check: false).stdout().strip().split('\n')
-
-  if libutil.length() > 0
-      message('Found libutil as @0@'.format(libutil[0]))
-      test_c_args += '-DLIBUTIL_SONAME="@0@"'.format(libutil[0])
-  else
-      warning('libutil not found')
-  endif # libutil.length() > 0
-endif # build_machine.system() == 'linux'
+libutil_dep = dependency('', required : false)
+
+if cc.has_header('pty.h')
+  have_openpty = cc.has_function('openpty', prefix : '#include <pty.h>')
+
+  if host_machine.system() == 'linux' and not have_openpty
+    libutil_dep = cc.find_library('util', required : false)
+    have_openpty = cc.has_function('openpty', dependencies : libutil_dep, prefix : '#include <pty.h>')
+  endif
+
+  if have_openpty
+    test_c_args += '-DHAVE_OPENPTY'
+  endif
+endif
 
 if host_machine.system() == 'windows'
   common_gio_tests_deps += [iphlpapi_dep, winsock2, cc.find_library ('secur32')]
@@ -91,7 +91,7 @@ gio_tests = {
   'network-monitor' : {},
   'network-monitor-race' : {},
   'permission' : {},
-  'pollable' : {'dependencies' : [libdl_dep]},
+  'pollable' : {'dependencies' : [libutil_dep]},
   'power-profile-monitor' : {},
   'proxy-test' : {},
   'readwrite' : {},
diff --git a/gio/tests/pollable.c b/gio/tests/pollable.c
index 516d7f4e4..be7d6e0f8 100644
--- a/gio/tests/pollable.c
+++ b/gio/tests/pollable.c
@@ -22,12 +22,20 @@
 #include <glib/gstdio.h>
 
 #ifdef G_OS_UNIX
-#include <dlfcn.h>
 #include <fcntl.h>
+#ifdef HAVE_OPENPTY
+#include <pty.h>
+#endif
 #include <gio/gunixinputstream.h>
 #include <gio/gunixoutputstream.h>
 #endif
 
+/* openpty() is non-standard and might not be available on all kernels
+ * and libc implementations, but glibc on Linux definitely has it */
+#if defined(__linux__) && defined(__GNUC__) !defined(HAVE_OPENPTY)
+#error Should have been able to find openpty on GNU/Linux
+#endif
+
 GMainLoop *loop;
 GPollableInputStream *in;
 GOutputStream *out;
@@ -185,31 +193,19 @@ test_pollable_unix_pipe (void)
 static void
 test_pollable_unix_pty (void)
 {
-  int (*openpty_impl) (int *, int *, char *, void *, void *);
+#ifdef HAVE_OPENPTY
   int a, b, status;
-#ifdef LIBUTIL_SONAME
-  void *handle;
 #endif
 
   g_test_summary ("Test that PTYs are considered pollable");
 
-#ifdef LIBUTIL_SONAME
-  handle = dlopen (LIBUTIL_SONAME, RTLD_GLOBAL | RTLD_LAZY);
-  g_assert_nonnull (handle);
-#endif
+#ifdef HAVE_OPENPTY
+  status = openpty (&a, &b, NULL, NULL, NULL);
 
-  openpty_impl = dlsym (RTLD_DEFAULT, "openpty");
-  if (openpty_impl == NULL)
-    {
-      g_test_skip ("System does not support openpty()");
-      goto close_libutil;
-    }
-
-  status = openpty_impl (&a, &b, NULL, NULL, NULL);
   if (status == -1)
     {
       g_test_skip ("Unable to open PTY");
-      goto close_libutil;
+      return;
     }
 
   in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (a, TRUE));
@@ -222,12 +218,8 @@ test_pollable_unix_pty (void)
 
   close (a);
   close (b);
-
-close_libutil:
-#ifdef LIBUTIL_SONAME
-  dlclose (handle);
 #else
-  return;
+  g_test_skip ("openpty not found");
 #endif
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]