X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fruntime.c;h=f127933225786b82344bb2968bbcfdc1e601c2dd;hb=5c0a884190d6c98448d86fb05e1e99df901c9bf8;hp=02898e3d16d0b7959339fbfcb4dd564949731242;hpb=1eb303172df6650de51ad12b993a392681f50c50;p=sbcl.git diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 02898e3..f127933 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -35,6 +35,7 @@ #endif #include #include +#include #if defined(SVR4) || defined(__linux__) #include @@ -43,14 +44,14 @@ #include "signal.h" #include "runtime.h" -#include "alloc.h" #include "vars.h" #include "globals.h" #include "os.h" +#include "interr.h" +#include "alloc.h" #include "interrupt.h" #include "arch.h" #include "gc.h" -#include "interr.h" #include "validate.h" #include "core.h" #include "save.h" @@ -67,16 +68,22 @@ #endif #ifndef SBCL_HOME -#define SBCL_HOME "/usr/local/lib/sbcl/" +#define SBCL_HOME SBCL_PREFIX"/lib/sbcl/" +#endif + +#ifdef LISP_FEATURE_HPUX +extern void *return_from_lisp_stub; +#include "genesis/closure.h" +#include "genesis/simple-fun.h" #endif /* SIGINT handler that invokes the monitor (for when Lisp isn't up to it) */ static void -sigint_handler(int signal, siginfo_t *info, void *void_context) +sigint_handler(int signal, siginfo_t *info, os_context_t *context) { lose("\nSIGINT hit at 0x%08lX\n", - (unsigned long) *os_context_pc_addr(void_context)); + (unsigned long) *os_context_pc_addr(context)); } /* (This is not static, because we want to be able to call it from @@ -121,6 +128,37 @@ copied_existing_filename_or_null(char *filename) return copied_string(filename); } } + +#ifndef LISP_FEATURE_WIN32 +char * +copied_realpath(const char *pathname) +{ + char *messy, *tidy; + size_t len; + + /* realpath() supposedly can't be counted on to always return + * an absolute path, so we prepend the cwd to relative paths */ + messy = NULL; + if (pathname[0] != '/') { + messy = successful_malloc(PATH_MAX + 1); + if (getcwd(messy, PATH_MAX + 1) == NULL) { + free(messy); + return NULL; + } + len = strlen(messy); + snprintf(messy + len, PATH_MAX + 1 - len, "/%s", pathname); + } + + tidy = successful_malloc(PATH_MAX + 1); + if (realpath((messy ? messy : pathname), tidy) == NULL) { + free(messy); + free(tidy); + return NULL; + } + + return tidy; +} +#endif /* LISP_FEATURE_WIN32 */ /* miscellaneous chattiness */ @@ -199,9 +237,58 @@ search_for_core () return core; } +/* Try to find the path to an executable from argv[0], this is only + * used when os_get_runtime_executable_path() returns NULL */ +#ifdef LISP_FEATURE_WIN32 +char * +search_for_executable(const char *argv0) +{ + return NULL; +} +#else /* LISP_FEATURE_WIN32 */ +char * +search_for_executable(const char *argv0) +{ + char *search, *start, *end, *buf; + + /* If argv[0] contains a slash then it's probably an absolute path + * or relative to the current directory, so check if it exists. */ + if (strchr(argv0, '/') != NULL && access(argv0, F_OK) == 0) + return copied_realpath(argv0); + + /* Bail on an absolute path which doesn't exist */ + if (argv0[0] == '/') + return NULL; + + /* Otherwise check if argv[0] exists relative to any directory in PATH */ + search = getenv("PATH"); + if (search == NULL) + return NULL; + search = copied_string(search); + buf = successful_malloc(PATH_MAX + 1); + for (start = search; (end = strchr(start, ':')) != NULL; start = end + 1) { + *end = '\0'; + snprintf(buf, PATH_MAX + 1, "%s/%s", start, argv0); + if (access(buf, F_OK) == 0) { + free(search); + search = copied_realpath(buf); + free(buf); + return search; + } + } + + free(search); + free(buf); + return NULL; +} +#endif /* LISP_FEATURE_WIN32 */ + char **posix_argv; char *core_string; +struct runtime_options *runtime_options; + +char *saved_runtime_path = NULL; int main(int argc, char *argv[], char *envp[]) @@ -216,26 +303,70 @@ main(int argc, char *argv[], char *envp[]) char *core = 0; char **sbcl_argv = 0; os_vm_offset_t embedded_core_offset = 0; + char *runtime_path = 0; /* other command line options */ boolean noinform = 0; boolean end_runtime_options = 0; + boolean disable_lossage_handler_p = 0; lispobj initial_function; const char *sbcl_home = getenv("SBCL_HOME"); interrupt_init(); - block_blockable_signals(); + block_blockable_signals(0, 0); setlocale(LC_ALL, ""); + runtime_options = NULL; + + /* Save the argv[0] derived runtime path in case + * os_get_runtime_executable_path(1) isn't able to get an + * externally-usable path later on. */ + saved_runtime_path = search_for_executable(argv[0]); + + /* Check early to see if this executable has an embedded core, + * which also populates runtime_options if the core has runtime + * options */ + runtime_path = os_get_runtime_executable_path(0); + if (runtime_path || saved_runtime_path) { + os_vm_offset_t offset = search_for_embedded_core( + runtime_path ? runtime_path : saved_runtime_path); + if (offset != -1) { + embedded_core_offset = offset; + core = (runtime_path ? runtime_path : + copied_string(saved_runtime_path)); + } else { + if (runtime_path) + free(runtime_path); + } + } + + /* Parse our part of the command line (aka "runtime options"), * stripping out those options that we handle. */ - { + if (runtime_options != NULL) { + dynamic_space_size = runtime_options->dynamic_space_size; + thread_control_stack_size = runtime_options->thread_control_stack_size; + sbcl_argv = argv; + } else { int argi = 1; + + runtime_options = successful_malloc(sizeof(struct runtime_options)); + while (argi < argc) { char *arg = argv[argi]; - if (0 == strcmp(arg, "--noinform")) { + if (0 == strcmp(arg, "--script")) { + /* This is both a runtime and a toplevel option. As a + * runtime option, it is equivalent to --noinform. + * This exits, and does not increment argi, so that + * TOPLEVEL-INIT sees the option. */ + noinform = 1; + end_runtime_options = 1; + disable_lossage_handler_p = 1; + lose_on_corruption_p = 1; + break; + } else if (0 == strcmp(arg, "--noinform")) { noinform = 1; ++argi; } else if (0 == strcmp(arg, "--core")) { @@ -263,10 +394,24 @@ main(int argc, char *argv[], char *envp[]) ++argi; if (argi >= argc) lose("missing argument for --dynamic-space-size"); - errno = 0; - dynamic_space_size = strtol(argv[argi++], 0, 0) << 20; - if (errno) - lose("argument to --dynamic-space-size is not a number"); + { + 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; + } +# 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"); +# endif } else if (0 == strcmp(arg, "--control-stack-size")) { ++argi; if (argi >= argc) @@ -274,7 +419,7 @@ main(int argc, char *argv[], char *envp[]) errno = 0; thread_control_stack_size = strtol(argv[argi++], 0, 0) << 20; if (errno) - lose("argument to --dynamic-space-size is not a number"); + lose("argument to --control-stack-size is not a number"); } else if (0 == strcmp(arg, "--debug-environment")) { int n = 0; printf("; Commandline arguments:\n"); @@ -289,6 +434,12 @@ main(int argc, char *argv[], char *envp[]) ++n; } ++argi; + } else if (0 == strcmp(arg, "--disable-ldb")) { + disable_lossage_handler_p = 1; + ++argi; + } else if (0 == strcmp(arg, "--lose-on-corruption")) { + lose_on_corruption_p = 1; + ++argi; } else if (0 == strcmp(arg, "--end-runtime-options")) { end_runtime_options = 1; ++argi; @@ -331,8 +482,15 @@ main(int argc, char *argv[], char *envp[]) /* Align down to multiple of page_table page size, and to the appropriate * stack alignment. */ dynamic_space_size &= ~(PAGE_BYTES-1); +#ifdef LISP_FEATURE_GENCGC + dynamic_space_size &= ~(GENCGC_CARD_BYTES-1); +#endif thread_control_stack_size &= ~(CONTROL_STACK_ALIGNMENT_BYTES-1); + /* Preserve the runtime options for possible future core saving */ + runtime_options->dynamic_space_size = dynamic_space_size; + runtime_options->thread_control_stack_size = thread_control_stack_size; + /* KLUDGE: os_vm_page_size is set by os_init(), and on some * systems (e.g. Alpha) arch_init() needs need os_vm_page_size, so * it must follow os_init(). -- WHN 2000-01-26 */ @@ -343,21 +501,7 @@ main(int argc, char *argv[], char *envp[]) /* If no core file was specified, look for one. */ if (!core) { - char *runtime_path = os_get_runtime_executable_path(); - - if (runtime_path) { - os_vm_offset_t offset = search_for_embedded_core(runtime_path); - - if (offset != -1) { - embedded_core_offset = offset; - core = runtime_path; - } else { - free(runtime_path); - core = search_for_core(); - } - } else { - core = search_for_core(); - } + core = search_for_core(); } /* Make sure that SBCL_HOME is set and not the empty string, @@ -381,14 +525,15 @@ main(int argc, char *argv[], char *envp[]) fflush(stdout); } -#if defined(SVR4) || defined(__linux__) +#if defined(SVR4) || defined(__linux__) || defined(__NetBSD__) tzset(); #endif define_var("nil", NIL, 1); define_var("t", T, 1); - enable_lossage_handler(); + if (!disable_lossage_handler_p) + enable_lossage_handler(); globals_init(); @@ -396,6 +541,12 @@ main(int argc, char *argv[], char *envp[]) if (initial_function == NIL) { lose("couldn't find initial function\n"); } +#ifdef LISP_FEATURE_HPUX + /* -1 = CLOSURE_FUN_OFFSET, 23 = SIMPLE_FUN_CODE_OFFSET, we are + * not in LANGUAGE_ASSEMBLY so we cant reach them. */ + return_from_lisp_stub = (void *) ((char *)*((unsigned long *) + ((char *)initial_function + -1)) + 23); +#endif gc_initialize_pointers();