From 6e17c429ffdd85413004e26cb9504cfd14d26941 Mon Sep 17 00:00:00 2001 From: Albert Slepak Date: Wed, 12 Aug 2026 23:26:06 -0700 Subject: [PATCH] feat(userland): cleaned up the shell's Ctrl+C and signal-death reporting A ^C at the prompt was silently swallowed, and every signal death got a "Terminated by signal" label even for routine SIGINT and SIGPIPE exits the terminal already narrates. The prompt now discards the line readline-style, and reap_status matches bash's quiet list. Co-authored-by: Cursor --- userland/apps/shell/src/line_edit.c | 12 ++++++++++++ userland/apps/shell/src/shell.c | 10 ++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/userland/apps/shell/src/line_edit.c b/userland/apps/shell/src/line_edit.c index 8ed711a4..b74fa74b 100644 --- a/userland/apps/shell/src/line_edit.c +++ b/userland/apps/shell/src/line_edit.c @@ -513,6 +513,18 @@ char* line_edit_read(line_edit_state* s, const char* prompt) { continue; } + if (c == 0x03) { // Ctrl-C: discard the line, start fresh + s->cursor_pos = s->line_len; + redraw(s, prompt); /* park the cursor at end of line */ + write(1, "^C\r\n", 4); + s->line_buf[0] = '\0'; + s->line_len = 0; + s->cursor_pos = 0; + s->history_index = s->history_count < HISTORY_MAX ? s->history_count : HISTORY_MAX; + write_str(prompt); + continue; + } + if (c == '\r' || c == '\n') { write(1, "\r\n", 2); s->line_buf[s->line_len] = '\0'; diff --git a/userland/apps/shell/src/shell.c b/userland/apps/shell/src/shell.c index 73cff7f7..ba29e0e2 100644 --- a/userland/apps/shell/src/shell.c +++ b/userland/apps/shell/src/shell.c @@ -51,15 +51,21 @@ static int reap_status(int status) { int sig = STLX_WTERMSIG(status); const char* name; switch (sig) { + case 2: /* SIGINT: the terminal's ^C echo already told the story */ + case 13: /* SIGPIPE: routine death for pipeline members */ + name = NULL; break; case 4: name = "Illegal instruction"; break; case 7: name = "Bus error"; break; case 8: name = "Floating point exception"; break; case 9: name = "Killed"; break; case 11: name = "Segmentation fault"; break; + case 15: name = "Terminated"; break; default: name = "Terminated by signal"; break; } - shell_err(name); - shell_err("\r\n"); + if (name) { + shell_err(name); + shell_err("\r\n"); + } return 128 + sig; } return status;