| 2045 | } |
| 2046 | |
| 2047 | static void main_daemon_ctl_open_browser(int port) { |
| 2048 | char url[64]; |
| 2049 | (void)snprintf(url, sizeof(url), "http://127.0.0.1:%d", port); |
| 2050 | #ifdef CBM_ENABLE_TEST_SEAMS |
| 2051 | char marker_path[MAIN_PATH_CAP]; |
| 2052 | if (cbm_safe_getenv("CBM_TEST_DAEMON_OPEN_MARKER", marker_path, sizeof(marker_path), NULL)) { |
| 2053 | FILE *marker = cbm_fopen(marker_path, "wb"); |
| 2054 | bool opened = marker && fwrite(url, 1, strlen(url), marker) == strlen(url); |
| 2055 | if (marker && fclose(marker) != 0) { |
| 2056 | opened = false; |
| 2057 | } |
| 2058 | if (!opened) { |
| 2059 | (void)fprintf(stderr, "hint: could not record the test browser request\n"); |
| 2060 | } |
| 2061 | return; |
| 2062 | } |
| 2063 | #endif |
| 2064 | #if defined(_WIN32) |
| 2065 | /* ShellExecuteW resolves the http protocol association directly — no |
| 2066 | * command shell interprets the argument. Values > 32 signal success. */ |
| 2067 | wchar_t *wide_url = cbm_utf8_to_wide(url); |
| 2068 | bool opened = |
| 2069 | wide_url && (INT_PTR)ShellExecuteW(NULL, L"open", wide_url, NULL, NULL, SW_SHOWNORMAL) > 32; |
| 2070 | free(wide_url); |
| 2071 | #elif defined(__APPLE__) |
| 2072 | const char *open_argv[] = {"open", url, NULL}; |
| 2073 | bool opened = cbm_exec_no_shell(open_argv) == 0; |
| 2074 | #else |
| 2075 | const char *open_argv[] = {"xdg-open", url, NULL}; |
| 2076 | bool opened = cbm_exec_no_shell(open_argv) == 0; |
| 2077 | #endif |
| 2078 | if (!opened) { |
| 2079 | (void)fprintf(stderr, "hint: could not open a browser automatically; visit %s\n", url); |
| 2080 | } |
| 2081 | } |
| 2082 | |
| 2083 | static int main_daemon_ctl_finish_ui_open(cbm_daemon_runtime_client_t **client_io, int port, |
| 2084 | bool open_browser) { |
no test coverage detected