mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-05 02:36:19 +01:00
Merge branch 'win32-socket' into 'main'
Various socket-related fixes for win32 See merge request GNOME/glib!2599
This commit is contained in:
commit
9c9a26215d
@ -167,6 +167,9 @@
|
|||||||
#include <gio/gtlsinteraction.h>
|
#include <gio/gtlsinteraction.h>
|
||||||
#include <gio/gtlspassword.h>
|
#include <gio/gtlspassword.h>
|
||||||
#include <gio/gtlsserverconnection.h>
|
#include <gio/gtlsserverconnection.h>
|
||||||
|
#include <gio/gunixconnection.h>
|
||||||
|
#include <gio/gunixcredentialsmessage.h>
|
||||||
|
#include <gio/gunixsocketaddress.h>
|
||||||
#include <gio/gvfs.h>
|
#include <gio/gvfs.h>
|
||||||
#include <gio/gvolume.h>
|
#include <gio/gvolume.h>
|
||||||
#include <gio/gvolumemonitor.h>
|
#include <gio/gvolumemonitor.h>
|
||||||
|
@ -1682,6 +1682,7 @@ test_nonce_tcp (void)
|
|||||||
gchar *nonce_file;
|
gchar *nonce_file;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
const gchar *address;
|
const gchar *address;
|
||||||
|
int fd;
|
||||||
|
|
||||||
test_guid = g_dbus_generate_guid ();
|
test_guid = g_dbus_generate_guid ();
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
@ -1780,7 +1781,9 @@ test_nonce_tcp (void)
|
|||||||
g_assert (c == NULL);
|
g_assert (c == NULL);
|
||||||
|
|
||||||
/* Recreate the nonce-file so we can ensure the server deletes it when stopped. */
|
/* Recreate the nonce-file so we can ensure the server deletes it when stopped. */
|
||||||
g_assert_cmpint (g_creat (nonce_file, 0600), !=, -1);
|
fd = g_creat (nonce_file, 0600);
|
||||||
|
g_assert_cmpint (fd, !=, -1);
|
||||||
|
g_close (fd, NULL);
|
||||||
|
|
||||||
g_dbus_server_stop (server);
|
g_dbus_server_stop (server);
|
||||||
g_object_unref (server);
|
g_object_unref (server);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
#include "glib-private.h"
|
||||||
|
|
||||||
#include <gio/gcredentialsprivate.h>
|
#include <gio/gcredentialsprivate.h>
|
||||||
#include <gio/gunixconnection.h>
|
#include <gio/gunixconnection.h>
|
||||||
@ -32,6 +33,7 @@
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include "giowin32-afunix.h"
|
#include "giowin32-afunix.h"
|
||||||
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gnetworkingprivate.h"
|
#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_family (server), ==, family);
|
||||||
g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type);
|
g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type);
|
||||||
g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
|
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);
|
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_family (client), ==, family);
|
||||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
|
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);
|
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_blocking (client, TRUE);
|
||||||
g_socket_set_timeout (client, 1);
|
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_family (client), ==, family);
|
||||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
|
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);
|
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_blocking (client, TRUE);
|
||||||
g_socket_set_timeout (client, 1);
|
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_family (client), ==, family);
|
||||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
|
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);
|
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
|
#ifdef G_OS_WIN32
|
||||||
/* Winsock can't recv() on unbound udp socket */
|
/* 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_family (client), ==, family);
|
||||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
|
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);
|
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_blocking (client, TRUE);
|
||||||
g_socket_set_timeout (client, 1);
|
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_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_socket_type (client2), ==, g_socket_get_socket_type (client));
|
||||||
g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP);
|
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);
|
len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error);
|
||||||
g_assert_no_error (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_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_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
|
||||||
g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
|
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);
|
g_object_unref (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1511,6 +1533,35 @@ test_unix_connection_ancillary_data (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
static gboolean
|
||||||
postmortem_source_cb (GSocket *socket,
|
postmortem_source_cb (GSocket *socket,
|
||||||
GIOCondition condition,
|
GIOCondition condition,
|
||||||
@ -2327,6 +2378,9 @@ main (int argc,
|
|||||||
g_test_add_func ("/socket/unix-connection", test_unix_connection);
|
g_test_add_func ("/socket/unix-connection", test_unix_connection);
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
|
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
|
#endif
|
||||||
g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
|
g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
|
||||||
g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
|
g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
|
||||||
|
@ -39,7 +39,7 @@ create_fd_list (gint *fd_list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_fds (void)
|
test_scm (void)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
GUnixFDMessage *message;
|
GUnixFDMessage *message;
|
||||||
@ -235,7 +235,7 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
g_test_add_func ("/unix-streams/file-descriptors", test_fds);
|
g_test_add_func ("/unix-fd/scm", test_scm);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
|
|
||||||
|
@ -43,6 +43,9 @@ gboolean _g_win32_call_rtl_version (OSVERSIONINFOEXW *info);
|
|||||||
|
|
||||||
extern HMODULE glib_dll;
|
extern HMODULE glib_dll;
|
||||||
gchar *g_win32_find_helper_executable_path (const gchar *process_name, void *dll_handle);
|
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
|
#endif
|
||||||
|
|
||||||
#endif /* __GLIB_INIT_H__ */
|
#endif /* __GLIB_INIT_H__ */
|
||||||
|
@ -55,6 +55,8 @@ glib__private__ (void)
|
|||||||
g_win32_readlink_utf8,
|
g_win32_readlink_utf8,
|
||||||
g_win32_fstat,
|
g_win32_fstat,
|
||||||
g_win32_find_helper_executable_path,
|
g_win32_find_helper_executable_path,
|
||||||
|
g_win32_reopen_noninherited,
|
||||||
|
g_win32_handle_is_socket,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,6 +171,13 @@ typedef struct {
|
|||||||
/* See gwin32.c */
|
/* See gwin32.c */
|
||||||
gchar *(*g_win32_find_helper_executable_path) (const gchar *process_name,
|
gchar *(*g_win32_find_helper_executable_path) (const gchar *process_name,
|
||||||
void *dll_handle);
|
void *dll_handle);
|
||||||
|
|
||||||
|
int (* g_win32_reopen_noninherited) (int fd,
|
||||||
|
int mode,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
|
gboolean (* g_win32_handle_is_socket) (void *handle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#define GSPAWN_HELPER
|
#define GSPAWN_HELPER
|
||||||
#include "gspawn-win32.c" /* For shared definitions */
|
#include "gspawn-win32.c" /* For shared definitions */
|
||||||
|
#include "glib/glib-private.h"
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -295,7 +296,8 @@ main (int ignored_argc, char **ignored_argv)
|
|||||||
/* GUI application do not necessarily have a stderr */
|
/* GUI application do not necessarily have a stderr */
|
||||||
if (_fileno (stderr) == 2)
|
if (_fileno (stderr) == 2)
|
||||||
{
|
{
|
||||||
saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
|
saved_stderr_fd = GLIB_PRIVATE_CALL (g_win32_reopen_noninherited) (
|
||||||
|
dup (2), _O_WRONLY, NULL);
|
||||||
if (saved_stderr_fd == -1)
|
if (saved_stderr_fd == -1)
|
||||||
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
|
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
|
||||||
}
|
}
|
||||||
@ -403,8 +405,10 @@ main (int ignored_argc, char **ignored_argv)
|
|||||||
/* We don't want our child to inherit the error report and
|
/* We don't want our child to inherit the error report and
|
||||||
* helper sync fds.
|
* helper sync fds.
|
||||||
*/
|
*/
|
||||||
child_err_report_fd = reopen_noninherited (child_err_report_fd, _O_WRONLY);
|
child_err_report_fd = GLIB_PRIVATE_CALL (g_win32_reopen_noninherited) (
|
||||||
helper_sync_fd = reopen_noninherited (helper_sync_fd, _O_RDONLY);
|
child_err_report_fd, _O_WRONLY, NULL);
|
||||||
|
helper_sync_fd = GLIB_PRIVATE_CALL (g_win32_reopen_noninherited) (
|
||||||
|
helper_sync_fd, _O_RDONLY, NULL);
|
||||||
if (helper_sync_fd == -1)
|
if (helper_sync_fd == -1)
|
||||||
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
|
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
|
||||||
|
|
||||||
|
@ -107,19 +107,6 @@ enum {
|
|||||||
ARG_COUNT = ARG_PROGRAM
|
ARG_COUNT = ARG_PROGRAM
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
reopen_noninherited (int fd,
|
|
||||||
int mode)
|
|
||||||
{
|
|
||||||
HANDLE filehandle;
|
|
||||||
|
|
||||||
DuplicateHandle (GetCurrentProcess (), (LPHANDLE) _get_osfhandle (fd),
|
|
||||||
GetCurrentProcess (), &filehandle,
|
|
||||||
0, FALSE, DUPLICATE_SAME_ACCESS);
|
|
||||||
close (fd);
|
|
||||||
return _open_osfhandle ((gintptr) filehandle, mode | _O_NOINHERIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef GSPAWN_HELPER
|
#ifndef GSPAWN_HELPER
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@ -684,7 +671,10 @@ fork_exec (gint *exit_status,
|
|||||||
* helper process, and the started actual user process. As such that
|
* helper process, and the started actual user process. As such that
|
||||||
* shouldn't harm, but it is unnecessary.
|
* shouldn't harm, but it is unnecessary.
|
||||||
*/
|
*/
|
||||||
child_err_report_pipe[0] = reopen_noninherited (child_err_report_pipe[0], _O_RDONLY);
|
child_err_report_pipe[0] = g_win32_reopen_noninherited (
|
||||||
|
child_err_report_pipe[0], _O_RDONLY, error);
|
||||||
|
if (child_err_report_pipe[0] == -1)
|
||||||
|
goto cleanup_and_fail;
|
||||||
|
|
||||||
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
|
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
|
||||||
{
|
{
|
||||||
@ -703,7 +693,10 @@ fork_exec (gint *exit_status,
|
|||||||
* process won't read but won't get any EOF either, as it has the
|
* process won't read but won't get any EOF either, as it has the
|
||||||
* write end open itself.
|
* write end open itself.
|
||||||
*/
|
*/
|
||||||
helper_sync_pipe[1] = reopen_noninherited (helper_sync_pipe[1], _O_WRONLY);
|
helper_sync_pipe[1] = g_win32_reopen_noninherited (
|
||||||
|
helper_sync_pipe[1], _O_WRONLY, error);
|
||||||
|
if (helper_sync_pipe[1] == -1)
|
||||||
|
goto cleanup_and_fail;
|
||||||
|
|
||||||
if (stdin_fd != -1)
|
if (stdin_fd != -1)
|
||||||
{
|
{
|
||||||
@ -903,7 +896,8 @@ fork_exec (gint *exit_status,
|
|||||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
char *emsg = g_win32_error_message (GetLastError ());
|
char *emsg = g_win32_error_message (GetLastError ());
|
||||||
g_print("%s\n", emsg);
|
g_print ("%s\n", emsg);
|
||||||
|
g_free (emsg);
|
||||||
*child_pid = 0;
|
*child_pid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
118
glib/gwin32.c
118
glib/gwin32.c
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "glibconfig.h"
|
#include "glibconfig.h"
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -39,6 +40,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#define STRICT /* Strict typing, please */
|
#define STRICT /* Strict typing, please */
|
||||||
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#undef STRICT
|
#undef STRICT
|
||||||
#ifndef G_WITH_CYGWIN
|
#ifndef G_WITH_CYGWIN
|
||||||
@ -805,8 +807,6 @@ g_win32_get_command_line (void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
|
|
||||||
/* Binary compatibility versions. Not for newly compiled code. */
|
/* Binary compatibility versions. Not for newly compiled code. */
|
||||||
|
|
||||||
_GLIB_EXTERN gchar *g_win32_get_package_installation_directory_utf8 (const gchar *package,
|
_GLIB_EXTERN gchar *g_win32_get_package_installation_directory_utf8 (const gchar *package,
|
||||||
@ -837,10 +837,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
|
|
||||||
/* This function looks up two environment
|
/* This function looks up two environment
|
||||||
* variables, G_WIN32_ALLOC_CONSOLE and G_WIN32_ATTACH_CONSOLE.
|
* variables, G_WIN32_ALLOC_CONSOLE and G_WIN32_ATTACH_CONSOLE.
|
||||||
* G_WIN32_ALLOC_CONSOLE, if set to 1, makes the process
|
* G_WIN32_ALLOC_CONSOLE, if set to 1, makes the process
|
||||||
@ -1455,4 +1451,112 @@ g_win32_find_helper_executable_path (const gchar *executable_name, void *dll_han
|
|||||||
return executable_path;
|
return executable_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
/*
|
||||||
|
* 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
|
||||||
|
* @mode: _open_osfhandle flags
|
||||||
|
* @error: A location to return an error of type %G_FILE_ERROR
|
||||||
|
*
|
||||||
|
* Reopen the given @fd with `_O_NOINHERIT`.
|
||||||
|
*
|
||||||
|
* The @fd is closed on success.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): The new file-descriptor, or -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
g_win32_reopen_noninherited (int fd,
|
||||||
|
int mode,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
HANDLE duph;
|
||||||
|
int dupfd, errsv;
|
||||||
|
|
||||||
|
h = (HANDLE) _get_osfhandle (fd);
|
||||||
|
errsv = errno;
|
||||||
|
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
const char *emsg = g_strerror (errsv);
|
||||||
|
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
|
||||||
|
"_get_osfhandle() failed: %s", emsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_win32_handle_is_socket (h))
|
||||||
|
{
|
||||||
|
WSAPROTOCOL_INFO info;
|
||||||
|
|
||||||
|
if (WSADuplicateSocket ((SOCKET) h,
|
||||||
|
GetCurrentProcessId (),
|
||||||
|
&info))
|
||||||
|
{
|
||||||
|
gchar *emsg = g_win32_error_message (WSAGetLastError ());
|
||||||
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
"WSADuplicateSocket() failed: %s", emsg);
|
||||||
|
g_free (emsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
duph = (HANDLE) WSASocket (FROM_PROTOCOL_INFO,
|
||||||
|
FROM_PROTOCOL_INFO,
|
||||||
|
FROM_PROTOCOL_INFO,
|
||||||
|
&info, 0, 0);
|
||||||
|
if (duph == (HANDLE) INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
gchar *emsg = g_win32_error_message (WSAGetLastError ());
|
||||||
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
"WSASocket() failed: %s", emsg);
|
||||||
|
g_free (emsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DuplicateHandle (GetCurrentProcess (), h,
|
||||||
|
GetCurrentProcess (), &duph,
|
||||||
|
0, FALSE, DUPLICATE_SAME_ACCESS) == 0)
|
||||||
|
{
|
||||||
|
char *emsg = g_win32_error_message (GetLastError ());
|
||||||
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
"DuplicateHandle() failed: %s", emsg);
|
||||||
|
g_free (emsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the duph ownership is transferred to dupfd */
|
||||||
|
dupfd = _open_osfhandle ((gintptr) duph, mode | _O_NOINHERIT);
|
||||||
|
if (dupfd < 0)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
"_open_osfhandle() failed");
|
||||||
|
CloseHandle (duph);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_close (fd, error))
|
||||||
|
{
|
||||||
|
/* ignore extra errors in this case */
|
||||||
|
g_close (dupfd, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dupfd;
|
||||||
|
}
|
||||||
|
@ -108,7 +108,9 @@ glib_tests = {
|
|||||||
'sort' : {},
|
'sort' : {},
|
||||||
'spawn-multithreaded' : {},
|
'spawn-multithreaded' : {},
|
||||||
'spawn-path-search' : {},
|
'spawn-path-search' : {},
|
||||||
'spawn-singlethread' : {},
|
'spawn-singlethread' : {
|
||||||
|
'dependencies' : [winsock2],
|
||||||
|
},
|
||||||
'spawn-test' : {},
|
'spawn-test' : {},
|
||||||
'strfuncs' : {},
|
'strfuncs' : {},
|
||||||
'string' : {},
|
'string' : {},
|
||||||
@ -306,6 +308,13 @@ if host_machine.system() == 'windows'
|
|||||||
install_dir: installed_tests_execdir,
|
install_dir: installed_tests_execdir,
|
||||||
install: installed_tests_enabled,
|
install: installed_tests_enabled,
|
||||||
)
|
)
|
||||||
|
executable('spawn-test-win32-gui', 'spawn-test-win32-gui.c',
|
||||||
|
c_args : test_cargs,
|
||||||
|
dependencies : test_deps,
|
||||||
|
install_dir: installed_tests_execdir,
|
||||||
|
install: installed_tests_enabled,
|
||||||
|
win_subsystem: 'windows',
|
||||||
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
executable('testing-helper', 'testing-helper.c',
|
executable('testing-helper', 'testing-helper.c',
|
||||||
|
@ -32,11 +32,13 @@
|
|||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
#include <glib-unix.h>
|
#include <glib-unix.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define LINEEND "\r\n"
|
#define LINEEND "\r\n"
|
||||||
#else
|
#else
|
||||||
@ -353,6 +355,56 @@ test_spawn_sync (void)
|
|||||||
g_free (joined_args_str);
|
g_free (joined_args_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_networking (void)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
|
||||||
|
g_error ("Windows Sockets could not be initialized");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_spawn_stderr_socket (void)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GPtrArray *argv;
|
||||||
|
int estatus;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
g_test_summary ("Test calling g_spawn_sync() with its stderr FD set to a socket");
|
||||||
|
|
||||||
|
if (g_test_subprocess ())
|
||||||
|
{
|
||||||
|
init_networking ();
|
||||||
|
fd = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
fd = _open_osfhandle (fd, 0);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
#endif
|
||||||
|
/* Set the socket as FD 2, stderr */
|
||||||
|
estatus = dup2 (fd, 2);
|
||||||
|
g_assert_cmpint (estatus, >=, 0);
|
||||||
|
|
||||||
|
argv = g_ptr_array_new ();
|
||||||
|
g_ptr_array_add (argv, echo_script_path);
|
||||||
|
g_ptr_array_add (argv, NULL);
|
||||||
|
|
||||||
|
g_spawn_sync (NULL, (char**) argv->pdata, NULL, 0, NULL, NULL, NULL, NULL, NULL, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_ptr_array_free (argv, TRUE);
|
||||||
|
g_close (fd, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_test_trap_subprocess (NULL, 0, 0);
|
||||||
|
g_test_trap_assert_passed ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Like test_spawn_sync but uses spawn flags that trigger the optimized
|
/* Like test_spawn_sync but uses spawn flags that trigger the optimized
|
||||||
* posix_spawn codepath.
|
* posix_spawn codepath.
|
||||||
*/
|
*/
|
||||||
@ -517,6 +569,7 @@ main (int argc,
|
|||||||
g_assert (g_file_test (echo_script_path, G_FILE_TEST_EXISTS));
|
g_assert (g_file_test (echo_script_path, G_FILE_TEST_EXISTS));
|
||||||
|
|
||||||
g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync);
|
g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync);
|
||||||
|
g_test_add_func ("/gthread/spawn-stderr-socket", test_spawn_stderr_socket);
|
||||||
g_test_add_func ("/gthread/spawn-single-async", test_spawn_async);
|
g_test_add_func ("/gthread/spawn-single-async", test_spawn_async);
|
||||||
g_test_add_func ("/gthread/spawn-single-async-with-fds", test_spawn_async_with_fds);
|
g_test_add_func ("/gthread/spawn-single-async-with-fds", test_spawn_async_with_fds);
|
||||||
g_test_add_func ("/gthread/spawn-script", test_spawn_script);
|
g_test_add_func ("/gthread/spawn-script", test_spawn_script);
|
||||||
|
@ -114,6 +114,9 @@ if cc.has_argument('-fno-strict-aliasing')
|
|||||||
add_project_arguments('-fno-strict-aliasing', language: 'c')
|
add_project_arguments('-fno-strict-aliasing', language: 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# dummy/empty dependency() object to declare fallbacks and simpler dependencies
|
||||||
|
not_found = dependency('', required: false)
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Configuration begins #
|
# Configuration begins #
|
||||||
########################
|
########################
|
||||||
@ -2134,6 +2137,8 @@ endif
|
|||||||
|
|
||||||
if host_system == 'windows'
|
if host_system == 'windows'
|
||||||
winsock2 = cc.find_library('ws2_32')
|
winsock2 = cc.find_library('ws2_32')
|
||||||
|
else
|
||||||
|
winsock2 = not_found
|
||||||
endif
|
endif
|
||||||
|
|
||||||
selinux_dep = []
|
selinux_dep = []
|
||||||
|
@ -42,12 +42,6 @@ test_extra_programs = {
|
|||||||
'assert-msg-test' : {},
|
'assert-msg-test' : {},
|
||||||
}
|
}
|
||||||
|
|
||||||
if host_machine.system() == 'windows'
|
|
||||||
test_extra_programs += {
|
|
||||||
'spawn-test-win32-gui' : {'win_subsystem' : 'windows'}
|
|
||||||
}
|
|
||||||
endif
|
|
||||||
|
|
||||||
module_suffix = []
|
module_suffix = []
|
||||||
# Keep the autotools convention for shared module suffix because GModule
|
# Keep the autotools convention for shared module suffix because GModule
|
||||||
# depends on it: https://gitlab.gnome.org/GNOME/glib/issues/520
|
# depends on it: https://gitlab.gnome.org/GNOME/glib/issues/520
|
||||||
|
Loading…
Reference in New Issue
Block a user