mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-11 03:46:17 +01:00
gspawn-win32: Provide thread-safe wrappers for _wspawn*e functions
_wspawn*e functions are not thread safe on the MSVCRT.dll and the pre-2015 MSVC runtime DLLs (msvcrXXX.dll).
This commit is contained in:
parent
0cb43a4965
commit
477ff949e1
@ -64,6 +64,10 @@
|
|||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <vcruntime.h> /* for _UCRT */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef GSPAWN_HELPER
|
#ifndef GSPAWN_HELPER
|
||||||
#ifdef G_SPAWN_WIN32_DEBUG
|
#ifdef G_SPAWN_WIN32_DEBUG
|
||||||
static int debug = 1;
|
static int debug = 1;
|
||||||
@ -117,6 +121,53 @@ enum {
|
|||||||
#define HELPER_PROCESS "gspawn-win32-helper"
|
#define HELPER_PROCESS "gspawn-win32-helper"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _UCRT
|
||||||
|
|
||||||
|
/* The wspawn*e functions are thread-safe only in the Universal
|
||||||
|
* CRT (UCRT). If we are linking against the MSVCRT.dll or the
|
||||||
|
* pre-2015 MSVC runtime (MSVCRXXX.dll), then we have to use a
|
||||||
|
* mutex.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static GMutex safe_wspawn_e_mutex;
|
||||||
|
|
||||||
|
static intptr_t
|
||||||
|
safe_wspawnve (int _Mode,
|
||||||
|
const wchar_t *_Filename,
|
||||||
|
const wchar_t *const *_ArgList,
|
||||||
|
const wchar_t *const *_Env)
|
||||||
|
{
|
||||||
|
intptr_t ret_val = -1;
|
||||||
|
|
||||||
|
g_mutex_lock (&safe_wspawn_e_mutex);
|
||||||
|
ret_val = _wspawnve (_Mode, _Filename, _ArgList, _Env);
|
||||||
|
g_mutex_unlock (&safe_wspawn_e_mutex);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static intptr_t
|
||||||
|
safe_wspawnvpe (int _Mode,
|
||||||
|
const wchar_t *_Filename,
|
||||||
|
const wchar_t *const *_ArgList,
|
||||||
|
const wchar_t *const *_Env)
|
||||||
|
{
|
||||||
|
intptr_t ret_val = -1;
|
||||||
|
|
||||||
|
g_mutex_lock (&safe_wspawn_e_mutex);
|
||||||
|
ret_val = _wspawnvpe (_Mode, _Filename, _ArgList, _Env);
|
||||||
|
g_mutex_unlock (&safe_wspawn_e_mutex);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define safe_wspawnve _spawnve
|
||||||
|
#define safe_wspawnvpe _wspawnvpe
|
||||||
|
|
||||||
|
#endif /* _UCRT */
|
||||||
|
|
||||||
/* This logic has a copy for wchar_t in gspawn-win32-helper.c, protect_wargv() */
|
/* This logic has a copy for wchar_t in gspawn-win32-helper.c, protect_wargv() */
|
||||||
static gchar *
|
static gchar *
|
||||||
protect_argv_string (const gchar *string)
|
protect_argv_string (const gchar *string)
|
||||||
@ -489,12 +540,12 @@ do_spawn_directly (gint *exit_status,
|
|||||||
|
|
||||||
if (flags & G_SPAWN_SEARCH_PATH)
|
if (flags & G_SPAWN_SEARCH_PATH)
|
||||||
if (wenvp != NULL)
|
if (wenvp != NULL)
|
||||||
rc = _wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
rc = safe_wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
||||||
else
|
else
|
||||||
rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv);
|
rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv);
|
||||||
else
|
else
|
||||||
if (wenvp != NULL)
|
if (wenvp != NULL)
|
||||||
rc = _wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
rc = safe_wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
||||||
else
|
else
|
||||||
rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv);
|
rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv);
|
||||||
|
|
||||||
@ -833,7 +884,7 @@ fork_exec (gint *exit_status,
|
|||||||
g_free (helper_process);
|
g_free (helper_process);
|
||||||
|
|
||||||
if (wenvp != NULL)
|
if (wenvp != NULL)
|
||||||
rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
rc = safe_wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
||||||
else
|
else
|
||||||
rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
|
rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user