diff --git a/libs/libc/string/Kconfig b/libs/libc/string/Kconfig index 302053d00e..f279932ae5 100644 --- a/libs/libc/string/Kconfig +++ b/libs/libc/string/Kconfig @@ -9,7 +9,7 @@ config LIBC_STRERROR bool "Enable strerror" default n ---help--- - strerror() is useful because it decodes 'errno' values into a human readable + strerror() is useful because it decodes 'errno' values into human readable strings. But it can also require a lot of memory. If this option is not selected, strerror() will still exist in the build but it will not decode error values. This option should be used by other logic to decide if it should use @@ -22,11 +22,11 @@ config LIBC_STRERROR_SHORT default n depends on LIBC_STRERROR ---help--- - If this option is selected, then strerror() will use a shortened string when + If this option is selected, then strerror() will use shortened string when it decodes the error. Specifically, strerror() is simply use the string that is the common name for the error. For example, the 'errno' value of 2 will - produce the string "No such file or directory" is LIBC_STRERROR_SHORT - is not defined but the string "ENOENT" is LIBC_STRERROR_SHORT is defined. + produce the string "No such file or directory" if LIBC_STRERROR_SHORT + is not defined but the string "ENOENT" if LIBC_STRERROR_SHORT is defined. config LIBC_PERROR_STDOUT bool "perror() to stdout" @@ -90,3 +90,30 @@ config MEMSET_64BIT efficiently. endmenu # memcpy/memset Options + +menu "signal Decode Support" + +config LIBC_STRSIGNAL + bool "Enable strsignal" + default y + ---help--- + strsignal() is useful because it decodes signal number values into + human readable strings. But it can also require additional memory. + If this option is not selected, strsignal() will still exist in the + build but it will not decode signal number values to specific string + equivalents, but a generic string 'Signal X' will be returned for the + valid signal number value and 'Real-time Signal X' will be returned + for the valid real-time signal number value. + +config LIBC_STRSIGNAL_SHORT + bool "Use short message string descriptions in strsignal()" + default DEFAULT_SMALL + depends on LIBC_STRSIGNAL + ---help--- + If this option is selected, then strsignal() will use a symbolic value + string equivalent to the signal number when signal value is decoded. + For example, the signal value for SIGTRAP will produce the string + "Trace/breakpoint trap" if LIBC_STRSIGNAL_SHORT is not defined but the + string "SIGTRAP" if LIBC_STRSIGNAL_SHORT is defined. + +endmenu # signal Decode Support diff --git a/libs/libc/string/lib_strsignal.c b/libs/libc/string/lib_strsignal.c index 8588f98f20..e4e7f4f07d 100644 --- a/libs/libc/string/lib_strsignal.c +++ b/libs/libc/string/lib_strsignal.c @@ -22,53 +22,24 @@ * Included Files ****************************************************************************/ +#include #include +#include #include /**************************************************************************** - * Private Data + * Pre-processor Definitions ****************************************************************************/ -/* We don't know what signals names will be assigned to which signals in - * advance and we do not want to return a volatile value. One solution is - * this silly array of useless names: - */ - -static FAR const char *g_default_sigstr[32] = -{ - "Signal 0", - "Signal 1", - "Signal 2", - "Signal 3", - "Signal 4", - "Signal 5", - "Signal 6", - "Signal 7", - "Signal 8", - "Signal 9", - "Signal 10", - "Signal 11", - "Signal 12", - "Signal 13", - "Signal 14", - "Signal 15", - "Signal 16", - "Signal 17", - "Signal 18", - "Signal 19", - "Signal 20", - "Signal 21", - "Signal 22", - "Signal 23", - "Signal 24", - "Signal 25", - "Signal 26", - "Signal 27", - "Signal 28", - "Signal 29", - "Signal 30", - "Signal 31", -}; +#ifdef CONFIG_LIBC_STRSIGNAL_SHORT +# define CASE_SIG_STR(sig, msg) \ + case (sig): \ + return (FAR char *)#sig +#else +# define CASE_SIG_STR(sig, msg) \ + case (sig): \ + return (FAR char *)(msg) +#endif /**************************************************************************** * Public Functions @@ -85,6 +56,8 @@ static FAR const char *g_default_sigstr[32] = FAR char *strsignal(int signum) { + static char sigstr[32]; + /* Handle invalid signals */ if (!GOOD_SIGNO(signum)) @@ -96,73 +69,54 @@ FAR char *strsignal(int signum) switch (signum) { +#ifdef CONFIG_LIBC_STRSIGNAL /* Standard signals */ -#ifdef SIGUSR1 - case SIGUSR1: - return (FAR char *)"SIGUSR1"; -#endif + CASE_SIG_STR(SIGHUP, "Hangup"); + CASE_SIG_STR(SIGINT, "Interrupt"); + CASE_SIG_STR(SIGQUIT, "Quit"); + CASE_SIG_STR(SIGILL, "Illegal instruction"); + CASE_SIG_STR(SIGTRAP, "Trace/breakpoint trap"); + CASE_SIG_STR(SIGABRT, "Aborted"); + CASE_SIG_STR(SIGBUS, "Bus error"); + CASE_SIG_STR(SIGFPE, "Arithmetic exception"); + CASE_SIG_STR(SIGKILL, "Killed"); + CASE_SIG_STR(SIGUSR1, "User defined signal 1"); + CASE_SIG_STR(SIGSEGV, "Invalid memory reference"); + CASE_SIG_STR(SIGUSR2, "User defined signal 2"); + CASE_SIG_STR(SIGPIPE, "Broken pipe"); + CASE_SIG_STR(SIGALRM, "Alarm clock"); + CASE_SIG_STR(SIGTERM, "Terminated"); + CASE_SIG_STR(SIGCHLD, "Child status changed"); + CASE_SIG_STR(SIGCONT, "Continued"); + CASE_SIG_STR(SIGSTOP, "Stopped (signal)"); + CASE_SIG_STR(SIGTSTP, "Stopped"); + CASE_SIG_STR(SIGTTIN, "Stopped (tty input)"); + CASE_SIG_STR(SIGTTOU, "Stopped (tty output)"); + CASE_SIG_STR(SIGURG, "Urgent I/O condition"); + CASE_SIG_STR(SIGXCPU, "CPU time limit exceeded"); + CASE_SIG_STR(SIGXFSZ, "File size limit exceeded"); + CASE_SIG_STR(SIGVTALRM, "Virtual timer expired"); + CASE_SIG_STR(SIGPROF, "Profiling timer expired"); + CASE_SIG_STR(SIGPOLL, "Pollable event occurred"); + CASE_SIG_STR(SIGSYS, "Bad system call"); -#ifdef SIGUSR2 - case SIGUSR2: - return (FAR char *)"SIGUSR2"; -#endif +#endif /* CONFIG_LIBC_STRSIGNAL */ -#ifdef SIGALRM - case SIGALRM: - return (FAR char *)"SIGALRM"; -#endif - -#ifdef SIGCHLD - case SIGCHLD: - return (FAR char *)"SIGCHLD"; -#endif - -#ifdef SIGPOLL - case SIGPOLL: - return (FAR char *)"SIGPOLL"; -#endif - -#ifdef SIGSTOP - case SIGSTOP: - return (FAR char *)"SIGSTOP"; -#endif - -#ifdef SIGTSTP - case SIGTSTP: - return (FAR char *)"SIGTSTP"; -#endif - -#ifdef SIGCONT - case SIGCONT: - return (FAR char *)"SIGCONT"; -#endif - -#ifdef SIGKILL - case SIGKILL: - return (FAR char *)"SIGKILL"; -#endif - -#ifdef SIGINT - case SIGINT: - return (FAR char *)"SIGINT"; -#endif - -#ifdef SIGQUIT - case SIGQUIT: - return (FAR char *)"SIGQUIT"; -#endif - -#ifdef SIGTERM - case SIGTERM: - return (FAR char *)"SIGTERM"; -#endif - - default: - break; + default: + if (signum >= SIGRTMIN && signum <= SIGRTMAX) + { + snprintf(sigstr, sizeof(sigstr), "Real-time Signal %d", + signum - SIGRTMIN); + } + else + { + snprintf(sigstr, sizeof(sigstr), "Signal %d", signum); + } + break; } /* Return a string devoid is meaning */ - return (FAR char *)g_default_sigstr[signum]; + return sigstr; }