| 368 | } |
| 369 | |
| 370 | FILE *cbm_popen(const char *cmd, const char *mode) { |
| 371 | /* Our git shell-outs are all read-mode; they MUST use the isolated |
| 372 | * spawn. On failure, log and fail the call — never fall back to |
| 373 | * _popen, whose full handle inheritance re-arms the UI hang (#798). */ |
| 374 | if (mode && mode[0] == 'r' && mode[1] == '\0') { |
| 375 | const char *stage = ""; |
| 376 | DWORD gle = 0; |
| 377 | FILE *fp = cbm_popen_isolated(cmd, &stage, &gle); |
| 378 | g_popen_last_isolated = (fp != NULL); |
| 379 | if (!fp) { |
| 380 | char glebuf[CBM_SZ_16]; |
| 381 | char errnobuf[CBM_SZ_16]; |
| 382 | snprintf(glebuf, sizeof(glebuf), "%lu", (unsigned long)gle); |
| 383 | snprintf(errnobuf, sizeof(errnobuf), "%d", errno); |
| 384 | cbm_log_warn("compat.popen_isolated_failed", "stage", stage, "gle", glebuf, "errno", |
| 385 | errnobuf); |
| 386 | } |
| 387 | return fp; |
| 388 | } |
| 389 | g_popen_last_isolated = 0; |
| 390 | return _popen(cmd, mode); |
| 391 | } |
| 392 | |
| 393 | int cbm_pclose(FILE *f) { |
| 394 | InitOnceExecuteOnce(&g_popen_once, cbm_popen_init, NULL, NULL); |
no test coverage detected