u_signal_names.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Signal name/number conversion routines.
  4. *
  5. * Copyright 2006 Rob Landley <rob@landley.net>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //config:config FEATURE_RTMINMAX
  10. //config: bool "Support RTMIN[+n] and RTMAX[-n] signal names"
  11. //config: default y
  12. //config: help
  13. //config: Support RTMIN[+n] and RTMAX[-n] signal names
  14. //config: in kill, killall etc. This costs ~250 bytes.
  15. //config:
  16. //config:config FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
  17. //config: bool "Use the definitions of SIGRTMIN/SIGRTMAX provided by libc"
  18. //config: default y
  19. //config: depends on FEATURE_RTMINMAX
  20. //config: help
  21. //config: Some C libraries reserve a few real-time signals for internal
  22. //config: use, and adjust the values of SIGRTMIN/SIGRTMAX seen by
  23. //config: applications accordingly. Saying yes here means that a signal
  24. //config: name RTMIN+n will be interpreted according to the libc definition
  25. //config: of SIGRTMIN, and not the raw definition provided by the kernel.
  26. //config: This behavior matches "kill -l RTMIN+n" from bash.
  27. #include "libbb.h"
  28. /* Believe it or not, but some arches have more than 32 SIGs!
  29. * HPPA: SIGSTKFLT == 36. */
  30. static const char signals[][7] ALIGN1 = {
  31. // SUSv3 says kill must support these, and specifies the numerical values,
  32. // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
  33. // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"},
  34. // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"}
  35. // And Posix adds the following:
  36. // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
  37. // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
  38. // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
  39. // {SIGTTOU, "TTOU"}
  40. [0] = "EXIT",
  41. #ifdef SIGHUP
  42. [SIGHUP ] = "HUP",
  43. #endif
  44. #ifdef SIGINT
  45. [SIGINT ] = "INT",
  46. #endif
  47. #ifdef SIGQUIT
  48. [SIGQUIT ] = "QUIT",
  49. #endif
  50. #ifdef SIGILL
  51. [SIGILL ] = "ILL",
  52. #endif
  53. #ifdef SIGTRAP
  54. [SIGTRAP ] = "TRAP",
  55. #endif
  56. #ifdef SIGABRT
  57. [SIGABRT ] = "ABRT",
  58. #endif
  59. #ifdef SIGBUS
  60. [SIGBUS ] = "BUS",
  61. #endif
  62. #ifdef SIGFPE
  63. [SIGFPE ] = "FPE",
  64. #endif
  65. #ifdef SIGKILL
  66. [SIGKILL ] = "KILL",
  67. #endif
  68. #ifdef SIGUSR1
  69. [SIGUSR1 ] = "USR1",
  70. #endif
  71. #ifdef SIGSEGV
  72. [SIGSEGV ] = "SEGV",
  73. #endif
  74. #ifdef SIGUSR2
  75. [SIGUSR2 ] = "USR2",
  76. #endif
  77. #ifdef SIGPIPE
  78. [SIGPIPE ] = "PIPE",
  79. #endif
  80. #ifdef SIGALRM
  81. [SIGALRM ] = "ALRM",
  82. #endif
  83. #ifdef SIGTERM
  84. [SIGTERM ] = "TERM",
  85. #endif
  86. #ifdef SIGSTKFLT
  87. [SIGSTKFLT] = "STKFLT",
  88. #endif
  89. #ifdef SIGCHLD
  90. [SIGCHLD ] = "CHLD",
  91. #endif
  92. #ifdef SIGCONT
  93. [SIGCONT ] = "CONT",
  94. #endif
  95. #ifdef SIGSTOP
  96. [SIGSTOP ] = "STOP",
  97. #endif
  98. #ifdef SIGTSTP
  99. [SIGTSTP ] = "TSTP",
  100. #endif
  101. #ifdef SIGTTIN
  102. [SIGTTIN ] = "TTIN",
  103. #endif
  104. #ifdef SIGTTOU
  105. [SIGTTOU ] = "TTOU",
  106. #endif
  107. #ifdef SIGURG
  108. [SIGURG ] = "URG",
  109. #endif
  110. #ifdef SIGXCPU
  111. [SIGXCPU ] = "XCPU",
  112. #endif
  113. #ifdef SIGXFSZ
  114. [SIGXFSZ ] = "XFSZ",
  115. #endif
  116. #ifdef SIGVTALRM
  117. [SIGVTALRM] = "VTALRM",
  118. #endif
  119. #ifdef SIGPROF
  120. [SIGPROF ] = "PROF",
  121. #endif
  122. #ifdef SIGWINCH
  123. [SIGWINCH ] = "WINCH",
  124. #endif
  125. #ifdef SIGPOLL
  126. [SIGPOLL ] = "POLL",
  127. #endif
  128. #ifdef SIGPWR
  129. [SIGPWR ] = "PWR",
  130. #endif
  131. #ifdef SIGSYS
  132. [SIGSYS ] = "SYS",
  133. #endif
  134. #if ENABLE_FEATURE_RTMINMAX && !ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
  135. # ifdef __SIGRTMIN
  136. [__SIGRTMIN] = "RTMIN",
  137. # endif
  138. // This makes array about x2 bigger.
  139. // More compact approach is to special-case SIGRTMAX in print_signames()
  140. //# ifdef __SIGRTMAX
  141. // [__SIGRTMAX] = "RTMAX",
  142. //# endif
  143. #endif
  144. };
  145. // Convert signal name to number.
  146. int FAST_FUNC get_signum(const char *name)
  147. {
  148. unsigned i;
  149. /* bb_strtou returns UINT_MAX on error. NSIG is smaller
  150. * than UINT_MAX on any sane Unix. Hence no need
  151. * to check errno after bb_strtou().
  152. */
  153. i = bb_strtou(name, NULL, 10);
  154. if (i < NSIG) /* for shells, we allow 0 too */
  155. return i;
  156. if (strncasecmp(name, "SIG", 3) == 0)
  157. name += 3;
  158. for (i = 0; i < ARRAY_SIZE(signals); i++)
  159. if (strcasecmp(name, signals[i]) == 0)
  160. return i;
  161. #if ENABLE_DESKTOP
  162. # if defined(SIGIOT) || defined(SIGIO)
  163. /* SIGIO[T] are aliased to other names,
  164. * thus cannot be stored in the signals[] array.
  165. * Need special code to recognize them */
  166. if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
  167. # ifdef SIGIO
  168. if (!name[2])
  169. return SIGIO;
  170. # endif
  171. # ifdef SIGIOT
  172. if ((name[2] | 0x20) == 't' && !name[3])
  173. return SIGIOT;
  174. # endif
  175. }
  176. # endif
  177. #endif
  178. #if ENABLE_FEATURE_RTMINMAX && defined(SIGRTMIN) && defined(SIGRTMAX)
  179. {
  180. # if ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
  181. /* Use the libc provided values. */
  182. unsigned sigrtmin = SIGRTMIN;
  183. unsigned sigrtmax = SIGRTMAX;
  184. # else
  185. /* Use the "raw" SIGRTMIN/MAX. Underscored names, if exist, provide
  186. * them. If they don't exist, fall back to non-underscored ones: */
  187. # if !defined(__SIGRTMIN)
  188. # define __SIGRTMIN SIGRTMIN
  189. # endif
  190. # if !defined(__SIGRTMAX)
  191. # define __SIGRTMAX SIGRTMAX
  192. # endif
  193. # define sigrtmin __SIGRTMIN
  194. # define sigrtmax __SIGRTMAX
  195. # endif
  196. if (strncasecmp(name, "RTMIN", 5) == 0) {
  197. if (!name[5])
  198. return sigrtmin;
  199. if (name[5] == '+') {
  200. i = bb_strtou(name + 6, NULL, 10);
  201. if (i <= sigrtmax - sigrtmin)
  202. return sigrtmin + i;
  203. }
  204. }
  205. else if (strncasecmp(name, "RTMAX", 5) == 0) {
  206. if (!name[5])
  207. return sigrtmax;
  208. if (name[5] == '-') {
  209. i = bb_strtou(name + 6, NULL, 10);
  210. if (i <= sigrtmax - sigrtmin)
  211. return sigrtmax - i;
  212. }
  213. }
  214. # undef sigrtmin
  215. # undef sigrtmax
  216. }
  217. #endif
  218. return -1;
  219. }
  220. // Convert signal number to name
  221. const char* FAST_FUNC get_signame(int number)
  222. {
  223. if ((unsigned)number < ARRAY_SIZE(signals)) {
  224. if (signals[number][0]) /* if it's not an empty str */
  225. return signals[number];
  226. }
  227. return itoa(number);
  228. }
  229. // Print the whole signal list
  230. void FAST_FUNC print_signames(void)
  231. {
  232. unsigned signo;
  233. for (signo = 1; signo < ARRAY_SIZE(signals); signo++) {
  234. const char *name = signals[signo];
  235. if (name[0])
  236. printf("%2u) %s\n", signo, name);
  237. }
  238. #if ENABLE_FEATURE_RTMINMAX
  239. # if ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
  240. # if defined(SIGRTMIN) && defined(SIGRTMAX)
  241. printf("%2u) %s\n", SIGRTMIN, "RTMIN");
  242. printf("%2u) %s\n", SIGRTMAX, "RTMAX");
  243. # endif
  244. # else
  245. // __SIGRTMIN is included in signals[] array.
  246. # ifdef __SIGRTMAX
  247. printf("%2u) %s\n", __SIGRTMAX, "RTMAX");
  248. # endif
  249. # endif
  250. #endif
  251. }