| /* |
| * Copyright (C) 2002 Manuel Novoa III |
| * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> |
| * |
| * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. |
| */ |
| |
| /* |
| * Sep 11, 2003 |
| * Patch by Atsushi Nemoto <anemo@mba.ocn.ne.jp> to do arch-required |
| * mapping of signal strings (alpha, mips, hppa, sparc). |
| */ |
| |
| /* TODO: make a threadsafe version? */ |
| |
| #include <features.h> |
| #include <string.h> |
| #include <bits/uClibc_uintmaxtostr.h> |
| #include <signal.h> |
| |
| #define _SYS_NSIG 32 |
| |
| #ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__ |
| # define _SYS_SIGMSG_MAXLEN 25 |
| #else |
| # define _SYS_SIGMSG_MAXLEN 0 |
| #endif |
| |
| #if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15 |
| # define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15) |
| #else |
| # define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN |
| #endif |
| |
| #ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__ |
| |
| extern const char _string_syssigmsgs[] attribute_hidden; |
| |
| #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
| static const unsigned char sstridx[] = { |
| 0, |
| SIGHUP, |
| SIGINT, |
| SIGQUIT, |
| SIGILL, |
| SIGTRAP, |
| SIGIOT, |
| SIGBUS, |
| SIGFPE, |
| SIGKILL, |
| SIGUSR1, |
| SIGSEGV, |
| SIGUSR2, |
| SIGPIPE, |
| SIGALRM, |
| SIGTERM, |
| #if defined SIGSTKFLT |
| SIGSTKFLT, |
| #else |
| 0, |
| #endif |
| SIGCHLD, |
| SIGCONT, |
| SIGSTOP, |
| SIGTSTP, |
| SIGTTIN, |
| SIGTTOU, |
| SIGURG, |
| SIGXCPU, |
| SIGXFSZ, |
| SIGVTALRM, |
| SIGPROF, |
| SIGWINCH, |
| SIGIO, |
| SIGPWR, |
| SIGSYS, |
| #if defined SIGEMT |
| SIGEMT, |
| #endif |
| }; |
| #endif |
| |
| char *strsignal(int signum) |
| { |
| register char *s; |
| int i; |
| static char buf[_STRSIGNAL_BUFSIZE]; |
| static const char unknown[] = { |
| 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' ' |
| }; |
| |
| #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
| /* Need to translate signum to string index. */ |
| for (i = 0; i < sizeof(sstridx)/sizeof(sstridx[0]); i++) { |
| if (sstridx[i] == signum) { |
| goto GOT_SSTRIDX; |
| } |
| } |
| i = INT_MAX; /* Failed. */ |
| GOT_SSTRIDX: |
| #else |
| /* No signum to string index translation needed. */ |
| i = signum; |
| #endif |
| |
| if (((unsigned int) signum) < _SYS_NSIG) { |
| /* Trade time for space. This function should rarely be called |
| * so rather than keeping an array of pointers for the different |
| * messages, just run through the buffer until we find the |
| * correct string. */ |
| for (s = (char *) _string_syssigmsgs; i; ++s) { |
| if (!*s) { |
| --i; |
| } |
| } |
| if (*s) { /* Make sure we have an actual message. */ |
| goto DONE; |
| } |
| } |
| |
| s = _int10tostr(buf + sizeof(buf)-1, signum) - sizeof(unknown); |
| memcpy(s, unknown, sizeof(unknown)); |
| |
| DONE: |
| return s; |
| } |
| |
| #else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
| |
| char *strsignal(int signum) |
| { |
| static char buf[_STRSIGNAL_BUFSIZE]; |
| static const char unknown[] = { |
| 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' ' |
| }; |
| |
| return memcpy(_int10tostr(buf + sizeof(buf)-1, signum) - sizeof(unknown), |
| unknown, sizeof(unknown)); |
| } |
| |
| #endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
| |
| libc_hidden_def(strsignal) |