@@ -34,19 +34,17 @@ void process_create_windows(const char* cmd, const char* stdin_stream,
3434
3535 STARTUPINFO si ;
3636 PROCESS_INFORMATION pi ;
37- HANDLE hStdout = NULL , hStderr = NULL ;
37+ HANDLE hStdout = NULL , hStderr = NULL , hStdin = NULL ;
3838 SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES ), NULL , TRUE };
3939 FILE * stdin_fp = NULL ;
40+ char * full_cmd = NULL ;
4041
4142 // Initialize null handle
4243 (* pid ) = 0 ;
4344
4445 ZeroMemory (& si , sizeof (si ));
4546 si .cb = sizeof (STARTUPINFO );
4647
47- // If possible, we redirect stdout/stderr to file handles directly.
48- // This will override any cmd redirection settings (<>). For stdin
49-
5048 // Write stdin_stream to stdin_file if provided
5149 if (stdin_stream && stdin_file ) {
5250 stdin_fp = fopen (stdin_file , "w" );
@@ -58,57 +56,68 @@ void process_create_windows(const char* cmd, const char* stdin_stream,
5856 fclose (stdin_fp );
5957 }
6058
59+ // Open stdin file if provided, otherwise use the null device
60+ if (stdin_file ) {
61+ hStdin = CreateFile (stdin_file , GENERIC_READ , 0 , & sa , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
62+ } else {
63+ hStdin = CreateFile ("NUL" , GENERIC_READ , 0 , & sa , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
64+ }
65+
66+ if (hStdin == INVALID_HANDLE_VALUE ) {
67+ fprintf (stderr , "Failed to open input source (file or null)\n" );
68+ // No handles to close yet
69+ return ;
70+ }
71+
72+ si .hStdInput = hStdin ;
73+ si .dwFlags |= STARTF_USESTDHANDLES ;
74+
6175 // Open stdout file if provided, otherwise use the null device
6276 if (stdout_file ) {
6377 hStdout = CreateFile (stdout_file , GENERIC_WRITE , 0 , & sa , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
64- if (hStdout == INVALID_HANDLE_VALUE ) {
65- fprintf (stderr , "Failed to open stdout file\n" );
66- return ;
67- }
6878 } else {
69- hStdout = CreateFile ("NUL" , GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
70- if (hStdout == INVALID_HANDLE_VALUE ) {
71- fprintf (stderr , "Failed to open null device for stdout\n" );
72- return ;
73- }
79+ hStdout = CreateFile ("NUL" , GENERIC_WRITE , 0 , & sa , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
80+ }
81+
82+ if (hStdout == INVALID_HANDLE_VALUE ) {
83+ fprintf (stderr , "Failed to open stdout sink\n" );
84+ CloseHandle (hStdin );
85+ return ;
7486 }
87+
7588 si .hStdOutput = hStdout ;
76- si .dwFlags |= STARTF_USESTDHANDLES ;
7789
7890 // Open stderr file if provided, otherwise use the null device
7991 if (stderr_file ) {
8092 hStderr = CreateFile (stderr_file , GENERIC_WRITE , 0 , & sa , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
81- if (hStderr == INVALID_HANDLE_VALUE ) {
82- fprintf (stderr , "Failed to open stderr file\n" );
83- return ;
84- }
8593 } else {
86- hStderr = CreateFile ("NUL" , GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
87- if (hStderr == INVALID_HANDLE_VALUE ) {
88- fprintf (stderr , "Failed to open null device for stderr\n" );
89- return ;
90- }
94+ hStderr = CreateFile ("NUL" , GENERIC_WRITE , 0 , & sa , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
95+ }
96+
97+ if (hStderr == INVALID_HANDLE_VALUE ) {
98+ fprintf (stderr , "Failed to open stderr sink\n" );
99+ CloseHandle (hStdin );
100+ CloseHandle (hStdout );
101+ return ;
91102 }
103+
92104 si .hStdError = hStderr ;
93- si .dwFlags |= STARTF_USESTDHANDLES ;
94105
95- // Prepare the command line with redirected stdin
96- char * full_cmd ;
106+ // Prepare the command line
97107 size_t cmd_len = strlen (cmd );
98- size_t stdin_len = stdin_file ? strlen (stdin_file ) : 0 ;
99- size_t full_cmd_len = cmd_len + stdin_len + 5 ;
108+ size_t full_cmd_len = cmd_len + 1 ;
100109 full_cmd = (char * )malloc (full_cmd_len );
101110 if (!full_cmd ) {
102111 fprintf (stderr , "Failed to allocate memory for full_cmd\n" );
112+ CloseHandle (hStdin );
113+ CloseHandle (hStdout );
114+ CloseHandle (hStderr );
103115 return ;
104116 }
105117
106118 // Use full_cmd as needed (e.g., pass to CreateProcess)
107- if (stdin_file ) {
108- snprintf (full_cmd , full_cmd_len , "%s < %s" , cmd , stdin_file );
109- } else {
110- snprintf (full_cmd , full_cmd_len , "%s" , cmd );
111- }
119+ snprintf (full_cmd , full_cmd_len , "%s" , cmd );
120+
112121
113122 // Create the process
114123 BOOL success = CreateProcess (
@@ -129,12 +138,16 @@ void process_create_windows(const char* cmd, const char* stdin_stream,
129138
130139 if (!success ) {
131140 fprintf (stderr , "CreateProcess failed (%lu).\n" , GetLastError ());
141+ CloseHandle (hStdin );
142+ CloseHandle (hStdout );
143+ CloseHandle (hStderr );
132144 return ;
133145 }
134146
135- // Close unneeded handles
136- if (hStdout ) CloseHandle (hStdout );
137- if (hStderr ) CloseHandle (hStderr );
147+ // Close unneeded handles (the child has its own duplicates now)
148+ CloseHandle (hStdin );
149+ CloseHandle (hStdout );
150+ CloseHandle (hStderr );
138151
139152 // Return the process handle for status queries
140153 CloseHandle (pi .hThread ); // Close the thread handle
0 commit comments