#include "ikarus-data.h" #include #include #include #include #include #include #include #include #include #include void register_handlers(); void register_alt_stack(); void ikarus_usage_short(){ fprintf(stderr, "ikarus -h for more help\n"); } void ikarus_usage(){ static char* helpstring = "\n\ Options for running ikarus scheme:\n\ \n ikarus -h\n\ Prints this help message then exits.\n\ \n ikarus [-b ] --r6r-script opts ...\n\ Starts ikarus in r6rs-script mode. The script file is treated\n\ as an R6RS-script. The options opts ... can be obtained using\n\ the \"command-line\" procedure in the (rnrs programs) library.\n\ \n ikarus [-b ] ... [-- opts ...]\n\ Starts ikarus in interactive mode. Each of the files is first\n\ loaded into the interaction environment before the interactive\n\ repl is started. The options opts can be obtained using the\n\ \"command-line\" procedure.\n\ \n\ If the option [-b ] is provided, the bootfile is used\n\ as the system's initial boot file from which the environment is\n\ initialized. If the -b option is not supplied, the default boot\n\ file (ikarus.boot if the executable name is ikarus) is used based\n\ on where the executable file is located in the PATH. If ikarus\n\ was invoked using a path (e.g. ./ikarus or /bin/ikarus), then the\n\ PATH is not searched, instead, the path to the executable is used\n\ to locate the boot file (e.g. ./ikarus.boot or /bin/ikarus.boot).\n\ Consult the ikarus manual for more details.\n\n"; fprintf(stderr, helpstring); } ikpcb* the_pcb; /* get_option takes pointers to argc and argv and looks for the first option matching opt. If one exists, it removes it from the argv list, updates argc, and returns a pointer to the option value. returns null if option is not found. */ char* get_option(char* opt, int argc, char** argv){ int i; for(i=1; i 0){ char* s = argv[i]; int n = strlen(s); ikp str = ik_alloc(pcb, align(n*string_char_size+disp_string_data+1)) + string_tag; ref(str, off_string_length) = fix(n); { int i; for(i=0; iarg_list = arg_list; } register_handlers(); register_alt_stack(); ik_fasl_load(pcb, boot_file); /* fprintf(stderr, "collect time: %d.%03d utime, %d.%03d stime (%d collections)\n", pcb->collect_utime.tv_sec, pcb->collect_utime.tv_usec/1000, pcb->collect_stime.tv_sec, pcb->collect_stime.tv_usec/1000, pcb->collection_id ); */ ik_delete_pcb(pcb); return 0; } #if 0 Notice how the bsd manpages have incorrect type for the handler. #include struct sigaction { union { void (*__sa_handler)(int); void (*__sa_sigaction)(int, struct __siginfo *, void *); } __sigaction_u; /* signal handler */ int sa_flags; /* see signal options below */ sigset_t sa_mask; /* signal mask to apply */ }; #define sa_handler __sigaction_u.__sa_handler #define sa_sigaction __sigaction_u.__sa_sigaction int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * restrict oact); #endif void handler(int signo, siginfo_t* info, void* uap){ the_pcb->engine_counter = -1; the_pcb->interrupted = 1; } void register_handlers(){ struct sigaction sa; sa.sa_sigaction = handler; #ifdef __CYGWIN__ sa.sa_flags = SA_SIGINFO; #else sa.sa_flags = SA_SIGINFO | SA_ONSTACK; #endif sigemptyset(&sa.sa_mask); int err = sigaction(SIGINT, &sa, 0); if(err){ fprintf(stderr, "Sigaction Failed: %s\n", strerror(errno)); exit(-1); } } #if 0 SYNOPSIS #include #include struct sigaltstack { char *ss_sp; int ss_size; int ss_flags; }; int sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss); #endif void register_alt_stack(){ #ifndef __CYGWIN__ char* stk = mmap(0, SIGSTKSZ, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON, -1, 0); // char* stk = ik_mmap(SIGSTKSZ); if(stk == (char*)-1){ fprintf(stderr, "Cannot maloc an alt stack\n"); exit(-1); } struct sigaltstack sa; sa.ss_sp = stk; sa.ss_size = SIGSTKSZ; sa.ss_flags = 0; int err = sigaltstack(&sa, 0); if(err){ fprintf(stderr, "Cannot set alt stack: %s\n", strerror(errno)); exit(-1); } #endif }