e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
df458c2004-12-30Henrik Grubbström (Grubba) || $Id: main.c,v 1.219 2004/12/30 13:40:19 grubba Exp $
e576bb2002-10-11Martin Nilsson */
aedfb12002-10-09Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
5740881998-01-01Fredrik Hübinette (Hubbe) #include "fdlib.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "backend.h" #include "module.h" #include "object.h" #include "lex.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h" #include "builtin_functions.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "array.h" #include "stralloc.h" #include "interpret.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "callback.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "signal_handler.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "threads.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "dynamic_load.h" #include "gc.h"
61e9a01998-01-25Fredrik Hübinette (Hubbe) #include "multiset.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "mapping.h"
5740881998-01-01Fredrik Hübinette (Hubbe) #include "cpp.h"
0808b21998-01-25Fredrik Hübinette (Hubbe) #include "main.h"
19aaeb1998-05-25Fredrik Hübinette (Hubbe) #include "operators.h"
ab56702001-04-30Martin Stjernholm #include "rbtree.h"
37775c2004-04-06Martin Nilsson #include "pike_security.h"
67f0b51999-09-26Henrik Grubbström (Grubba) #include "constants.h"
c37c7e1999-03-26Fredrik Hübinette (Hubbe) #include "version.h"
4b63c62001-12-14Martin Nilsson #include "program.h"
d5c61f2002-12-07Henrik Grubbström (Grubba) #include "pike_rusage.h"
d658ab2002-09-26Martin Stjernholm #include "module_support.h"
143d882003-11-14Martin Stjernholm #include "opcodes.h"
4b63c62001-12-14Martin Nilsson  #ifdef AUTO_BIGNUM #include "bignum.h" #endif
5740881998-01-01Fredrik Hübinette (Hubbe) 
ec337d2004-12-29Henrik Grubbström (Grubba) #include "pike_embed.h"
d1913b2000-10-01Fredrik Hübinette (Hubbe) #if defined(__linux__) && defined(HAVE_DLOPEN) && defined(HAVE_DLFCN_H)
07eda22000-07-05Fredrik Hübinette (Hubbe) #include <dlfcn.h> #endif
cee5811999-12-05Henrik Grubbström (Grubba) #include "las.h"
834e022003-11-28Henrik Grubbström (Grubba) #ifdef HAVE_UNISTD_H
fde6ed2003-11-27Martin Stjernholm #include <unistd.h>
834e022003-11-28Henrik Grubbström (Grubba) #endif #ifdef HAVE_ERRNO_H
ac173e1997-11-02Henrik Grubbström (Grubba) #include <errno.h>
834e022003-11-28Henrik Grubbström (Grubba) #endif
ac173e1997-11-02Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_LOCALE_H #include <locale.h> #endif
6930181996-02-25Fredrik Hübinette (Hubbe) 
6e37dc1996-06-21Fredrik Hübinette (Hubbe) #include "time_stuff.h"
6930181996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif
ff34a52001-05-31Henrik Grubbström (Grubba) /* Define this to trace the execution of main(). */ /* #define TRACE_MAIN */ #ifdef TRACE_MAIN #define TRACE(X) fprintf X #else /* !TRACE_MAIN */ #define TRACE(X) #endif /* TRACE_MAIN */
f8e5fe1997-01-18Henrik Grubbström (Grubba) 
df458c2004-12-30Henrik Grubbström (Grubba) /* * Code searching for master & libpike. */
3f1eeb1998-04-05Fredrik Hübinette (Hubbe) 
df458c2004-12-30Henrik Grubbström (Grubba) #define MASTER_COOKIE1 "(#*&)@(*&$" #define MASTER_COOKIE2 "Master Cookie:"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
df458c2004-12-30Henrik Grubbström (Grubba) #define MASTER_COOKIE MASTER_COOKIE1 MASTER_COOKIE2
5267b71995-08-09Fredrik Hübinette (Hubbe) 
df458c2004-12-30Henrik Grubbström (Grubba) #ifndef MAXPATHLEN #define MAXPATHLEN 32768 #endif static char master_location[MAXPATHLEN * 2] = MASTER_COOKIE; static void set_master(const char *file)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
df458c2004-12-30Henrik Grubbström (Grubba)  if (strlen(file) >= MAXPATHLEN*2 - CONSTANT_STRLEN(MASTER_COOKIE)) { fprintf(stderr, "Too long path to master: \"%s\" (limit:%d)\n", file, MAXPATHLEN*2 - CONSTANT_STRLEN(MASTER_COOKIE)); exit(1); } strcpy(master_location + CONSTANT_STRLEN(MASTER_COOKIE), file);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a999e71998-07-27Fredrik Hübinette (Hubbe) #ifdef __NT__
1c32fd2000-08-19Henrik Grubbström (Grubba) static void get_master_key(HKEY cat)
a999e71998-07-27Fredrik Hübinette (Hubbe) { HKEY k; char buffer[4096]; DWORD len=sizeof(buffer)-1,type=REG_SZ;
a5cd6a2001-09-24Henrik Grubbström (Grubba) 
a999e71998-07-27Fredrik Hübinette (Hubbe)  if(RegOpenKeyEx(cat,
387b042003-01-02Martin Nilsson  (LPCTSTR)("SOFTWARE\\Pike\\"
1f1f182001-03-10Henrik Grubbström (Grubba)  DEFINETOSTR(PIKE_MAJOR_VERSION) "."
a999e71998-07-27Fredrik Hübinette (Hubbe)  0,KEY_READ,&k)==ERROR_SUCCESS) { if(RegQueryValueEx(k, "PIKE_MASTER", 0, &type, buffer, &len)==ERROR_SUCCESS) {
df458c2004-12-30Henrik Grubbström (Grubba)  /* FIXME: Look at len? UNICODE? */ set_master(buffer);
a999e71998-07-27Fredrik Hübinette (Hubbe)  } RegCloseKey(k); } } #endif /* __NT__ */
df458c2004-12-30Henrik Grubbström (Grubba) static void set_default_master(void) { #ifdef HAVE_GETENV if(!master_location[CONSTANT_STRLEN(MASTER_COOKIE)] && getenv("PIKE_MASTER")) { set_master(getenv("PIKE_MASTER")); } #endif #ifdef __NT__ if(!master_location[CONSTANT_STRLEN(MASTER_COOKIE)]) get_master_key(HKEY_CURRENT_USER); if(!master_location[CONSTANT_STRLEN(MASTER_COOKIE)]) get_master_key(HKEY_LOCAL_MACHINE); #endif if(!master_location[CONSTANT_STRLEN(MASTER_COOKIE)]) { sprintf(master_location + CONSTANT_STRLEN(MASTER_COOKIE), DEFAULT_MASTER, PIKE_MAJOR_VERSION, PIKE_MINOR_VERSION, PIKE_BUILD_VERSION); } TRACE((stderr, "Default master at \"%s\"...\n", master_location + CONSTANT_STRLEN(MASTER_COOKIE))); } #ifdef LIBPIKE static char libpike_file[MAXPATHLEN * 2]; static void *libpike; static void (*init_pike)(const char **argv, const char *file); static void (*init_pike_runtime)(void (*exit_cb)(int)); #endif /* LIBPIKE */ static void find_lib_dir(int argc, char **argv) { int e; char *p; char *dir; TRACE((stderr, "find_lib_dir...\n")); set_default_master(); for(e=1; e<argc; e++) { TRACE((stderr, "Parse argument %d:\"%s\"...\n", e, argv[e])); if(argv[e][0] != '-') break; switch(argv[e][1]) { default: break; case 'm': if(argv[e][2]) { set_master(argv[e]+2); }else{ e++; if(e >= argc) { fprintf(stderr,"Missing argument to -m\n"); exit(1); } set_master(argv[e]); } break; case 's': if((!argv[e][2]) || ((argv[e][2] == 's') && !argv[e][3])) { e++; } break; case 'q': if(!argv[e][2]) e++; break; } } #ifdef LIBPIKE memcpy(libpike_file, master_location + CONSTANT_STRLEN(MASTER_COOKIE), sizeof(master_location) - CONSTANT_STRLEN(MASTER_COOKIE)); for (p = dir = libpike_file; *p; p++) { if ((*p == '/') #ifdef __NT__ || (*p == '\\') #endif /* __NT__ */ ) dir = p+1; } if ((p + CONSTANT_STRLEN("pike.so")) >= libpike_file + 2*MAXPATHLEN) { /* Not likely to happen as long as MASTER_COOKIE is longer than "pike.so". */ fprintf(stderr, "Too long path to pike.so.\n"); exit(1); } /* Don't forget the NUL! */ memcpy(p, "pike.so", CONSTANT_STRLEN("pike.so") + 1); #endif /* LIBPIKE */ } static long instructions_left; static void time_to_exit(struct callback *cb,void *tmp,void *ignored) { if(instructions_left-- < 0) { push_int(0); f_exit(1); } } static struct callback_list post_master_callbacks; PMOD_EXPORT struct callback *add_post_master_callback(callback_func call, void *arg, callback_func free_func) { return add_to_callback(&post_master_callbacks, call, arg, free_func); }
3189c92004-01-31Marcus Comstedt #ifdef __amigaos4__ #define timeval timeval_amigaos #include <exec/types.h> #include <utility/hooks.h> #include <dos/dosextens.h> #include <proto/dos.h> static SAVEDS LONG scan_amigaos_environment_func(struct Hook *REG(a0,hook), APTR REG(a2,userdata), struct ScanVarsMsg *REG(a1,msg)) { if(msg->sv_GDir[0] == '\0' || !strcmp(msg->sv_GDir, "ENV:")) { push_text(msg->sv_Name); push_constant_text("="); push_string(make_shared_binary_string(msg->sv_Var, msg->sv_VarLen)); f_add(3); } return 0; } static struct Hook scan_amigaos_environment_hook = { { NULL, NULL }, (ULONG (*)())scan_amigaos_environment_func, NULL, NULL }; #endif /* __amigsos4__ */
df458c2004-12-30Henrik Grubbström (Grubba) int main(int argc, char **argv)
ec337d2004-12-29Henrik Grubbström (Grubba) { JMP_BUF back; int e, num;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *p;
ec337d2004-12-29Henrik Grubbström (Grubba)  struct array *a;
85f59e1998-01-08Fredrik Hübinette (Hubbe) #ifdef DECLARE_ENVIRON extern char **environ; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
df458c2004-12-30Henrik Grubbström (Grubba)  TRACE((stderr, "Init master...\n")); find_lib_dir(argc, argv);
cee5811999-12-05Henrik Grubbström (Grubba) 
df458c2004-12-30Henrik Grubbström (Grubba) #ifdef LIBPIKE if (!dlinit()) { fprintf(stderr, "dlinit failed.\n"); exit(1); }
bf47e12000-04-06Henrik Grubbström (Grubba) 
df458c2004-12-30Henrik Grubbström (Grubba)  if (!(libpike = dlopen(libpike_name, RTLD_NOW))) { const char *err = dlerror(); if (!err) err = "Unknown reason."; fprintf(stderr, "Failed to open %s: %s\n", libpike_name, err); exit(1); } #define LOOKUP(symbol) do { \ if (!(symbol = CAST_TO_FUN(dlsym(libpike, TOSTR(symbol)))) && \ !(symbol = CAST_TO_FUN(dlsym(libpike, "_" TOSTR(symbol))))) { \ fprintf(stderr, "Missing symbol in %s: " TOSTR(symbol) "\n", \ libpike_name); \ dlclose(libpike); \ exit(1); \ } \ } while(0) LOOKUP(init_pike); LOOKUP(init_pike_runtime); LOOKUP(add_predefine);
ff34a52001-05-31Henrik Grubbström (Grubba) 
df458c2004-12-30Henrik Grubbström (Grubba) #endif /* LIBPIKE */ TRACE((stderr, "init_pike()\n")); init_pike(argv, master_location + CONSTANT_STRLEN(MASTER_COOKIE));
895ced2003-10-25Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=1; e<argc; e++) {
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Parse argument %d:\"%s\"...\n", e, argv[e]));
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(argv[e][0]=='-') { for(p=argv[e]+1; *p;) { switch(*p) { case 'D': add_predefine(p+1); p+=strlen(p); break; case 'm': if(p[1]) { p+=strlen(p); }else{ e++; if(e >= argc) { fprintf(stderr,"Missing argument to -m\n"); exit(1); } p+=strlen(p); } break;
9f243b1996-08-12Fredrik Hübinette (Hubbe)  case 's': if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -s\n"); exit(1); } p=argv[e];
4908871998-08-10Fredrik Hübinette (Hubbe)  }else{ p++; if(*p=='s') { if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -ss\n"); exit(1); } p=argv[e]; }else{ p++; } #ifdef _REENTRANT thread_stack_size=STRTOL(p,&p,0); #endif p+=strlen(p); break; }
9f243b1996-08-12Fredrik Hübinette (Hubbe)  }
7965d72001-01-24Fredrik Hübinette (Hubbe)  Pike_stack_size=STRTOL(p,&p,0);
9f243b1996-08-12Fredrik Hübinette (Hubbe)  p+=strlen(p);
7965d72001-01-24Fredrik Hübinette (Hubbe)  if(Pike_stack_size < 256)
9f243b1996-08-12Fredrik Hübinette (Hubbe)  { fprintf(stderr,"Stack size must at least be 256.\n"); exit(1); } break;
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  case 'q': if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -q\n"); exit(1); } p=argv[e];
4908871998-08-10Fredrik Hübinette (Hubbe)  }else{ p++;
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  }
4908871998-08-10Fredrik Hübinette (Hubbe)  instructions_left=STRTOL(p,&p,0);
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  p+=strlen(p); add_to_callback(&evaluator_callbacks, time_to_exit, 0,0); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case 'd':
cd83521998-02-02Fredrik Hübinette (Hubbe)  more_d_flags: switch(p[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': d_flag+=STRTOL(p+1,&p,10); break;
943f851998-04-13Henrik Grubbström (Grubba)  case 'c': p++;
ff34a52001-05-31Henrik Grubbström (Grubba) #if defined(YYDEBUG) || defined(PIKE_DEBUG)
943f851998-04-13Henrik Grubbström (Grubba)  yydebug++;
ff34a52001-05-31Henrik Grubbström (Grubba) #endif /* YYDEBUG || PIKE_DEBUG */
943f851998-04-13Henrik Grubbström (Grubba)  break;
cd83521998-02-02Fredrik Hübinette (Hubbe)  case 's':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_debug_options(DEBUG_SIGNALS, DEBUG_SIGNALS);
cd83521998-02-02Fredrik Hübinette (Hubbe)  p++;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  goto more_d_flags; case 't':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_debug_options(NO_TAILRECURSION, NO_TAILRECURSION);
cd83521998-02-02Fredrik Hübinette (Hubbe)  p++;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  goto more_d_flags;
cd83521998-02-02Fredrik Hübinette (Hubbe) 
7386972001-06-30Fredrik Hübinette (Hubbe)  case 'g':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_debug_options(GC_RESET_DMALLOC, GC_RESET_DMALLOC);
7386972001-06-30Fredrik Hübinette (Hubbe)  p++; goto more_d_flags; case 'p':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_debug_options(NO_PEEP_OPTIMIZING, NO_PEEP_OPTIMIZING);
7386972001-06-30Fredrik Hübinette (Hubbe)  p++; goto more_d_flags;
01185d2003-04-01Martin Stjernholm  case 'T':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_debug_options(ERRORCHECK_MUTEXES, ERRORCHECK_MUTEXES);
01185d2003-04-01Martin Stjernholm  p++; goto more_d_flags;
7d955e1999-12-13Henrik Grubbström (Grubba)  default: d_flag += (p[0] == 'd');
cee5811999-12-05Henrik Grubbström (Grubba)  p++;
7d955e1999-12-13Henrik Grubbström (Grubba)  } break;
cee5811999-12-05Henrik Grubbström (Grubba) 
7d955e1999-12-13Henrik Grubbström (Grubba)  case 'r':
17e1771999-12-13Per Hedbor  more_r_flags: switch(p[1]) {
7d955e1999-12-13Henrik Grubbström (Grubba)  case 't':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_runtime_options(RUNTIME_CHECK_TYPES, RUNTIME_CHECK_TYPES);
7d955e1999-12-13Henrik Grubbström (Grubba)  p++;
17e1771999-12-13Per Hedbor  goto more_r_flags;
7d955e1999-12-13Henrik Grubbström (Grubba)  case 'T':
df458c2004-12-30Henrik Grubbström (Grubba)  set_pike_runtime_options(RUNTIME_STRICT_TYPES, RUNTIME_STRICT_TYPES);
7d955e1999-12-13Henrik Grubbström (Grubba)  p++;
17e1771999-12-13Per Hedbor  goto more_r_flags;
7d955e1999-12-13Henrik Grubbström (Grubba) 
17e1771999-12-13Per Hedbor  default: p++;
7d955e1999-12-13Henrik Grubbström (Grubba)  break;
cd83521998-02-02Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case 'a': if(p[1]>='0' && p[1]<='9') a_flag+=STRTOL(p+1,&p,10); else a_flag++,p++; break; case 't':
24d38f2004-03-17Martin Stjernholm  more_t_flags: switch (p[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': Pike_interpreter.trace_level+=STRTOL(p+1,&p,10); break; case 'g': gc_trace++; p++; goto more_t_flags; default: if (p[0] == 't') Pike_interpreter.trace_level++; p++; }
97ebb32003-01-09Henrik Grubbström (Grubba)  default_t_flag = Pike_interpreter.trace_level;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case 'p':
0612442001-05-16Fredrik Hübinette (Hubbe)  if(p[1]=='s') {
ec337d2004-12-29Henrik Grubbström (Grubba)  pike_enable_stack_profiling();
0612442001-05-16Fredrik Hübinette (Hubbe)  p+=strlen(p); }else{ if(p[1]>='0' && p[1]<='9') p_flag+=STRTOL(p+1,&p,10); else p_flag++,p++; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case 'l': if(p[1]>='0' && p[1]<='9') l_flag+=STRTOL(p+1,&p,10); else l_flag++,p++; break; default:
4967071997-01-15Fredrik Hübinette (Hubbe)  p+=strlen(p);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } }else{ break; } }
01185d2003-04-01Martin Stjernholm #ifndef PIKE_MUTEX_ERRORCHECK if (debug_options & ERRORCHECK_MUTEXES) fputs ("Warning: -dT (error checking mutexes) not supported on this system.\n", stderr); #endif if (d_flag) debug_options |= ERRORCHECK_MUTEXES;
ec337d2004-12-29Henrik Grubbström (Grubba)  init_pike_runtime(exit);
a9388a1998-09-02Henrik Grubbström (Grubba) 
df458c2004-12-30Henrik Grubbström (Grubba)  /* NOTE: Reuse master_location here to avoid duplicates of * the MASTER_COOKIE string in the binary. */ add_pike_string_constant("__master_cookie", master_location, CONSTANT_STRLEN(MASTER_COOKIE));
ec337d2004-12-29Henrik Grubbström (Grubba)  if(SETJMP(back))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
ec337d2004-12-29Henrik Grubbström (Grubba)  if(throw_severity == THROW_EXIT)
61e9a01998-01-25Fredrik Hübinette (Hubbe)  { num=throw_value.u.integer; }else{
667ec22003-07-22Martin Stjernholm  if (throw_value.type == T_OBJECT && throw_value.u.object->prog == master_load_error_program && !get_master()) { /* Report this specific error in a nice way. Since there's no * master it'd be reported with a raw error dump otherwise. */ struct generic_error_struct *err;
e8cbe42004-07-04Martin Nilsson  dynamic_buffer buf; dynbuf_string s; struct svalue t;
667ec22003-07-22Martin Stjernholm  *(Pike_sp++) = throw_value; dmalloc_touch_svalue(Pike_sp-1); throw_value.type=T_INT; err = (struct generic_error_struct *) get_storage (Pike_sp[-1].u.object, generic_error_program);
e8cbe42004-07-04Martin Nilsson  t.type = PIKE_T_STRING; t.u.string = err->error_message; init_buf(&buf); describe_svalue(&t,0,0); s=complex_free_buf(&buf);
9f6bfe2004-07-04Stephen R. van den Berg  fputs(s.str, stderr);
e8cbe42004-07-04Martin Nilsson  free(s.str);
667ec22003-07-22Martin Stjernholm  } else call_handle_error();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  num=10; }
ec337d2004-12-29Henrik Grubbström (Grubba)  }else{ back.severity=THROW_EXIT; TRACE((stderr, "Init master...\n")); master(); call_callback(& post_master_callbacks, 0); free_callback_list(& post_master_callbacks);
09126b2001-12-19Martin Stjernholm  TRACE((stderr, "Call master->_main()...\n"));
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  a=allocate_array_no_init(argc,0); for(num=0;num<argc;num++) { ITEM(a)[num].u.string=make_shared_string(argv[num]); ITEM(a)[num].type=T_STRING; }
2523ce2003-04-28Martin Stjernholm  a->type_field = BIT_STRING;
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  push_array(a);
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
092e542003-12-17Marcus Comstedt #ifdef __amigaos__
3189c92004-01-31Marcus Comstedt #ifdef __amigaos4__
52ce1d2004-09-26Marcus Comstedt  if(DOSBase->lib_Version >= 50) {
3189c92004-01-31Marcus Comstedt  struct svalue *mark = Pike_sp; IDOS->ScanVars(&scan_amigaos_environment_hook, GVF_BINARY_VAR|GVF_DONT_NULL_TERM, NULL); f_aggregate(Pike_sp-mark); } else #endif push_array(allocate_array_no_init(0,0));
092e542003-12-17Marcus Comstedt #else
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  for(num=0;environ[num];num++); a=allocate_array_no_init(num,0); for(num=0;environ[num];num++) { ITEM(a)[num].u.string=make_shared_string(environ[num]); ITEM(a)[num].type=T_STRING; }
2523ce2003-04-28Martin Stjernholm  a->type_field = BIT_STRING;
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  push_array(a);
092e542003-12-17Marcus Comstedt #endif
fe5eb01998-01-31Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  apply(master(),"_main",2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  num=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } UNSETJMP(back);
cfd36c2003-11-14Martin Stjernholm  TRACE((stderr, "Exit %d...\n", num));
ec337d2004-12-29Henrik Grubbström (Grubba) 
eb2fd52000-11-06Henrik Grubbström (Grubba)  pike_do_exit(num);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  return num; /* avoid warning */
61e9a01998-01-25Fredrik Hübinette (Hubbe) }
378b2d1997-02-06Fredrik Hübinette (Hubbe) void exit_main(void)
156fd51997-10-27Fredrik Hübinette (Hubbe) {
b5c00b2003-03-30Martin Stjernholm #ifdef DO_PIKE_CLEANUP
75c0252004-03-16Martin Stjernholm  size_t count;
31a8682004-09-27Martin Stjernholm  if (exit_with_cleanup) { /* Destruct all remaining objects while we have a proper execution * environment. The downside is that the leak report below will * always report destructed objects. We use the gc in a special mode * for this to get a reasonably sane destruct order. */ gc_destruct_everything = 1; count = do_gc (NULL, 1); while (count) { size_t new_count = do_gc (NULL, 1); if (new_count >= count) { fprintf (stderr, "Some destroy function is creating new objects " "during final cleanup - can't exit cleanly.\n"); break; } count = new_count;
75c0252004-03-16Martin Stjernholm  }
31a8682004-09-27Martin Stjernholm  gc_destruct_everything = 0;
75c0252004-03-16Martin Stjernholm  }
826bd72003-04-02Martin Stjernholm  /* Unload dynamic modules before static ones. */ exit_dynamic_load();
b5c00b2003-03-30Martin Stjernholm #endif
156fd51997-10-27Fredrik Hübinette (Hubbe) } void init_main(void) { }