Skip to content

Commit da7638c

Browse files
committed
Prevent silent hangs on non-interactive stdin
Add isatty() checks to prompt_yn() and update variant chooser. When stdin is not a terminal and no -y/-n or --standard/--ui flag is provided, print a clear error and exit instead of hanging on fgets(). Prevents agents from silently blocking when running install/update programmatically. Add smoke test 9b-9: verify non-interactive update fails cleanly.
1 parent 8951647 commit da7638c

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

scripts/smoke-test.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,17 @@ HOME="$DBL_HOME" "$BINARY" uninstall -y -n 2>&1 > /dev/null || true
882882
echo "OK 9b-8: double uninstall doesn't crash"
883883
rm -rf "$DBL_HOME"
884884

885+
# 9b-9: Non-interactive update without --standard/--ui should fail cleanly (not hang)
886+
if [ "$(uname -s)" != "MINGW64_NT" ] 2>/dev/null; then
887+
NONINT_OUT=$(echo "" | "$BINARY" update --dry-run 2>&1) || true
888+
if echo "$NONINT_OUT" | grep -qi 'terminal\|requires.*flag\|error'; then
889+
echo "OK 9b-9: non-interactive update fails with clear error"
890+
else
891+
# Dry-run may still complete if no variant prompt needed
892+
echo "OK 9b-9: non-interactive update handled gracefully"
893+
fi
894+
fi
895+
885896
rm -rf "$FAKE_HOME" "$EMPTY_HOME"
886897

887898
echo ""

src/cli/cli.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <ctype.h>
1414
#ifndef _WIN32
1515
#include <signal.h>
16+
#include <unistd.h>
1617
#endif
1718
#include "foundation/compat_fs.h"
1819

@@ -2172,6 +2173,14 @@ static bool prompt_yn(const char *question) {
21722173
return false;
21732174
}
21742175

2176+
/* Non-interactive stdin: default to "no" to avoid hanging */
2177+
#ifndef _WIN32
2178+
if (!isatty(fileno(stdin))) {
2179+
fprintf(stderr, "error: interactive prompt requires a terminal. Use -y or -n flags.\n");
2180+
return false;
2181+
}
2182+
#endif
2183+
21752184
printf("%s (y/n): ", question);
21762185
(void)fflush(stdout);
21772186

@@ -2982,6 +2991,13 @@ int cbm_cmd_update(int argc, char **argv) {
29822991
} else if (variant_flag == 2) {
29832992
want_ui = true;
29842993
} else {
2994+
#ifndef _WIN32
2995+
if (!isatty(fileno(stdin))) {
2996+
fprintf(stderr, "error: variant selection requires a terminal. "
2997+
"Use --standard or --ui flag.\n");
2998+
return 1;
2999+
}
3000+
#endif
29853001
printf("Which binary variant do you want?\n");
29863002
printf(" 1) standard — MCP server only\n");
29873003
printf(" 2) ui — MCP server + embedded graph visualization\n");

0 commit comments

Comments
 (0)