Windows console I/O overhaul
[sbcl.git] / src / runtime / runtime.c
index d1a215b..38770a6 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #ifndef LISP_FEATURE_WIN32
 #include <libgen.h>
 #endif
@@ -29,7 +30,7 @@
 #include <sys/file.h>
 #include <sys/param.h>
 #include <sys/stat.h>
-#include <signal.h>
+#include "runtime.h"
 #ifndef LISP_FEATURE_WIN32
 #include <sched.h>
 #endif
@@ -41,7 +42,9 @@
 #include <time.h>
 #endif
 
+#if !(defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD))
 #include "signal.h"
+#endif
 
 #include "runtime.h"
 #include "vars.h"
@@ -291,12 +294,58 @@ search_for_executable(const char *argv0)
 }
 #endif /* LISP_FEATURE_WIN32 */
 
+unsigned long parse_size_arg(char *arg, char *arg_name)
+{
+  char *tail, *power_name;
+  unsigned long power, res;
+
+  res = strtoul(arg, &tail, 0);
+
+  if (arg == tail) {
+    lose("%s argument is not a number: %s", arg_name, arg);
+  } else if (tail[0]) {
+    int i, size;
+    power_name = copied_string(tail);
+    size = strlen(power_name);
+    for (i=0; i<size; i++)
+      power_name[i] = toupper(power_name[i]);
+  } else {
+    power = 20;
+    power_name = NULL;
+  }
+  if (power_name) {
+    if ((0==strcmp("KB", power_name)) ||
+        (0==strcmp("KIB", power_name))) {
+      power = 10;
+    } else if ((0==strcmp("MB", power_name)) ||
+               (0==strcmp("MIB", power_name))) {
+      power = 20;
+    } else if ((0==strcmp("GB", power_name)) ||
+               (0==strcmp("GIB", power_name))) {
+      power = 30;
+    } else {
+      lose("%s argument has an unknown suffix: %s", arg_name, tail);
+    }
+    free(power_name);
+  }
+  if ((res <= 0) ||
+      (res > (ULONG_MAX >> power))) {
+    lose("%s argument is out of range: %s", arg_name, arg);
+  }
+  res <<= power;
+  return res;
+}
+
 char **posix_argv;
 char *core_string;
 
 struct runtime_options *runtime_options;
 
 char *saved_runtime_path = NULL;
+#if defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD)
+void pthreads_win32_init();
+#endif
+
 \f
 int
 main(int argc, char *argv[], char *envp[])
@@ -321,6 +370,11 @@ main(int argc, char *argv[], char *envp[])
     lispobj initial_function;
     const char *sbcl_home = getenv("SBCL_HOME");
 
+#if defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD)
+    os_preinit();
+    pthreads_win32_init();
+#endif
+
     interrupt_init();
     block_blockable_signals(0, 0);
 
@@ -402,32 +456,21 @@ main(int argc, char *argv[], char *envp[])
                 ++argi;
                 if (argi >= argc)
                     lose("missing argument for --dynamic-space-size");
-                {
-                  char *tail;
-                  long tmp = strtol(argv[argi++], &tail, 0);
-                  if (tail[0])
-                    lose("--dynamic-space-size argument is not a number");
-                  if ((tmp <= 0) ||
-                      (tmp >= (LONG_MAX >> 20))) {
-                    lose("--dynamic-space-size argument is out of range");
-                  }
-                  dynamic_space_size = tmp << 20;
-                }
+                  dynamic_space_size = parse_size_arg(argv[argi++], "--dynamic-space-size");
 #               ifdef MAX_DYNAMIC_SPACE_END
                 if (!((DYNAMIC_SPACE_START <
                        DYNAMIC_SPACE_START+dynamic_space_size) &&
                       (DYNAMIC_SPACE_START+dynamic_space_size <=
                        MAX_DYNAMIC_SPACE_END)))
-                    lose("--dynamic-space-size argument is too large");
+                  lose("--dynamic-space-size argument %s is too large, max %lu",
+                       argv[argi-1], MAX_DYNAMIC_SPACE_END-DYNAMIC_SPACE_START);
 #               endif
             } else if (0 == strcmp(arg, "--control-stack-size")) {
                 ++argi;
                 if (argi >= argc)
                     lose("missing argument for --control-stack-size");
                 errno = 0;
-                thread_control_stack_size = strtol(argv[argi++], 0, 0) << 20;
-                if (errno)
-                    lose("argument to --control-stack-size is not a number");
+                thread_control_stack_size = parse_size_arg(argv[argi++], "--control-stack-size");
             } else if (0 == strcmp(arg, "--debug-environment")) {
                 int n = 0;
                 printf("; Commandline arguments:\n");
@@ -452,6 +495,15 @@ main(int argc, char *argv[], char *envp[])
                 end_runtime_options = 1;
                 ++argi;
                 break;
+            } else if (0 == strcmp(arg, "--merge-core-pages")) {
+                ++argi;
+                merge_core_pages = 1;
+            } else if (0 == strcmp(arg, "--no-merge-core-pages")) {
+                ++argi;
+                merge_core_pages = 0;
+            } else if (0 == strcmp(arg, "--default-merge-core-pages")) {
+                ++argi;
+                merge_core_pages = -1;
             } else {
                 /* This option was unrecognized as a runtime option,
                  * so it must be a toplevel option or a user option,
@@ -503,6 +555,7 @@ main(int argc, char *argv[], char *envp[])
      * systems (e.g. Alpha) arch_init() needs need os_vm_page_size, so
      * it must follow os_init(). -- WHN 2000-01-26 */
     os_init(argv, envp);
+    dyndebug_init(); /* after os_init: do not print output before execve */
     arch_init();
     gc_init();
     validate();
@@ -533,6 +586,19 @@ main(int argc, char *argv[], char *envp[])
         fflush(stdout);
     }
 
+    if (embedded_core_offset == 0) {
+        /* Here we make a last attempt at recognizing an embedded core,
+         * so that a file with an embedded core is a valid argument to
+         * --core.  We take care that any decisions on special behaviour
+         * (suppressed banner, embedded options) have already been made
+         * before we reach this block, so that there is no observable
+         * difference between "embedded" and "bare" images given to
+         * --core. */
+        os_vm_offset_t offset = search_for_embedded_core(core);
+        if (offset != -1)
+            embedded_core_offset = offset;
+    }
+
 #if defined(SVR4) || defined(__linux__) || defined(__NetBSD__)
     tzset();
 #endif