2 * main() entry point for a stand-alone SBCL image
6 * This software is part of the SBCL system. See the README file for
9 * This software is derived from the CMU CL system, which was
10 * written at Carnegie Mellon University and released into the
11 * public domain. The software is in the public domain and is
12 * provided with absolutely no warranty. See the COPYING and CREDITS
13 * files for more information.
20 #ifndef LISP_FEATURE_WIN32
23 #include <sys/types.h>
24 #ifndef LISP_FEATURE_WIN32
30 #include <sys/param.h>
33 #ifndef LISP_FEATURE_WIN32
39 #if defined(SVR4) || defined(__linux__)
50 #include "interrupt.h"
61 #include "genesis/static-symbols.h"
62 #include "genesis/symbol.h"
71 #define SBCL_HOME "/usr/local/lib/sbcl/"
75 /* SIGINT handler that invokes the monitor (for when Lisp isn't up to it) */
77 sigint_handler(int signal, siginfo_t *info, void *void_context)
79 lose("\nSIGINT hit at 0x%08lX\n",
80 (unsigned long) *os_context_pc_addr(void_context));
83 /* (This is not static, because we want to be able to call it from
88 SHOW("entering sigint_init()");
89 install_handler(SIGINT, sigint_handler);
90 SHOW("leaving sigint_init()");
94 * helper functions for dealing with command line args
98 successful_malloc(size_t size)
100 void* result = malloc(size);
102 lose("malloc failure\n");
106 return (void *) NULL; /* dummy value: return something ... */
110 copied_string(char *string)
112 return strcpy(successful_malloc(1+strlen(string)), string);
116 copied_existing_filename_or_null(char *filename)
118 struct stat filename_stat;
119 if (stat(filename, &filename_stat)) { /* if failure */
122 return copied_string(filename);
126 /* Convert a null-terminated array of null-terminated strings (e.g.
127 * argv or envp) into a Lisp list of Lisp base-strings. */
129 alloc_base_string_list(char *array_ptr[])
132 return alloc_cons(alloc_base_string(*array_ptr),
133 alloc_base_string_list(1 + array_ptr));
139 /* miscellaneous chattiness */
145 "SBCL is a Common Lisp programming environment. Ordinarily you shouldn't\n\
146 need command line options when you invoke it interactively: you can just\n\
147 start it and work with the customary Lisp READ-EVAL-PRINT loop.\n\
149 One option idiom which is sometimes useful interactively (e.g. when\n\
150 exercising a test case for a bug report) is\n\
151 sbcl --no-sysinit --no-userinit\n\
152 to keep SBCL from reading any initialization files at startup. And some\n\
153 people like to suppress the default startup message:\n\
156 Other options can be useful when you're running SBCL noninteractively,\n\
157 e.g. from a script, or if you have a strange system configuration, so\n\
158 that SBCL can't by default find one of the files it needs. For\n\
159 information on such options, see the sbcl(1) man page.\n\
161 More information on SBCL can be found on its man page, or at\n\
162 <http://sbcl.sf.net/>.\n");
168 printf("SBCL %s\n", SBCL_VERSION_STRING);
175 "This is SBCL %s, an implementation of ANSI Common Lisp.\n\
176 More information about SBCL is available at <http://www.sbcl.org/>.\n\
178 SBCL is free software, provided as is, with absolutely no warranty.\n\
179 It is mostly in the public domain; some portions are provided under\n\
180 BSD-style licenses. See the CREDITS and COPYING files in the\n\
181 distribution for more information.\n\
182 ", SBCL_VERSION_STRING);
185 /* Look for a core file to load, first in the directory named by the
186 * SBCL_HOME environment variable, then in a hardcoded default
187 * location. Returns a malloced copy of the core filename. */
191 char *sbcl_home = getenv("SBCL_HOME");
193 char *stem = "/sbcl.core";
196 if(!sbcl_home) sbcl_home = SBCL_HOME;
197 lookhere = (char *) calloc(strlen(sbcl_home) +
201 sprintf(lookhere, "%s%s", sbcl_home, stem);
202 core = copied_existing_filename_or_null(lookhere);
205 lose("can't find core file\n");
213 main(int argc, char *argv[], char *envp[])
215 #ifdef LISP_FEATURE_WIN32
216 /* Exception handling support structure. Evil Win32 hack. */
217 struct lisp_exception_frame exception_frame;
220 /* the name of the core file we're to execute. Note that this is
221 * a malloc'ed string which should be freed eventually. */
223 char **sbcl_argv = 0;
224 os_vm_offset_t embedded_core_offset = 0;
226 /* other command line options */
227 boolean noinform = 0;
228 boolean end_runtime_options = 0;
230 lispobj initial_function;
233 block_blockable_signals();
235 setlocale(LC_ALL, "");
237 /* KLUDGE: os_vm_page_size is set by os_init(), and on some
238 * systems (e.g. Alpha) arch_init() needs need os_vm_page_size, so
239 * it must follow os_init(). -- WHN 2000-01-26 */
245 /* Parse our part of the command line (aka "runtime options"),
246 * stripping out those options that we handle. */
249 while (argi < argc) {
250 char *arg = argv[argi];
251 if (0 == strcmp(arg, "--noinform")) {
254 } else if (0 == strcmp(arg, "--core")) {
256 lose("more than one core file specified\n");
260 lose("missing filename for --core argument\n");
262 core = copied_string(argv[argi]);
265 } else if (0 == strcmp(arg, "--help")) {
266 /* I think this is the (or a) usual convention: upon
267 * seeing "--help" we immediately print our help
268 * string and exit, ignoring everything else. */
271 } else if (0 == strcmp(arg, "--version")) {
272 /* As in "--help" case, I think this is expected. */
275 } else if (0 == strcmp(arg, "--end-runtime-options")) {
276 end_runtime_options = 1;
280 /* This option was unrecognized as a runtime option,
281 * so it must be a toplevel option or a user option,
282 * so we must be past the end of the runtime option
287 /* This is where we strip out those options that we handle. We
288 * also take this opportunity to make sure that we don't find
289 * an out-of-place "--end-runtime-options" option. */
291 char *argi0 = argv[argi];
293 /* (argc - argi) for the arguments, one for the binary,
294 and one for the terminating NULL. */
295 sbcl_argv = successful_malloc((2 + argc - argi) * sizeof(char *));
296 sbcl_argv[0] = argv[0];
297 while (argi < argc) {
298 char *arg = argv[argi++];
299 /* If we encounter --end-runtime-options for the first
300 * time after the point where we had to give up on
301 * runtime options, then the point where we had to
302 * give up on runtime options must've been a user
304 if (!end_runtime_options &&
305 0 == strcmp(arg, "--end-runtime-options")) {
306 lose("bad runtime option \"%s\"\n", argi0);
308 sbcl_argv[argj++] = arg;
314 /* If no core file was specified, look for one. */
316 char *runtime_path = os_get_runtime_executable_path();
319 os_vm_offset_t offset = search_for_embedded_core(runtime_path);
322 embedded_core_offset = offset;
326 core = search_for_core();
329 core = search_for_core();
333 /* Make sure that SBCL_HOME is set, unless loading an embedded core. */
334 if (!getenv("SBCL_HOME") && embedded_core_offset == 0) {
335 char *envstring, *copied_core, *dir;
336 char *stem = "SBCL_HOME=";
337 copied_core = copied_string(core);
338 dir = dirname(copied_core);
339 envstring = (char *) calloc(strlen(stem) +
343 sprintf(envstring, "%s%s", stem, dir);
353 #if defined(SVR4) || defined(__linux__)
357 define_var("nil", NIL, 1);
358 define_var("t", T, 1);
360 set_lossage_handler(monitor_or_something);
364 initial_function = load_core_file(core, embedded_core_offset);
365 if (initial_function == NIL) {
366 lose("couldn't find initial function\n");
369 gc_initialize_pointers();
371 arch_install_interrupt_handlers();
372 #ifndef LISP_FEATURE_WIN32
373 os_install_interrupt_handlers();
375 /* wos_install_interrupt_handlers(handler); */
376 wos_install_interrupt_handlers(&exception_frame);
379 /* Pass core filename into Lisp */
380 SetSymbolValue(CORE_STRING, alloc_base_string(core),0);
381 SHOW("freeing core");
384 /* Convert remaining argv values to something that Lisp can grok. */
385 SHOW("setting POSIX-ARGV symbol value");
386 SetSymbolValue(POSIX_ARGV, alloc_base_string_list(sbcl_argv),0);
389 FSHOW((stderr, "/funcalling initial_function=0x%lx\n",
390 (unsigned long)initial_function));
391 #ifdef LISP_FEATURE_WIN32
393 This is experimental prerelease support for the Windows platform: use\n\
394 at your own risk. \"Your Kitten of Death awaits!\"\n");
398 create_initial_thread(initial_function);
399 lose("CATS. CATS ARE NICE.\n");