[glib: 9/12] glib/win32: introduce private g_win32_handle_is_socket()




commit 277657eaccc9dfcc16b177e95cc1df55e5c5be0f
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Fri Apr 8 14:49:49 2022 +0400

    glib/win32: introduce private g_win32_handle_is_socket()
    
    Used in following commits, including in some GIO experiments.
    
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 gio/tests/socket.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 glib/glib-init.h    |  1 +
 glib/glib-private.c |  1 +
 glib/glib-private.h |  3 +++
 glib/gwin32.c       | 19 ++++++++++++++++++
 5 files changed, 79 insertions(+), 1 deletion(-)
---
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index d271310c00..9a5092642c 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -18,6 +18,7 @@
 
 #include <gio/gio.h>
 #include <glib/gstdio.h>
+#include "glib-private.h"
 
 #include <gio/gcredentialsprivate.h>
 #include <gio/gunixconnection.h>
@@ -32,6 +33,7 @@
 
 #ifdef G_OS_WIN32
 #include "giowin32-afunix.h"
+#include <io.h>
 #endif
 
 #include "gnetworkingprivate.h"
@@ -139,6 +141,9 @@ create_server_full (GSocketFamily   family,
   g_assert_cmpint (g_socket_get_family (server), ==, family);
   g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type);
   g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (server)));
+#endif
 
   g_socket_set_blocking (server, TRUE);
 
@@ -475,7 +480,9 @@ test_ip_sync (GSocketFamily family)
   g_assert_cmpint (g_socket_get_family (client), ==, family);
   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
-
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
+#endif
   g_socket_set_blocking (client, TRUE);
   g_socket_set_timeout (client, 1);
 
@@ -612,6 +619,9 @@ test_ip_sync_dgram (GSocketFamily family)
   g_assert_cmpint (g_socket_get_family (client), ==, family);
   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
+#endif
 
   g_socket_set_blocking (client, TRUE);
   g_socket_set_timeout (client, 1);
@@ -849,6 +859,9 @@ test_ip_sync_dgram_timeouts (GSocketFamily family)
   g_assert_cmpint (g_socket_get_family (client), ==, family);
   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
+#endif
 
 #ifdef G_OS_WIN32
   /* Winsock can't recv() on unbound udp socket */
@@ -991,6 +1004,9 @@ test_close_graceful (void)
   g_assert_cmpint (g_socket_get_family (client), ==, family);
   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
+#endif
 
   g_socket_set_blocking (client, TRUE);
   g_socket_set_timeout (client, 1);
@@ -1258,6 +1274,9 @@ test_fd_reuse (void)
   g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client));
   g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client));
   g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
+#endif
 
   len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error);
   g_assert_no_error (error);
@@ -1377,6 +1396,9 @@ test_unix_from_fd (void)
   g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX);
   g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
   g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
+#ifdef G_OS_WIN32
+  g_assert (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (s)));
+#endif
   g_object_unref (s);
 }
 
@@ -1511,6 +1533,35 @@ test_unix_connection_ancillary_data (void)
 }
 #endif
 
+#ifdef G_OS_WIN32
+static void
+test_handle_not_socket (void)
+{
+  GError *err = NULL;
+  gchar *name = NULL;
+  HANDLE hReadPipe, hWritePipe, h;
+  int fd;
+
+  g_assert_true (CreatePipe (&hReadPipe, &hWritePipe, NULL, 2048));
+  g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (hReadPipe));
+  g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (hWritePipe));
+  CloseHandle (hReadPipe);
+  CloseHandle (hWritePipe);
+
+  h = (HANDLE) _get_osfhandle (1);
+  g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (h));
+
+  fd = g_file_open_tmp (NULL, &name, &err);
+  g_assert_no_error (err);
+  h = (HANDLE) _get_osfhandle (fd);
+  g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (h));
+  g_close (fd, &err);
+  g_assert_no_error (err);
+  g_unlink (name);
+  g_free (name);
+}
+#endif
+
 static gboolean
 postmortem_source_cb (GSocket      *socket,
                       GIOCondition  condition,
@@ -2327,6 +2378,9 @@ main (int   argc,
   g_test_add_func ("/socket/unix-connection", test_unix_connection);
 #ifdef G_OS_UNIX
   g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
+#endif
+#ifdef G_OS_WIN32
+  g_test_add_func ("/socket/win32-handle-not-socket", test_handle_not_socket);
 #endif
   g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
   g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
diff --git a/glib/glib-init.h b/glib/glib-init.h
index b01d256b98..73e186199d 100644
--- a/glib/glib-init.h
+++ b/glib/glib-init.h
@@ -44,6 +44,7 @@ gboolean _g_win32_call_rtl_version (OSVERSIONINFOEXW *info);
 extern HMODULE glib_dll;
 gchar *g_win32_find_helper_executable_path (const gchar *process_name, void *dll_handle);
 int g_win32_reopen_noninherited (int fd, int mode, GError **err);
+gboolean g_win32_handle_is_socket (void *h);
 
 #endif
 
diff --git a/glib/glib-private.c b/glib/glib-private.c
index 357a43a30d..321efc1d6e 100644
--- a/glib/glib-private.c
+++ b/glib/glib-private.c
@@ -56,6 +56,7 @@ glib__private__ (void)
     g_win32_fstat,
     g_win32_find_helper_executable_path,
     g_win32_reopen_noninherited,
+    g_win32_handle_is_socket,
 #endif
   };
 
diff --git a/glib/glib-private.h b/glib/glib-private.h
index 787f8f1fab..39b7c0a8e7 100644
--- a/glib/glib-private.h
+++ b/glib/glib-private.h
@@ -175,6 +175,9 @@ typedef struct {
   int                   (* g_win32_reopen_noninherited) (int      fd,
                                                          int      mode,
                                                          GError **err);
+
+  gboolean              (* g_win32_handle_is_socket)    (void *handle);
+
 #endif
 
 
diff --git a/glib/gwin32.c b/glib/gwin32.c
index a4ed386bae..c0e1d7f3fb 100644
--- a/glib/gwin32.c
+++ b/glib/gwin32.c
@@ -1450,6 +1450,25 @@ g_win32_find_helper_executable_path (const gchar *executable_name, void *dll_han
   return executable_path;
 }
 
+/*
+ * g_win32_handle_is_socket:
+ * @h: a win32 HANDLE
+ *
+ * Returns: %TRUE if the handle is a `SOCKET`.
+ */
+gboolean
+g_win32_handle_is_socket (HANDLE h)
+{
+  int option = 0;
+  int optlen = sizeof (option);
+
+  /* according to: https://stackoverflow.com/a/50981652/1277510, this is reasonable */
+  if (getsockopt ((SOCKET) h, SOL_SOCKET, SO_DEBUG, (char *) &option, &optlen) == SOCKET_ERROR)
+    return FALSE;
+
+  return TRUE;
+}
+
 /*
  * g_win32_reopen_noninherited:
  * @fd: (transfer full): A file descriptor


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