Skip to content

Commit 257f172

Browse files
committed
Attempt at corretly passing the env variables on windows.
1 parent 6cbe2ef commit 257f172

File tree

1 file changed

+55
-33
lines changed

1 file changed

+55
-33
lines changed

src/vm/parrot/ops/nqp.ops

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,27 @@ extern char **environ;
336336
#ifdef WIN32
337337
#include <windows.h>
338338
#include <process.h>
339-
static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
339+
static char * pack_env_hash(Parrot_Interp interp, PMC* hash_pmc) {
340+
Hash *hash = VTABLE_get_pointer(interp, hash_pmc);
341+
STRING *equal = Parrot_str_new_constant(interp, "=");
342+
STRING *key, *value, *env_var, *env_var_with_null;
343+
INTVAL hash_size = Parrot_hash_size(interp, hash);
344+
STRING *packed = Parrot_str_new_constant(interp, "");
345+
STRING *null = Parrot_str_new_constant(interp, "\n");
346+
347+
348+
/* Parrot_hash_value_to_string is not exported*/
349+
parrot_hash_iterate(hash,
350+
key = (STRING *)_bucket->key;
351+
value = VTABLE_get_string_keyed_str(interp, hash_pmc, key);
352+
env_var = Parrot_str_concat(interp, key, Parrot_str_concat(interp, equal, value));
353+
env_var_with_null = Parrot_str_concat(interp, env_var, null);
354+
packed = Parrot_str_concat(interp, packed, env_var_with_null);
355+
);
356+
return Parrot_str_to_cstring(interp, packed);
357+
}
358+
359+
static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, PMC *env_hash)
340360
{
341361
DWORD status = 0;
342362
STARTUPINFO si;
@@ -345,6 +365,7 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
345365
char* const cmd = (char *)mem_sys_allocate(command->strlen + 4);
346366
char* const shell = Parrot_str_to_cstring(interp, Parrot_getenv(interp, comspec));
347367
char* const cmdin = Parrot_str_to_cstring(interp, command);
368+
char* const env = pack_env_hash(interp, env_hash);
348369

349370
strcpy(cmd, "/c ");
350371
strcat(cmd, cmdin);
@@ -377,7 +398,36 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
377398
#include <unistd.h>
378399
#include <sys/types.h>
379400
#include <sys/wait.h>
380-
static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
401+
402+
static char ** pack_env_hash(Parrot_Interp interp, PMC* hash_pmc) {
403+
Hash *hash = VTABLE_get_pointer(interp, hash_pmc);
404+
STRING *equal = Parrot_str_new_constant(interp, "=");
405+
STRING *key, *value, *env_var;
406+
INTVAL hash_size = Parrot_hash_size(interp, hash);
407+
char** packed = mem_sys_allocate_zeroed(sizeof(char*) * (hash_size+1));
408+
INTVAL i = 0;
409+
410+
411+
/* Parrot_hash_value_to_string is not exported*/
412+
parrot_hash_iterate(hash,
413+
key = (STRING *)_bucket->key;
414+
value = VTABLE_get_string_keyed_str(interp, hash_pmc,key);
415+
env_var = Parrot_str_concat(interp, key, Parrot_str_concat(interp,equal,value));
416+
packed[i++] = Parrot_str_to_cstring(interp, env_var);
417+
);
418+
packed[hash_size] = NULL;
419+
return packed;
420+
}
421+
422+
static void free_packed_env(char **env) {
423+
INTVAL i = 0;
424+
while (env[i]) {
425+
Parrot_str_free_cstring(env[i]);
426+
i++;
427+
}
428+
mem_sys_free(env);
429+
}
430+
static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, PMC *env_hash)
381431
{
382432
pid_t child;
383433
child = fork();
@@ -396,9 +446,11 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
396446
else {
397447
/* child */
398448
char * const cmd = Parrot_str_to_cstring(interp, command);
449+
char **env = pack_env_hash(interp,env_hash);
399450
const int status = execle("/bin/sh", "sh", "-c", cmd, (void *)NULL, env);
400451
/* if we get here, something's horribly wrong, but free anyway... */
401452
Parrot_str_free_cstring(cmd);
453+
free_packed_env(env);
402454

403455
if (status)
404456
PARROT_FORCE_EXIT(status);
@@ -415,34 +467,6 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
415467
printf("env_var: %s\n", Parrot_str_to_cstring(interp,env_var));
416468
*/
417469

418-
static char ** pack_env_hash(Parrot_Interp interp, PMC* hash_pmc) {
419-
Hash *hash = VTABLE_get_pointer(interp,hash_pmc);
420-
STRING *equal = Parrot_str_new_constant(interp,"=");
421-
STRING *key, *value, *env_var;
422-
INTVAL hash_size = Parrot_hash_size(interp,hash);
423-
char** packed = mem_sys_allocate_zeroed(sizeof(char*) * (hash_size+1));
424-
INTVAL i = 0;
425-
426-
427-
/* Parrot_hash_value_to_string is not exported*/
428-
parrot_hash_iterate(hash,
429-
key = (STRING *)_bucket->key;
430-
value = VTABLE_get_string_keyed_str(interp,hash_pmc,key);
431-
env_var = Parrot_str_concat(interp,key,Parrot_str_concat(interp,equal,value));
432-
packed[i++] = Parrot_str_to_cstring(interp,env_var);
433-
);
434-
packed[hash_size] = NULL;
435-
return packed;
436-
}
437-
438-
static void free_packed_env(char **env) {
439-
INTVAL i = 0;
440-
while (env[i]) {
441-
Parrot_str_free_cstring(env[i]);
442-
i++;
443-
}
444-
mem_sys_free(env);
445-
}
446470

447471
END_OPS_PREAMBLE
448472

@@ -3492,15 +3516,13 @@ inline op nqp_getlexrelcaller(out PMC, in PMC, in STR) :base_core {
34923516
inline op nqp_shell(out INT, in STR, in STR, in PMC) {
34933517
STRING *command = $2;
34943518
STRING *dir = $3;
3519+
PMC *env = $4;
34953520

34963521
STRING * const old_cwd = Parrot_file_getcwd(interp);
3497-
char **env = pack_env_hash(interp,$4);
34983522

34993523
Parrot_file_chdir(interp, dir);
35003524
$1 = Run_OS_Command(interp, command, env);
35013525
Parrot_file_chdir(interp, old_cwd);
3502-
3503-
free_packed_env(env);
35043526
}
35053527

35063528
inline op nqp_getenvhash(out PMC) {

0 commit comments

Comments
 (0)