From 702fb8b10e70df9bf2d0821b1456b56e9f937239 Mon Sep 17 00:00:00 2001
From: Robert Izzard <r.izzard@surrey.ac.uk>
Date: Wed, 20 Nov 2019 11:49:46 +0800
Subject: [PATCH] add more operating system checks in meson build

meson now checks for setitimer and sets __HAVE_SETITIMER__ if found

reset_timeout no longer requires LINUX, rather it requires __HAVE_SETITIMER__
---
 meson.build                 | 49 ++++++++++++++++++++++++++++++++-----
 src/binary_c_code_options.h |  6 ++++-
 src/reset_timeout.c         | 45 +++++++++++++++++++---------------
 src/setup/version.c         |  5 ++++
 4 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/meson.build b/meson.build
index a02e9ff82..d5c539cd0 100644
--- a/meson.build
+++ b/meson.build
@@ -162,24 +162,52 @@ endforeach
 
 ############################################################
 # per-compiler options
-
+#
 if compiler.get_id() == 'clang'
-    # clang flags
+    # clang-speific flags
     cflags += [ '-fbracket-depth=512' ]
 else
-    # default to gcc flags
+    # gcc-specific flags
     cflags += []
 endif
 
 ############################################################
 # system options
+#
 cflags += '-DCPUFREQ=' + cpufreq
 
-if host_machine.system() == 'linux'
+############################################################
+# operating system flags
+#
+os = host_machine.system()
+cflags += [
+    '-DOPERATING_SYSTEM=' + os
+    ]
+if os == 'linux'
     # Linux system
-    cflags += ['-DLINUX', '-DLARGEFILE_SOURCE']
+    cflags += [
+        '-DLINUX',
+        '-DLARGEFILE_SOURCE'
+    ]
+elif os == 'windows'
+    # windows
+    cflags += [
+        '-DWINDOWS'
+    ]
+elif os == 'darwin'
+    # darwin (MacOSX)
+    cflags += [
+        '-DDARWIN'
+    ]
+else
+    cflags += [
+        '-DUNKNOWN_OPERATING_SYSTEM'
+    ]
 endif
 
+############################################################
+# 64- or 32-bit build
+#
 if compiler.compiles('int main(int argc,char **argv){return 0;}',
                      args : '-m64',
                      name : '64-bit check')  
@@ -302,7 +330,8 @@ endif
 ###########
 # drand48 #
 #
