@@ -336,7 +336,27 @@ extern char **environ;
336
336
#ifdef WIN32
337
337
#include <windows.h>
338
338
#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)
340
360
{
341
361
DWORD status = 0;
342
362
STARTUPINFO si;
@@ -345,6 +365,7 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
345
365
char* const cmd = (char *)mem_sys_allocate(command->strlen + 4);
346
366
char* const shell = Parrot_str_to_cstring(interp, Parrot_getenv(interp, comspec));
347
367
char* const cmdin = Parrot_str_to_cstring(interp, command);
368
+ char* const env = pack_env_hash(interp, env_hash);
348
369
349
370
strcpy(cmd, "/c ");
350
371
strcat(cmd, cmdin);
@@ -377,7 +398,36 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
377
398
#include <unistd.h>
378
399
#include <sys/types.h>
379
400
#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)
381
431
{
382
432
pid_t child;
383
433
child = fork();
@@ -396,9 +446,11 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
396
446
else {
397
447
/* child */
398
448
char * const cmd = Parrot_str_to_cstring(interp, command);
449
+ char **env = pack_env_hash(interp,env_hash);
399
450
const int status = execle("/bin/sh", "sh", "-c", cmd, (void *)NULL, env);
400
451
/* if we get here, something's horribly wrong, but free anyway... */
401
452
Parrot_str_free_cstring(cmd);
453
+ free_packed_env(env);
402
454
403
455
if (status)
404
456
PARROT_FORCE_EXIT(status);
@@ -415,34 +467,6 @@ static INTVAL Run_OS_Command(PARROT_INTERP, STRING *command, char **env)
415
467
printf("env_var: %s\n", Parrot_str_to_cstring(interp,env_var));
416
468
*/
417
469
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
- }
446
470
447
471
END_OPS_PREAMBLE
448
472
@@ -3492,15 +3516,13 @@ inline op nqp_getlexrelcaller(out PMC, in PMC, in STR) :base_core {
3492
3516
inline op nqp_shell(out INT, in STR, in STR, in PMC) {
3493
3517
STRING *command = $2;
3494
3518
STRING *dir = $3;
3519
+ PMC *env = $4;
3495
3520
3496
3521
STRING * const old_cwd = Parrot_file_getcwd(interp);
3497
- char **env = pack_env_hash(interp,$4);
3498
3522
3499
3523
Parrot_file_chdir(interp, dir);
3500
3524
$1 = Run_OS_Command(interp, command, env);
3501
3525
Parrot_file_chdir(interp, old_cwd);
3502
-
3503
- free_packed_env(env);
3504
3526
}
3505
3527
3506
3528
inline op nqp_getenvhash(out PMC) {
0 commit comments