28static void run_child_tests(
const char *handle1_str,
const char *handle2_str);
32main(
int argc,
char *argv[])
39 fprintf(stderr,
"This test only runs on Windows\n");
55 snprintf(testfile1,
sizeof(testfile1),
"test_cloexec_1_%d.tmp", (
int) getpid());
56 snprintf(testfile2,
sizeof(testfile2),
"test_cloexec_2_%d.tmp", (
int) getpid());
68 fprintf(stderr,
"Usage: %s [handle1_hex handle2_hex]\n", argv[0]);
83 PROCESS_INFORMATION pi;
86 printf(
"Parent: Opening test files...\n");
91 fd1 = open(testfile1, O_RDWR | O_CREAT | O_TRUNC |
O_CLOEXEC, 0600);
101 fd2 = open(testfile2, O_RDWR | O_CREAT | O_TRUNC, 0600);
104 fprintf(stderr,
"Failed to open %s: %s\n", testfile2,
strerror(errno));
110 h1 = (HANDLE) _get_osfhandle(fd1);
111 h2 = (HANDLE) _get_osfhandle(fd2);
113 if (h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE)
115 fprintf(stderr,
"Failed to get OS handles\n");
121 printf(
"Parent: fd1=%d (O_CLOEXEC) -> HANDLE=%p\n", fd1, h1);
122 printf(
"Parent: fd2=%d (no O_CLOEXEC) -> HANDLE=%p\n", fd2, h2);
128 snprintf(cmdline,
sizeof(cmdline),
"\"%s\" %p %p",
129 GetCommandLine(), h1, h2);
136 char exe_path[MAX_PATH];
139 GetModuleFileName(NULL, exe_path,
sizeof(exe_path));
140 snprintf(cmdline,
sizeof(cmdline),
"\"%s\" %p %p",
144 memset(&si, 0,
sizeof(si));
146 memset(&pi, 0,
sizeof(pi));
148 printf(
"Parent: Spawning child process...\n");
149 printf(
"Parent: Command line: %s\n", cmdline);
151 if (!CreateProcess(NULL,
162 fprintf(stderr,
"CreateProcess failed: %lu\n", GetLastError());
168 printf(
"Parent: Waiting for child process...\n");
171 WaitForSingleObject(pi.hProcess, INFINITE);
172 GetExitCodeProcess(pi.hProcess, &exit_code);
174 CloseHandle(pi.hProcess);
175 CloseHandle(pi.hThread);
180 printf(
"Parent: Child exit code: %lu\n", exit_code);
183 printf(
"Parent: SUCCESS - O_CLOEXEC behavior verified\n");
186 printf(
"Parent: FAILURE - O_CLOEXEC not working correctly\n");
202 if (sscanf(handle1_str,
"%p", &h1) != 1 ||
203 sscanf(handle2_str,
"%p", &h2) != 1)
205 fprintf(stderr,
"Child: Failed to parse handle values\n");
209 printf(
"Child: Received HANDLE1=%p (should fail - O_CLOEXEC)\n", h1);
210 printf(
"Child: Received HANDLE2=%p (should work - no O_CLOEXEC)\n", h2);
216 printf(
"Child: HANDLE1 (O_CLOEXEC): %s\n",
217 h1_worked ?
"ACCESSIBLE (BAD!)" :
"NOT ACCESSIBLE (GOOD!)");
218 printf(
"Child: HANDLE2 (no O_CLOEXEC): %s\n",
219 h2_worked ?
"ACCESSIBLE (GOOD!)" :
"NOT ACCESSIBLE (BAD!)");
225 if (!h1_worked && h2_worked)
227 printf(
"Child: Test PASSED - O_CLOEXEC working correctly\n");
232 printf(
"Child: Test FAILED - O_CLOEXEC not working correctly\n");
242 const char *test_data =
"test\n";
246 result = WriteFile(h, test_data, strlen(test_data), &bytes_written, NULL);
248 if (result && bytes_written == strlen(test_data))
250 printf(
"Child: Successfully wrote to %s\n",
label);
255 printf(
"Child: Failed to write to %s (error %lu)\n",
256 label, GetLastError());
#define fprintf(file, fmt, msg)
static void run_child_tests(const char *handle1_str, const char *handle2_str)
int main(int argc, char *argv[])
static bool try_write_to_handle(HANDLE h, const char *label)
static void run_parent_tests(const char *testfile1, const char *testfile2)