+#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 */
+\f
+/* miscellaneous chattiness */
+
+void
+print_help()
+{
+ puts(
+"Usage: sbcl [runtime-options] [toplevel-options] [user-options]\n\
+Common runtime options:\n\
+ --help Print this message and exit.\n\
+ --version Print version information and exit.\n\
+ --core <filename> Use the specified core file instead of the default.\n\
+ --dynamic-space-size <MiB> Size of reserved dynamic space in megabytes.\n\
+ --control-stack-size <MiB> Size of reserved control stack in megabytes.\n\
+\n\
+Common toplevel options:\n\
+ --sysinit <filename> System-wide init-file to use instead of default.\n\
+ --userinit <filename> Per-user init-file to use instead of default.\n\
+ --no-sysinit Inhibit processing of any system-wide init-file.\n\
+ --no-userinit Inhibit processing of any per-user init-file.\n\
+ --disable-debugger Invoke sb-ext:disable-debugger.\n\
+ --noprint Run a Read-Eval Loop without printing results.\n\
+ --script [<filename>] Skip #! line, disable debugger, avoid verbosity.\n\
+ --quit Exit with code 0 after option processing.\n\
+ --non-interactive Sets both --quit and --disable-debugger.\n\
+Common toplevel options that are processed in order:\n\
+ --eval <form> Form to eval when processing this option.\n\
+ --load <filename> File to load when processing this option.\n\
+\n\
+User options are not processed by SBCL. All runtime options must\n\
+appear before toplevel options, and all toplevel options must\n\
+appear before user options.\n\
+\n\
+For more information please refer to the SBCL User Manual, which\n\
+should be installed along with SBCL, and is also available from the\n\
+website <http://www.sbcl.org/>.\n");
+}
+
+void
+print_version()
+{
+ printf("SBCL %s\n", SBCL_VERSION_STRING);
+}
+
+void
+print_banner()
+{
+ printf(
+"This is SBCL %s, an implementation of ANSI Common Lisp.\n\
+More information about SBCL is available at <http://www.sbcl.org/>.\n\
+\n\
+SBCL is free software, provided as is, with absolutely no warranty.\n\
+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);
+}
+
+/* Look for a core file to load, first in the directory named by the
+ * SBCL_HOME environment variable, then in a hardcoded default
+ * location. Returns a malloced copy of the core filename. */
+char *
+search_for_core ()
+{
+ char *sbcl_home = getenv("SBCL_HOME");
+ char *lookhere;
+ char *stem = "/sbcl.core";
+ char *core;
+
+ if (!(sbcl_home && *sbcl_home)) sbcl_home = SBCL_HOME;
+ lookhere = (char *) calloc(strlen(sbcl_home) +
+ strlen(stem) +
+ 1,
+ sizeof(char));
+ sprintf(lookhere, "%s%s", sbcl_home, stem);
+ core = copied_existing_filename_or_null(lookhere);
+
+ if (!core) {
+ lose("can't find core file at %s\n", lookhere);
+ }
+
+ free(lookhere);
+
+ 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 */
+
+size_t
+parse_size_arg(char *arg, char *arg_name)