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 --sysinit /dev/null --userinit /dev/null\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);
187 main(int argc, char *argv[], char *envp[])
189 #ifdef LISP_FEATURE_WIN32
190 /* Exception handling support structure. Evil Win32 hack. */
191 struct lisp_exception_frame exception_frame;
194 /* the name of the core file we're to execute. Note that this is
195 * a malloc'ed string which should be freed eventually. */
197 char **sbcl_argv = 0;
199 /* other command line options */
200 boolean noinform = 0;
201 boolean end_runtime_options = 0;
203 lispobj initial_function;
206 block_blockable_signals();
208 setlocale(LC_ALL, "");
210 /* KLUDGE: os_vm_page_size is set by os_init(), and on some
211 * systems (e.g. Alpha) arch_init() needs need os_vm_page_size, so
212 * it must follow os_init(). -- WHN 2000-01-26 */
218 /* Parse our part of the command line (aka "runtime options"),
219 * stripping out those options that we handle. */
222 while (argi < argc) {
223 char *arg = argv[argi];
224 if (0 == strcmp(arg, "--noinform")) {
227 } else if (0 == strcmp(arg, "--core")) {
229 lose("more than one core file specified\n");
233 lose("missing filename for --core argument\n");
235 core = copied_string(argv[argi]);
238 } else if (0 == strcmp(arg, "--help")) {
239 /* I think this is the (or a) usual convention: upon
240 * seeing "--help" we immediately print our help
241 * string and exit, ignoring everything else. */
244 } else if (0 == strcmp(arg, "--version")) {
245 /* As in "--help" case, I think this is expected. */
248 } else if (0 == strcmp(arg, "--end-runtime-options")) {
249 end_runtime_options = 1;
253 /* This option was unrecognized as a runtime option,
254 * so it must be a toplevel option or a user option,
255 * so we must be past the end of the runtime option
260 /* This is where we strip out those options that we handle. We
261 * also take this opportunity to make sure that we don't find
262 * an out-of-place "--end-runtime-options" option. */
264 char *argi0 = argv[argi];
266 /* (argc - argi) for the arguments, one for the binary,
267 and one for the terminating NULL. */
268 sbcl_argv = successful_malloc((2 + argc - argi) * sizeof(char *));
269 sbcl_argv[0] = argv[0];
270 while (argi < argc) {
271 char *arg = argv[argi++];
272 /* If we encounter --end-runtime-options for the first
273 * time after the point where we had to give up on
274 * runtime options, then the point where we had to
275 * give up on runtime options must've been a user
277 if (!end_runtime_options &&
278 0 == strcmp(arg, "--end-runtime-options")) {
279 lose("bad runtime option \"%s\"\n", argi0);
281 sbcl_argv[argj++] = arg;
287 /* If no core file was specified, look for one. */
289 char *sbcl_home = getenv("SBCL_HOME");
291 char *stem = "/sbcl.core";
292 if(!sbcl_home) sbcl_home = SBCL_HOME;
293 lookhere = (char *) calloc(strlen(sbcl_home) +
297 sprintf(lookhere, "%s%s", sbcl_home, stem);
298 core = copied_existing_filename_or_null(lookhere);
301 lose("can't find core file\n");
304 /* Make sure that SBCL_HOME is set, no matter where the core was
306 if (!getenv("SBCL_HOME")) {
307 char *envstring, *copied_core, *dir;
308 char *stem = "SBCL_HOME=";
309 copied_core = copied_string(core);
310 dir = dirname(copied_core);
311 envstring = (char *) calloc(strlen(stem) +
315 sprintf(envstring, "%s%s", stem, dir);
325 #if defined(SVR4) || defined(__linux__)
329 define_var("nil", NIL, 1);
330 define_var("t", T, 1);
332 set_lossage_handler(monitor_or_something);
336 initial_function = load_core_file(core);
337 if (initial_function == NIL) {
338 lose("couldn't find initial function\n");
340 SHOW("freeing core");
343 gc_initialize_pointers();
345 arch_install_interrupt_handlers();
346 #ifndef LISP_FEATURE_WIN32
347 os_install_interrupt_handlers();
349 /* wos_install_interrupt_handlers(handler); */
350 wos_install_interrupt_handlers(&exception_frame);
353 /* Convert remaining argv values to something that Lisp can grok. */
354 SHOW("setting POSIX-ARGV symbol value");
355 SetSymbolValue(POSIX_ARGV, alloc_base_string_list(sbcl_argv),0);
358 FSHOW((stderr, "/funcalling initial_function=0x%lx\n",
359 (unsigned long)initial_function));
360 #ifdef LISP_FEATURE_WIN32
362 This is experimental prerelease support for the Windows platform: use\n\
363 at your own risk. \"Your Kitten of Death awaits!\"\n");
367 create_initial_thread(initial_function);
368 lose("CATS. CATS ARE NICE.\n");