-if compiler.sizeof('drand48_r',
+if compiler.has_header('stdlib.h') and \
+   compiler.sizeof('drand48_r',
                    prefix : '#include <stdlib.h>') > 0
     cflags += '-D__HAVE_DRAND48__'
 endif
@@ -314,6 +343,14 @@ if compiler.has_header('malloc.h')
     cflags += '-D__HAVE_MALLOC_H__'
 endif
 
+############ 
+# setitimer 
+#
+if compiler.has_header('sys/time.h') and \
+   compiler.has_function('setitimer')
+    cflags += '-D__HAVE_SETITIMER__'
+endif
+
 #################################
 # pkg-config (external command) #
 #
diff --git a/src/binary_c_code_options.h b/src/binary_c_code_options.h
index a050b1394..60c5d5da2 100644
--- a/src/binary_c_code_options.h
+++ b/src/binary_c_code_options.h
@@ -311,8 +311,12 @@ void Print_trace(void);
 /*
  * The number of seconds til timeout - see reset_binary_c_timeout.c.
  * Ignored if 0.
+ *
+ * Note: if you set TIMEOUT_SECONDS to be non-zero and do not have 
+ *       setitimer available on your system, binary_c will exit because
+ *       this is considered a bug. 
  */
-#define TIMEOUT_SECONDS 0
+#define TIMEOUT_SECONDS 10
 
 /*
  * Provide a longer timeout if using valgrind
diff --git a/src/reset_timeout.c b/src/reset_timeout.c
index fa8c209ac..db54ce0cc 100644
--- a/src/reset_timeout.c
+++ b/src/reset_timeout.c
@@ -11,18 +11,32 @@
  *
  * TIMEOUT_SECONDS_WITH_VALGRIND is used if we are running under
  * valgrind.
+ *
+ * We require the setitimer command to be available if timeouts
+ * are going to work. This is detected by Meson which sets 
+ * __HAVE_SETITIMER__ if we have setitimer.
  */
 void reset_binary_c_timeout(void)
 {
-
-#ifdef LINUX
+#ifndef __HAVE_SETITIMER__
+    /*
+     * We don't have setitimer but we do want a timeout:
+     * exit with a warning.
+     */
+    Exit_binary_c_no_stardata(BINARY_C_TIMED_OUT,
+                              "TIMEOUT_SECONDS is set to %ld but we have no access to setitimer to actually set the timeout. This will cause binary_c to not have a timeout, even though you have asked for it. Please set TIMEOUT_SECONDS to 0 in binary_c_code_options.h to fix this problem, or build on an operating system that supports setitimer.",
+                              (long int)TIMEOUT_SECONDS);
+        
+#else
+    /*
+     * We have setitimer
+     */
     if(TIMEOUT_SECONDS)
     {
         /* Timing */
         struct itimerval value;
         struct timeval tv;
-/* set timeout limit in seconds */
-
+        /* set timeout limit in seconds */
 #ifdef __HAVE_VALGRIND__
         if(RUNNING_ON_VALGRIND)
         {
@@ -36,31 +50,22 @@ void reset_binary_c_timeout(void)
         tv.tv_sec = TIMEOUT_SECONDS;
 #endif  // __HAVE_VALGRIND__
         tv.tv_usec=0;
-        value.it_value=tv; 
-        value.it_interval=tv;
+
+        value.it_value = tv; 
+        value.it_interval = tv;
         if(unlikely(setitimer(ITIMER_VIRTUAL,&value,0) == -1))
         {
             Exit_binary_c_no_stardata(BINARY_C_TIMED_OUT,
                                       "Failed to allocate virtual timer");
         }
-#ifdef RANDOM_SYSTEMS_SHOW_ARGS_AND_START_TIME
-        time_t t = time(NULL);
-        char timestring[100];
-        if(strftime(timestring,sizeof(timestring)," %F %T :   ",localtime(&t)))
-        {
-            fprintf(RANDOM_SYSTEMS_SHOW_ARGS_STREAM,
-                    "Reset timer to %ld at %s",
-                    (long int)tv.tv_sec,
-                    timestring);
-        }
-#endif
     }
-#endif /* LINUX */
+#endif //__HAVE_SETITIMER__
+
 }
 
 void disable_binary_c_timeout(void)
 {
-#ifdef LINUX
+#ifdef __HAVE_SETITIMER__
     if(TIMEOUT_SECONDS)
     {
         struct itimerval value;
@@ -76,5 +81,5 @@ void disable_binary_c_timeout(void)
                                       "Failed to allocate virtual timer");
         }
     }
-#endif // LINUX
+#endif // __HAVE_SETITIMER__
 }
diff --git a/src/setup/version.c b/src/setup/version.c
index e28a53fb9..543e48e05 100644
--- a/src/setup/version.c
+++ b/src/setup/version.c
@@ -756,7 +756,11 @@ void version(struct stardata_t * RESTRICT const stardata)
     }
     Macrotest(SEGFAULTS);
     Macrotest(CATCH_SIGVTALRM);
+    Show_string_macro(OPERATING_SYSTEM);
     Macrotest(LINUX);
+    Macrotest(WINDOWS);
+    Macrotest(DARWIN);
+    Macrotest(UNKNOWN_OPERATING_SYSTEM);
     Macrotest(__APPLE__);
     Macrotest(__arm__);
     Macrotest(__i386__);
@@ -852,6 +856,7 @@ void version(struct stardata_t * RESTRICT const stardata)
     Macrotest(__HAVE_LIBBACKTRACE__);
     Macrotest(__HAVE_MALLOC_H__);
     Macrotest(__HAVE_DRAND48__);
+    Macrotest(__HAVE_SETITIMER__);
     Macrotest(__HAVE_PKG_CONFIG__);
     Macrotest(BACKTRACE);
 #ifdef BACKTRACE
-- 
GitLab