mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-28 02:20:04 +01:00
Merge branch 'windows-static-build-postfixes' into 'main'
Fix tests with static build on Windows See merge request GNOME/glib!2442
This commit is contained in:
commit
e01e6ef771
@ -23,27 +23,28 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "giotypes.h"
|
||||
#include "gioenumtypes.h"
|
||||
#include "gsocket.h"
|
||||
#include "gdbusauthobserver.h"
|
||||
#include "gdbusprivate.h"
|
||||
#include "gdbusmessage.h"
|
||||
#include "gdbusconnection.h"
|
||||
#include "gdbusproxy.h"
|
||||
#include "gdbusdaemon.h"
|
||||
#include "gdbuserror.h"
|
||||
#include "gdbusintrospection.h"
|
||||
#include "gdbusdaemon.h"
|
||||
#include "giomodule-priv.h"
|
||||
#include "gtask.h"
|
||||
#include "gdbusmessage.h"
|
||||
#include "gdbusprivate.h"
|
||||
#include "gdbusproxy.h"
|
||||
#include "ginputstream.h"
|
||||
#include "gmemoryinputstream.h"
|
||||
#include "gioenumtypes.h"
|
||||
#include "giomodule-priv.h"
|
||||
#include "giostream.h"
|
||||
#include "giotypes.h"
|
||||
#include "glib-private.h"
|
||||
#include "glib/gstdio.h"
|
||||
#include "gmemoryinputstream.h"
|
||||
#include "gsocket.h"
|
||||
#include "gsocketaddress.h"
|
||||
#include "gsocketcontrolmessage.h"
|
||||
#include "gsocketconnection.h"
|
||||
#include "gsocketcontrolmessage.h"
|
||||
#include "gsocketoutputstream.h"
|
||||
#include "gtask.h"
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#include "gunixfdmessage.h"
|
||||
@ -2275,6 +2276,26 @@ g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdsh
|
||||
|
||||
static gboolean autolaunch_binary_absent = FALSE;
|
||||
|
||||
static wchar_t *
|
||||
find_dbus_process_path (void)
|
||||
{
|
||||
wchar_t *dbus_path;
|
||||
gchar *exe_path = GLIB_PRIVATE_CALL (g_win32_find_helper_executable_path) ("gdbus.exe", _g_io_win32_get_module ());
|
||||
dbus_path = g_utf8_to_utf16 (exe_path, -1, NULL, NULL, NULL);
|
||||
g_free (exe_path);
|
||||
|
||||
if (dbus_path == NULL)
|
||||
return NULL;
|
||||
|
||||
if (GetFileAttributesW (dbus_path) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
g_free (dbus_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dbus_path;
|
||||
}
|
||||
|
||||
gchar *
|
||||
_g_dbus_win32_get_session_address_dbus_launch (GError **error)
|
||||
{
|
||||
@ -2292,61 +2313,53 @@ _g_dbus_win32_get_session_address_dbus_launch (GError **error)
|
||||
|
||||
if (address == NULL && !autolaunch_binary_absent)
|
||||
{
|
||||
wchar_t gio_path[MAX_PATH + 2] = { 0 };
|
||||
int gio_path_len = GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH + 1);
|
||||
wchar_t *dbus_path = find_dbus_process_path ();
|
||||
if (dbus_path == NULL)
|
||||
{
|
||||
/* warning won't be raised another time
|
||||
* since autolaunch_binary_absent would be already set.
|
||||
*/
|
||||
autolaunch_binary_absent = TRUE;
|
||||
g_warning ("win32 session dbus binary not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
STARTUPINFOW si = { 0 };
|
||||
BOOL res = FALSE;
|
||||
wchar_t args[MAX_PATH * 2 + 100] = { 0 };
|
||||
wchar_t working_dir[MAX_PATH + 2] = { 0 };
|
||||
wchar_t *p;
|
||||
|
||||
/* The <= MAX_PATH check prevents truncated path usage */
|
||||
if (gio_path_len > 0 && gio_path_len <= MAX_PATH)
|
||||
{
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
STARTUPINFOW si = { 0 };
|
||||
BOOL res = FALSE;
|
||||
wchar_t exe_path[MAX_PATH + 100] = { 0 };
|
||||
/* calculate index of first char of dll file name inside full path */
|
||||
int gio_name_index = gio_path_len;
|
||||
for (; gio_name_index > 0; --gio_name_index)
|
||||
{
|
||||
wchar_t prev_char = gio_path[gio_name_index - 1];
|
||||
if (prev_char == L'\\' || prev_char == L'/')
|
||||
break;
|
||||
}
|
||||
gio_path[gio_name_index] = L'\0';
|
||||
wcscpy (exe_path, gio_path);
|
||||
wcscat (exe_path, L"\\gdbus.exe");
|
||||
wcscpy (working_dir, dbus_path);
|
||||
p = wcsrchr (working_dir, L'\\');
|
||||
if (p != NULL)
|
||||
*p = L'\0';
|
||||
|
||||
if (GetFileAttributesW (exe_path) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
/* warning won't be raised another time
|
||||
* since autolaunch_binary_absent would be already set.
|
||||
*/
|
||||
autolaunch_binary_absent = TRUE;
|
||||
g_warning ("win32 session dbus binary not found: %S", exe_path );
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t args[MAX_PATH*2 + 100] = { 0 };
|
||||
wcscpy (args, L"\"");
|
||||
wcscat (args, exe_path);
|
||||
wcscat (args, L"\" ");
|
||||
wcscpy (args, L"\"");
|
||||
wcscat (args, dbus_path);
|
||||
wcscat (args, L"\" ");
|
||||
#define _L_PREFIX_FOR_EXPANDED(arg) L##arg
|
||||
#define _L_PREFIX(arg) _L_PREFIX_FOR_EXPANDED (arg)
|
||||
wcscat (args, _L_PREFIX (_GDBUS_ARG_WIN32_RUN_SESSION_BUS));
|
||||
wcscat (args, _L_PREFIX (_GDBUS_ARG_WIN32_RUN_SESSION_BUS));
|
||||
#undef _L_PREFIX
|
||||
#undef _L_PREFIX_FOR_EXPANDED
|
||||
|
||||
res = CreateProcessW (exe_path, args,
|
||||
0, 0, FALSE,
|
||||
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS,
|
||||
0, gio_path,
|
||||
&si, &pi);
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
||||
if (address == NULL)
|
||||
g_warning ("%S dbus binary failed to launch bus, maybe incompatible version", exe_path );
|
||||
}
|
||||
}
|
||||
res = CreateProcessW (dbus_path, args,
|
||||
0, 0, FALSE,
|
||||
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS,
|
||||
0, working_dir,
|
||||
&si, &pi);
|
||||
|
||||
if (res)
|
||||
{
|
||||
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
||||
if (address == NULL)
|
||||
g_warning ("%S dbus binary failed to launch bus, maybe incompatible version", dbus_path);
|
||||
}
|
||||
|
||||
g_free (dbus_path);
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex (autolaunch_mutex);
|
||||
|
@ -40,7 +40,9 @@ void g_clock_win32_init (void);
|
||||
void g_crash_handler_win32_init (void);
|
||||
void g_crash_handler_win32_deinit (void);
|
||||
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);
|
||||
#endif
|
||||
|
||||
#endif /* __GLIB_INIT_H__ */
|
||||
|
@ -54,6 +54,7 @@ glib__private__ (void)
|
||||
g_win32_lstat_utf8,
|
||||
g_win32_readlink_utf8,
|
||||
g_win32_fstat,
|
||||
g_win32_find_helper_executable_path,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -120,7 +120,6 @@ gboolean g_check_setuid (void);
|
||||
GMainContext * g_main_context_new_with_next_id (guint next_id);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
gchar *_glib_get_dll_directory (void);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gchar *_glib_get_locale_dir (void);
|
||||
#endif
|
||||
@ -168,6 +167,10 @@ typedef struct {
|
||||
|
||||
int (* g_win32_fstat) (int fd,
|
||||
GWin32PrivateStat *buf);
|
||||
|
||||
/* See gwin32.c */
|
||||
gchar *(*g_win32_find_helper_executable_path) (const gchar *process_name,
|
||||
void *dll_handle);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -42,10 +42,11 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "glib-init.h"
|
||||
#include "glib-private.h"
|
||||
#include "gprintfint.h"
|
||||
#include "glib.h"
|
||||
#include "glibintl.h"
|
||||
#include "gprintfint.h"
|
||||
#include "gspawn-private.h"
|
||||
#include "gthread.h"
|
||||
|
||||
@ -586,7 +587,6 @@ fork_exec (gint *exit_status,
|
||||
gint conv_error_index;
|
||||
gchar *helper_process;
|
||||
wchar_t *whelper, **wargv, **wenvp;
|
||||
gchar *glib_dll_directory;
|
||||
int stdin_pipe[2] = { -1, -1 };
|
||||
int stdout_pipe[2] = { -1, -1 };
|
||||
int stderr_pipe[2] = { -1, -1 };
|
||||
@ -651,16 +651,8 @@ fork_exec (gint *exit_status,
|
||||
helper_process = HELPER_PROCESS "-console.exe";
|
||||
else
|
||||
helper_process = HELPER_PROCESS ".exe";
|
||||
|
||||
glib_dll_directory = _glib_get_dll_directory ();
|
||||
if (glib_dll_directory != NULL)
|
||||
{
|
||||
helper_process = g_build_filename (glib_dll_directory, helper_process, NULL);
|
||||
g_free (glib_dll_directory);
|
||||
}
|
||||
else
|
||||
helper_process = g_strdup (helper_process);
|
||||
|
||||
helper_process = g_win32_find_helper_executable_path (helper_process, glib_dll);
|
||||
new_argv[0] = protect_argv_string (helper_process);
|
||||
|
||||
_g_sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]);
|
||||
|
@ -104,47 +104,6 @@
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
|
||||
gchar *
|
||||
_glib_get_dll_directory (void)
|
||||
{
|
||||
gchar *retval;
|
||||
gchar *p;
|
||||
wchar_t wc_fn[MAX_PATH];
|
||||
|
||||
#ifdef DLL_EXPORT
|
||||
if (glib_dll == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* This code is different from that in
|
||||
* g_win32_get_package_installation_directory_of_module() in that
|
||||
* here we return the actual folder where the GLib DLL is. We don't
|
||||
* do the check for it being in a "bin" or "lib" subfolder and then
|
||||
* returning the parent of that.
|
||||
*
|
||||
* In a statically built GLib, glib_dll will be NULL and we will
|
||||
* thus look up the application's .exe file's location.
|
||||
*/
|
||||
if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH))
|
||||
return NULL;
|
||||
|
||||
retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL);
|
||||
|
||||
p = strrchr (retval, G_DIR_SEPARATOR);
|
||||
if (p == NULL)
|
||||
{
|
||||
/* Wtf? */
|
||||
return NULL;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* g_memmove:
|
||||
* @dest: the destination address to copy the bytes to.
|
||||
|
119
glib/gwin32.c
119
glib/gwin32.c
@ -1336,4 +1336,123 @@ g_crash_handler_win32_deinit (void)
|
||||
WinVEH_handle = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_win32_find_helper_executable_path:
|
||||
* @executable_name: (transfer none): name of the helper executable to find
|
||||
* (something like gspawn-win64-helper.exe or gdbus.exe for example).
|
||||
* @dll_handle: handle of the DLL to use as searching base path. Pass NULL
|
||||
* to take current process executable as searching base path.
|
||||
*
|
||||
* Find an external executable path and name starting in the same folder
|
||||
* as a specified DLL or current process executable path. Helper executables
|
||||
* (like gspawn-win64-helper.exe, gspawn-win64-helper-console.exe or
|
||||
* gdbus.exe for example) are generally installed in the same folder as the
|
||||
* corresponding DLL file.
|
||||
*
|
||||
* So, if package has been correctly installed, with a dynamic build of GLib,
|
||||
* the helper executable should be in the same directory as the corresponding
|
||||
* DLL file and searching should be straightforward.
|
||||
*
|
||||
* But if built statically, DLL handle is not available and we have to start
|
||||
* searching from the directory holding current executable. It may be very
|
||||
* different from the directory containing the helper program. In order to
|
||||
* find the right helper program automatically in all common situations, we
|
||||
* use this pattern:
|
||||
*
|
||||
* current directory
|
||||
* |-- ???
|
||||
* |-- bin
|
||||
* | |-- ???
|
||||
* |-- lib
|
||||
* | |-- ???
|
||||
* |-- glib
|
||||
* | |-- ???
|
||||
* |-- gio
|
||||
* |-- ???
|
||||
*
|
||||
* starting at base searching path (DLL or current executable directory) and
|
||||
* getting up until the root path. If we cannot still find the helper program,
|
||||
* we'll rely on PATH as the last resort.
|
||||
*
|
||||
* Returns: (transfer full) (type filename) (nullable): the helper executable
|
||||
* path and name in the GLib filename encoding or NULL in case of error. It
|
||||
* should be deallocated with g_free().
|
||||
*/
|
||||
gchar *
|
||||
g_win32_find_helper_executable_path (const gchar *executable_name, void *dll_handle)
|
||||
{
|
||||
static const gchar *const subdirs[] = { "", "bin", "lib", "glib", "gio" };
|
||||
static const gsize nb_subdirs = G_N_ELEMENTS (subdirs);
|
||||
|
||||
DWORD module_path_len;
|
||||
wchar_t module_path[MAX_PATH + 2] = { 0 };
|
||||
gchar *base_searching_path;
|
||||
gchar *p;
|
||||
gchar *executable_path;
|
||||
gsize i;
|
||||
|
||||
g_return_val_if_fail (executable_name && *executable_name, NULL);
|
||||
|
||||
module_path_len = GetModuleFileNameW (dll_handle, module_path, MAX_PATH + 1);
|
||||
/* The > MAX_PATH check prevents truncated module path usage */
|
||||
if (module_path_len == 0 || module_path_len > MAX_PATH)
|
||||
return NULL;
|
||||
|
||||
base_searching_path = g_utf16_to_utf8 (module_path, -1, NULL, NULL, NULL);
|
||||
if (base_searching_path == NULL)
|
||||
return NULL;
|
||||
|
||||
p = strrchr (base_searching_path, G_DIR_SEPARATOR);
|
||||
if (p == NULL)
|
||||
{
|
||||
g_free (base_searching_path);
|
||||
return NULL;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Search in subdirectories */
|
||||
for (i = 0; i < nb_subdirs; ++i)
|
||||
{
|
||||
/* As this function is exclusively used on Windows, the
|
||||
* executable_path is always an absolute path. At worse, when
|
||||
* reaching the root of the filesystem, base_searching_path may
|
||||
* equal something like "[Drive letter]:" but never "/" like on
|
||||
* Linux or Mac.
|
||||
* For the peace of mind we still assert this, just in case that
|
||||
* one day someone tries to use this function on Linux or Mac.
|
||||
*/
|
||||
executable_path = g_build_filename (base_searching_path, subdirs[i], executable_name, NULL);
|
||||
g_assert (g_path_is_absolute (executable_path));
|
||||
if (g_file_test (executable_path, G_FILE_TEST_IS_REGULAR))
|
||||
break;
|
||||
|
||||
g_free (executable_path);
|
||||
executable_path = NULL;
|
||||
}
|
||||
|
||||
if (executable_path != NULL)
|
||||
break;
|
||||
|
||||
/* Let's get one directory level up */
|
||||
p = strrchr (base_searching_path, G_DIR_SEPARATOR);
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
*p = '\0';
|
||||
}
|
||||
g_free (base_searching_path);
|
||||
|
||||
if (executable_path == NULL)
|
||||
{
|
||||
/* Search in system PATH */
|
||||
executable_path = g_find_program_in_path (executable_name);
|
||||
if (executable_path == NULL)
|
||||
executable_path = g_strdup (executable_name);
|
||||
}
|
||||
|
||||
return executable_path;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,11 @@
|
||||
static void
|
||||
test_completion (void)
|
||||
{
|
||||
static const char *const a1 = "a\302\243";
|
||||
static const char *const a2 = "a\302\244";
|
||||
static const char *const bb = "bb";
|
||||
static const char *const bc = "bc";
|
||||
|
||||
GCompletion *cmp;
|
||||
GList *items;
|
||||
gchar *prefix;
|
||||
@ -42,10 +47,10 @@ test_completion (void)
|
||||
g_completion_set_compare (cmp, strncmp);
|
||||
|
||||
items = NULL;
|
||||
items = g_list_append (items, "a\302\243");
|
||||
items = g_list_append (items, "a\302\244");
|
||||
items = g_list_append (items, "bb");
|
||||
items = g_list_append (items, "bc");
|
||||
items = g_list_append (items, (gpointer) a1);
|
||||
items = g_list_append (items, (gpointer) a2);
|
||||
items = g_list_append (items, (gpointer) bb);
|
||||
items = g_list_append (items, (gpointer) bc);
|
||||
g_completion_add_items (cmp, items);
|
||||
g_list_free (items);
|
||||
|
||||
@ -75,7 +80,7 @@ test_completion (void)
|
||||
items = g_completion_complete_utf8 (cmp, "a", NULL);
|
||||
g_assert_cmpint (g_list_length (items), ==, 2);
|
||||
|
||||
items = g_list_append (NULL, "bb");
|
||||
items = g_list_append (NULL, (gpointer) bb);
|
||||
g_completion_remove_items (cmp, items);
|
||||
g_list_free (items);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[wrap-git]
|
||||
directory=proxy-libintl
|
||||
url=https://github.com/frida/proxy-libintl.git
|
||||
revision=0.2
|
||||
revision=c03e1a74b17fa7ec467e110130775409e4828a4c
|
||||
depth=1
|
||||
|
Loading…
x
Reference in New Issue
Block a user