This repository has been archived by the owner on May 4, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
windows: make spawn with custom environment work again
- Loading branch information
1 parent
5c674b2
commit abc945b
Showing
1 changed file
with
44 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,9 +37,9 @@ | |
typedef struct env_var { | ||
const char* narrow; | ||
const WCHAR* wide; | ||
int len; /* including null or '=' */ | ||
size_t len; /* including null or '=' */ | ||
DWORD value_len; | ||
int supplied; | ||
int value_len; | ||
} env_var_t; | ||
|
||
#define E_V(str) { str "=", L##str, sizeof(str), 0, 0 } | ||
|
@@ -549,10 +549,10 @@ uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) | |
* issues associated with that solution; this is the caller's | ||
* char**, and modifying it is rude. | ||
*/ | ||
static void check_required_vars_contains_var(env_var_t* required, int size, | ||
static void check_required_vars_contains_var(env_var_t* required, int count, | ||
const char* var) { | ||
int i; | ||
for (i = 0; i < size; ++i) { | ||
for (i = 0; i < count; ++i) { | ||
if (_strnicmp(required[i].narrow, var, required[i].len) == 0) { | ||
required[i].supplied = 1; | ||
return; | ||
|
@@ -572,11 +572,11 @@ static void check_required_vars_contains_var(env_var_t* required, int size, | |
* these get defined if the input environment block does not contain any | ||
* values for them. | ||
*/ | ||
WCHAR* make_program_env(char** env_block) { | ||
uv_err_t make_program_env(char* env_block[], WCHAR** dst_ptr) { | ||
WCHAR* dst; | ||
WCHAR* ptr; | ||
char** env; | ||
int env_len = 1 * sizeof(WCHAR); /* room for closing null */ | ||
size_t env_len = 1; /* room for closing null */ | ||
int len; | ||
int i; | ||
DWORD var_size; | ||
|
@@ -588,36 +588,53 @@ WCHAR* make_program_env(char** env_block) { | |
}; | ||
|
||
for (env = env_block; *env; env++) { | ||
int len; | ||
check_required_vars_contains_var(required_vars, | ||
ARRAY_SIZE(required_vars), | ||
*env); | ||
env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(WCHAR)); | ||
|
||
len = MultiByteToWideChar(CP_UTF8, | ||
0, | ||
*env, | ||
-1, | ||
NULL, | ||
0); | ||
if (len <= 0) { | ||
return uv__new_sys_error(GetLastError()); | ||
} | ||
|
||
env_len += len; | ||
} | ||
|
||
for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { | ||
if (!required_vars[i].supplied) { | ||
env_len += required_vars[i].len * sizeof(WCHAR); | ||
env_len += required_vars[i].len; | ||
var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); | ||
if (var_size == 0) { | ||
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); | ||
return uv__new_sys_error(GetLastError()); | ||
} | ||
required_vars[i].value_len = (int)var_size; | ||
env_len += (int)var_size * sizeof(WCHAR); | ||
required_vars[i].value_len = var_size; | ||
env_len += var_size; | ||
} | ||
} | ||
|
||
dst = malloc(env_len); | ||
dst = malloc(env_len * sizeof(WCHAR)); | ||
if (!dst) { | ||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); | ||
return uv__new_artificial_error(UV_ENOMEM); | ||
} | ||
|
||
ptr = dst; | ||
|
||
for (env = env_block; *env; env++, ptr += len) { | ||
len = uv_utf8_to_utf16(*env, ptr, (size_t)(env_len - (ptr - dst))); | ||
if (!len) { | ||
len = MultiByteToWideChar(CP_UTF8, | ||
0, | ||
*env, | ||
-1, | ||
ptr, | ||
(int) (env_len - (ptr - dst))); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
piscisaureus
Author
|
||
if (len <= 0) { | ||
free(dst); | ||
return NULL; | ||
return uv__new_sys_error(GetLastError()); | ||
} | ||
} | ||
|
||
|
@@ -636,8 +653,11 @@ WCHAR* make_program_env(char** env_block) { | |
} | ||
} | ||
|
||
/* Terminate with an extra NULL. */ | ||
*ptr = L'\0'; | ||
return dst; | ||
|
||
*dst_ptr = dst; | ||
return uv_ok_; | ||
} | ||
|
||
|
||
|
@@ -740,7 +760,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process, | |
WCHAR* path = NULL; | ||
BOOL result; | ||
WCHAR* application_path = NULL, *application = NULL, *arguments = NULL, | ||
*env = NULL, *cwd = NULL; | ||
*env = NULL, *cwd = NULL; | ||
STARTUPINFOW startup; | ||
PROCESS_INFORMATION info; | ||
DWORD process_flags; | ||
|
@@ -775,6 +795,12 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process, | |
if (err.code != UV_OK) | ||
goto done; | ||
|
||
if (options.env) { | ||
err = make_program_env(options.env, &env); | ||
if (err.code != UV_OK) | ||
goto done; | ||
} | ||
|
||
if (options.cwd) { | ||
/* Explicit cwd */ | ||
err = uv_utf8_to_utf16_alloc(options.cwd, &cwd); | ||
|
1 comment
on commit abc945b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
An int? The win32 API is so daft...