| 716 | } |
| 717 | |
| 718 | int cbm_exec_no_shell(const char *const *argv) { |
| 719 | if (!argv || !argv[0]) { |
| 720 | return CBM_NOT_FOUND; |
| 721 | } |
| 722 | |
| 723 | wchar_t *cmdline = cbm_build_cmdline(argv); |
| 724 | if (!cmdline) { |
| 725 | return CBM_NOT_FOUND; |
| 726 | } |
| 727 | |
| 728 | STARTUPINFOW si; |
| 729 | PROCESS_INFORMATION pi; |
| 730 | memset(&si, 0, sizeof(si)); |
| 731 | memset(&pi, 0, sizeof(pi)); |
| 732 | si.cb = sizeof(si); |
| 733 | |
| 734 | /* CREATE_NO_WINDOW: the third and last spawn site that still needed it |
| 735 | * (#1427). Without it every helper routed through here — git, codesign, |
| 736 | * open — flashes a console window, and under a stdio MCP session with |
| 737 | * auto_watch those steal focus while the user is typing. The other three |
| 738 | * CreateProcessW sites already set it: subprocess.c and cbm_popen_isolated |
| 739 | * via #1448, and the detached daemon spawn in daemon/bootstrap.c, which has |
| 740 | * had it since it was written. */ |
| 741 | if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { |
| 742 | free(cmdline); |
| 743 | return CBM_NOT_FOUND; |
| 744 | } |
| 745 | free(cmdline); |
| 746 | |
| 747 | WaitForSingleObject(pi.hProcess, INFINITE); |
| 748 | DWORD exit_code = (DWORD)CBM_NOT_FOUND; |
| 749 | GetExitCodeProcess(pi.hProcess, &exit_code); |
| 750 | CloseHandle(pi.hProcess); |
| 751 | CloseHandle(pi.hThread); |
| 752 | return (int)exit_code; |
| 753 | } |
| 754 | |
| 755 | #else /* POSIX */ |
| 756 |
no test coverage detected