@@ -565,6 +565,97 @@ static char *create_command_line(const char *const *args) {
565
565
return cmd;
566
566
}
567
567
568
+ static PIOHANDLE Run_OS_Command_Piped(PARROT_INTERP, PMC *command, PMC *env_hash, INTVAL flags,
569
+ INTVAL *pid, INTVAL *status) {
570
+ HANDLE current = GetCurrentProcess();
571
+ HANDLE hnull = INVALID_HANDLE_VALUE;
572
+ HANDLE hread = INVALID_HANDLE_VALUE;
573
+ HANDLE hwrite = INVALID_HANDLE_VALUE;
574
+ HANDLE hchild = INVALID_HANDLE_VALUE;
575
+ STARTUPINFO si;
576
+ PROCESS_INFORMATION pi;
577
+ SECURITY_ATTRIBUTES sec;
578
+ const char *env = pack_env_hash(interp, env_hash);
579
+ const char *const *argv = pack_arg_array(interp, command);
580
+ const char *cmd = create_command_line(argv);
581
+ PIOHANDLE os_handle;
582
+
583
+ pi.hThread = INVALID_HANDLE_VALUE;
584
+ pi.hProcess = INVALID_HANDLE_VALUE;
585
+ sec.nLength = sizeof sec;
586
+ sec.lpSecurityDescriptor = NULL;
587
+ sec.bInheritHandle = TRUE;
588
+
589
+ si.cb = sizeof si;
590
+ GetStartupInfo(&si);
591
+ si.dwFlags = STARTF_USESTDHANDLES;
592
+ if (CreatePipe(&hread, &hwrite, NULL, 0) == 0)
593
+ goto fail;
594
+ if (DuplicateHandle(current, flags & PARROT_EXEC_STDOUT ? hwrite : hread,
595
+ current, &hchild,
596
+ 0, TRUE,
597
+ DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
598
+ == 0)
599
+ goto fail;
600
+ if (hchild == INVALID_HANDLE_VALUE)
601
+ goto fail;
602
+
603
+ if (flags & PARROT_EXEC_STDOUT) {
604
+ /* Redirect input to NULL. This is to avoid
605
+ * interferences in case both the child and
606
+ * the parent tries to read from stdin.
607
+ * May be unnecessary or even interfere
608
+ * with valid usages, need more feedback. */
609
+ hnull = CreateFile("NUL", GENERIC_READ|GENERIC_WRITE,
610
+ 0, &sec, OPEN_EXISTING,
611
+ FILE_ATTRIBUTE_NORMAL, NULL);
612
+ if (hnull == INVALID_HANDLE_VALUE)
613
+ goto fail;
614
+ si.hStdInput = hnull;
615
+ si.hStdOutput = hchild;
616
+ si.hStdError = hchild;
617
+ }
618
+ else {
619
+ si.hStdInput = hchild;
620
+ }
621
+
622
+ if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, env, NULL, &si, &pi) == 0)
623
+ goto fail;
624
+
625
+ if (flags & PARROT_EXEC_STDOUT) {
626
+ os_handle = hread;
627
+ CloseHandle(hwrite);
628
+ }
629
+ else {
630
+ os_handle = hwrite;
631
+ CloseHandle(hread);
632
+ }
633
+
634
+ Parrot_str_free_cstring(cmd);
635
+ CloseHandle(pi.hThread);
636
+
637
+ *pid = (INTVAL)pi.hProcess;
638
+
639
+ return os_handle;
640
+
641
+ fail:
642
+ if (cmd != NULL)
643
+ Parrot_str_free_cstring(cmd);
644
+ if (hnull != INVALID_HANDLE_VALUE)
645
+ CloseHandle(hnull);
646
+ if (hread != INVALID_HANDLE_VALUE)
647
+ CloseHandle(hread);
648
+ if (hwrite != INVALID_HANDLE_VALUE)
649
+ CloseHandle(hwrite);
650
+ if (hchild != INVALID_HANDLE_VALUE)
651
+ CloseHandle(hchild);
652
+ if (pi.hThread != INVALID_HANDLE_VALUE)
653
+ CloseHandle(pi.hThread);
654
+ if (pi.hProcess != INVALID_HANDLE_VALUE)
655
+ CloseHandle(pi.hProcess);
656
+ Parrot_ex_throw_from_c_noargs(interp, EXCEPTION_UNIMPLEMENTED,
657
+ "pipe open error");
658
+ }
568
659
static INTVAL Run_OS_Command(PARROT_INTERP, PMC *command, PMC *env_hash)
569
660
{
570
661
DWORD status = 0;
0 commit comments