#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#ifndef LISP_FEATURE_WIN32
#include <libgen.h>
#endif
#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
#include <time.h>
#endif
+#if !(defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD))
#include "signal.h"
+#endif
#include "runtime.h"
#include "vars.h"
sigint_init(void)
{
SHOW("entering sigint_init()");
- install_handler(SIGINT, sigint_handler);
+ install_handler(SIGINT, sigint_handler, 1);
SHOW("leaving sigint_init()");
}
\f
It is mostly in the public domain; some portions are provided under\n\
BSD-style licenses. See the CREDITS and COPYING files in the\n\
distribution for more information.\n\
-", SBCL_VERSION_STRING);
+"
+#ifdef LISP_FEATURE_WIN32
+"\n\
+WARNING: the Windows port is fragile, particularly for multithreaded\n\
+code. Unfortunately, the development team currently lacks the time\n\
+and resources this platform demands.\n\
+"
+#endif
+, SBCL_VERSION_STRING);
}
/* Look for a core file to load, first in the directory named by the
return search;
}
}
+ /* The above for-loop fails to process the last part of PATH if PATH does
+ * not end with ':'. We may consider appending an extra ':' to the end of
+ * SEARCH. -- houjingyi 2013-05-24 */
+ if (start != NULL && *start != '\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);
}
#endif /* LISP_FEATURE_WIN32 */
+size_t
+parse_size_arg(char *arg, char *arg_name)
+{
+ char *tail, *power_name;
+ size_t 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 >= (SIZE_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
+
+void print_locale_variable(const char *name)
+{
+ char *value = getenv(name);
+
+ if (value) {
+ fprintf(stderr, "\n %s=%s", name, value);
+ }
+}
+
+void setup_locale()
+{
+ if(setlocale(LC_ALL, "") == NULL) {
+#ifndef LISP_FEATURE_WIN32
+
+ fprintf(stderr, "WARNING: Setting locale failed.\n");
+ fprintf(stderr, " Check the following variables for correct values:");
+
+ if (setlocale(LC_CTYPE, "") == NULL) {
+ print_locale_variable("LC_ALL");
+ print_locale_variable("LC_CTYPE");
+ print_locale_variable("LANG");
+ }
+
+ if (setlocale(LC_MESSAGES, "") == NULL) {
+ print_locale_variable("LC_MESSAGES");
+ }
+ if (setlocale(LC_COLLATE, "") == NULL) {
+ print_locale_variable("LC_COLLATE");
+ }
+ if (setlocale(LC_MONETARY, "") == NULL) {
+ print_locale_variable("LC_MONETARY");
+ }
+ if (setlocale(LC_NUMERIC, "") == NULL) {
+ print_locale_variable("LC_NUMERIC");
+ }
+ if (setlocale(LC_TIME, "") == NULL) {
+ print_locale_variable("LC_TIME");
+ }
+ fprintf(stderr, "\n");
+
+#endif
+ }
+}
+
\f
int
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);
- setlocale(LC_ALL, "");
-
runtime_options = NULL;
/* Save the argv[0] derived runtime path in case
++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");
+ MAX_DYNAMIC_SPACE_END))) {
+ char* suffix = "";
+ char* size = argv[argi-1];
+ if (!strchr(size, 'B') && !strchr(size, 'b')) {
+ suffix = " [MB]";
+ }
+ lose("--dynamic-space-size argument %s%s is too large, max %lu KB",
+ size, suffix,
+ (MAX_DYNAMIC_SPACE_END-DYNAMIC_SPACE_START) / 1024);
+ }
# 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");
/* Align down to multiple of page_table page size, and to the appropriate
* stack alignment. */
- dynamic_space_size &= ~(PAGE_BYTES-1);
+ dynamic_space_size &= ~(sword_t)(PAGE_BYTES-1);
#ifdef LISP_FEATURE_GENCGC
- dynamic_space_size &= ~(GENCGC_CARD_BYTES-1);
+ dynamic_space_size &= ~(sword_t)(GENCGC_CARD_BYTES-1);
#endif
- thread_control_stack_size &= ~(CONTROL_STACK_ALIGNMENT_BYTES-1);
+ thread_control_stack_size &= ~(sword_t)(CONTROL_STACK_ALIGNMENT_BYTES-1);
/* Preserve the runtime options for possible future core saving */
runtime_options->dynamic_space_size = dynamic_space_size;
* 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();
+ setup_locale();
+
/* If no core file was specified, look for one. */
if (!core) {
core = search_for_core();
if (initial_function == NIL) {
lose("couldn't find initial function\n");
}
+#ifdef LISP_FEATURE_SB_DYNAMIC_CORE
+ os_link_runtime();
+#endif
#ifdef LISP_FEATURE_HPUX
/* -1 = CLOSURE_FUN_OFFSET, 23 = SIMPLE_FUN_CODE_OFFSET, we are
* not in LANGUAGE_ASSEMBLY so we cant reach them. */
FSHOW((stderr, "/funcalling initial_function=0x%lx\n",
(unsigned long)initial_function));
-#ifdef LISP_FEATURE_WIN32
- fprintf(stderr, "\n\
-This is experimental prerelease support for the Windows platform: use\n\
-at your own risk. \"Your Kitten of Death awaits!\"\n");
- fflush(stdout);
- fflush(stderr);
-#endif
create_initial_thread(initial_function);
- lose("CATS. CATS ARE NICE.\n");
+ lose("unexpected return from initial thread in main()\n");
return 0;
}