From 237184a8bf52b2a4656f2031210b12d2b5d24ba5 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 10 Jul 2023 21:39:22 +0200 Subject: [PATCH] libc+sh: Implement strsignal and use it in the shell --- apps/sh.cpp | 10 +++++++++- libc/include/string.h | 3 +++ libc/src/string.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/apps/sh.cpp b/apps/sh.cpp index 7f247eb9..6bca57cf 100644 --- a/apps/sh.cpp +++ b/apps/sh.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -117,7 +118,14 @@ Result luna_main(int argc, char** argv) if (child == 0) { TRY(execute_command(cmd.view())); } - TRY(os::Process::wait(child, nullptr)); + int status; + TRY(os::Process::wait(child, &status)); + + if (WIFSIGNALED(status)) + { + int sig = WTERMSIG(status); + if (sig != SIGINT && sig != SIGQUIT) os::println("[sh] Process %d exited: %s", child, strsignal(sig)); + } } return 0; diff --git a/libc/include/string.h b/libc/include/string.h index 3349a828..aff7a35b 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -62,6 +62,9 @@ extern "C" /* Return the human-readable description of an error number. */ char* strerror(int errnum); + /* Return the human-readable description of a signal number. */ + char* strsignal(int signo); + /* Return the length of the initial segment of str which consists only of bytes in accept. */ size_t strspn(const char* str, const char* accept); diff --git a/libc/src/string.cpp b/libc/src/string.cpp index eabdc00a..510c465e 100644 --- a/libc/src/string.cpp +++ b/libc/src/string.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -12,4 +13,32 @@ extern "C" { return const_cast(error_string(errnum)); } + + static const char* __internal_strsignal(int signo) + { + switch (signo) + { + case SIGHUP: return "Hangup"; + case SIGINT: return "Terminal interrupt"; + case SIGQUIT: return "Terminal quit"; + case SIGILL: return "Invalid opcode"; + case SIGTRAP: return "Breakpoint trap"; + case SIGABRT: return "Aborted"; + case SIGCHLD: return "Child stopped or exited"; + case SIGFPE: return "Floating point exception"; + case SIGKILL: return "Killed"; + case SIGSTOP: return "Stopped"; + case SIGSEGV: return "Segmentation fault"; + case SIGCONT: return "Continued"; + case SIGPIPE: return "Broken pipe"; + case SIGALRM: return "Alarm signal"; + case SIGTERM: return "Terminated"; + default: return "Unknown signal"; + } + } + + char* strsignal(int signo) + { + return const_cast(__internal_strsignal(signo)); + } }