]> granicus.if.org Git - procps-ng/commitdiff
sig: Move runtime signal count check to compile time
authorJames Clarke <jrtc27@jrtc27.com>
Fri, 13 Oct 2017 16:09:47 +0000 (17:09 +0100)
committerCraig Small <csmall@enc.com.au>
Sat, 23 Dec 2017 06:48:36 +0000 (17:48 +1100)
Since the value of number_of_signals is known at compile time, we can
use a compile-time check instead. This also adds SIGLOST for the Hurd,
uses the correct signal counts for the Hurd and FreeBSD, and only gives
a compile-time warning when compiled on an unknown platform that it does
not know whether the number of signals is correct.

proc/sig.c

index a93aabb912342b2f4d2167f2379f9956a9409b9c..b883185fc28afbcfb4afb68c04c800965d205add 100644 (file)
  * You get SIGSTKFLT and SIGUNUSED instead on i386, m68k, ppc, and arm.
  * (this is a Linux & libc bug -- both must be fixed)
  *
- * Total garbage: SIGIO SIGINFO SIGIOT SIGLOST SIGCLD
+ * Total garbage: SIGIO SIGINFO SIGIOT SIGCLD
  *                 (popular ones are handled as aliases)
+ *                SIGLOST
+ *                 (except on the Hurd; reused to mean a server died)
  * Nearly garbage: SIGSTKFLT SIGUNUSED (nothing else to fill slots)
  */
 
 #  undef SIGSTKFLT
 #endif
 
+#if !defined(__GNU__) && defined(SIGLOST)
+#  undef SIGLOST
+#endif
+
 #ifndef SIGRTMIN
 #  warning Standards require that <signal.h> define SIGRTMIN; assuming 32
 #  define SIGRTMIN 32
@@ -81,6 +87,9 @@ static const mapstruct sigtable[] = {
   {"ILL",    SIGILL},
   {"INT",    SIGINT},
   {"KILL",   SIGKILL},
+#ifdef SIGLOST
+  {"LOST",   SIGLOST},  /* Hurd-specific */
+#endif
   {"PIPE",   SIGPIPE},
   {"POLL",   SIGPOLL},  /* IO */
   {"PROF",   SIGPROF},
@@ -108,7 +117,24 @@ static const mapstruct sigtable[] = {
   {"XFSZ",   SIGXFSZ}
 };
 
-static const int number_of_signals = sizeof(sigtable)/sizeof(mapstruct);
+#define number_of_signals (sizeof(sigtable)/sizeof(mapstruct))
+
+#define XJOIN(a, b) JOIN(a, b)
+#define JOIN(a, b) a##b
+#define STATIC_ASSERT(x) typedef int XJOIN(static_assert_on_line_,__LINE__)[(x) ? 1 : -1]
+
+/* sanity check */
+#if defined(__linux__)
+STATIC_ASSERT(number_of_signals == 31);
+#elif defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+STATIC_ASSERT(number_of_signals == 30);
+#elif defined(__GNU__)
+STATIC_ASSERT(number_of_signals == 31);
+#elif defined(__CYGWIN__)
+STATIC_ASSERT(number_of_signals == 31);
+#else
+#  warning Unknown operating system; assuming number_of_signals is correct
+#endif
 
 static int compare_signal_names(const void *a, const void *b){
   return strcasecmp( ((const mapstruct*)a)->name, ((const mapstruct*)b)->name );
@@ -285,12 +311,3 @@ void unix_print_signals(void){
   }
   printf("\n");
 }
-
-/* sanity check */
-static int init_signal_list(void) __attribute__((constructor));
-static int init_signal_list(void){
-  if(number_of_signals != 31){
-    fprintf(stderr, "WARNING: %d signals -- adjust and recompile.\n", number_of_signals);
-  }
-  return 0;
-}