pike.git / src / main.c

version» Context lines:

pike.git/src/main.c:1:   /*   || 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.   */      #include "global.h"   #include "fdlib.h"   #include "backend.h" - #include "module.h" +    #include "object.h"   #include "lex.h"   #include "pike_types.h"   #include "builtin_functions.h"   #include "array.h"   #include "stralloc.h"   #include "interpret.h"   #include "pike_error.h"   #include "pike_macros.h"   #include "callback.h"   #include "signal_handler.h"   #include "threads.h"   #include "dynamic_load.h"   #include "gc.h"   #include "multiset.h"   #include "mapping.h"   #include "cpp.h"   #include "main.h"   #include "operators.h"   #include "rbtree.h" - #include "pike_security.h" +    #include "constants.h"   #include "version.h"   #include "program.h"   #include "pike_rusage.h"   #include "module_support.h"   #include "opcodes.h" - #include "bignum.h" + #include "buffer.h"      #include "pike_embed.h"      #ifdef LIBPIKE   #if defined(HAVE_DLOPEN) && defined(HAVE_DLFCN_H)   #include <dlfcn.h>   #undef LIBPIKE   #endif   #endif      #include "las.h"      #ifdef HAVE_UNISTD_H   #include <unistd.h>   #endif - #ifdef HAVE_ERRNO_H - #include <errno.h> - #endif +     - #ifdef HAVE_LOCALE_H + #include <errno.h>   #include <locale.h> - #endif +       #include "time_stuff.h"      #ifdef HAVE_SYS_RESOURCE_H   #include <sys/resource.h>   #endif      /* Define this to trace the execution of main(). */   /* #define TRACE_MAIN */      #ifdef PIKE_EXTRA_DEBUG   #define TRACE_MAIN   #endif /* PIKE_EXTRA_DEBUG */      #ifdef TRACE_MAIN - #define TRACE(X) fprintf X + #define TRACE(...) fprintf(stderr, __VA_ARGS__)   #else /* !TRACE_MAIN */ - #define TRACE(X) + #define TRACE(...)   #endif /* TRACE_MAIN */      /*    * Code searching for master & libpike.    */      #define MASTER_COOKIE1 "(#*&)@(*&$"   #define MASTER_COOKIE2 "Master Cookie:"      #define MASTER_COOKIE MASTER_COOKIE1 MASTER_COOKIE2      #ifndef MAXPATHLEN   #define MAXPATHLEN 32768   #endif    - static char master_location[MAXPATHLEN * 2] = MASTER_COOKIE; + static const char _master_location[MAXPATHLEN+CONSTANT_STRLEN(MASTER_COOKIE)] = MASTER_COOKIE; + static const char *master_file_location = _master_location + CONSTANT_STRLEN(MASTER_COOKIE);      static void set_master(const char *file)   { -  if (strlen(file) >= MAXPATHLEN*2 - CONSTANT_STRLEN(MASTER_COOKIE)) { -  fprintf(stderr, "Too long path to master: \"%s\" (limit:%"PRINTPTRDIFFT"d)\n", -  file, MAXPATHLEN*2 - CONSTANT_STRLEN(MASTER_COOKIE)); -  exit(1); +  if( master_file_location != _master_location+CONSTANT_STRLEN(MASTER_COOKIE)) +  free((void*)master_file_location); + #ifdef DEBUG_MALLOC + #undef strdup /* We can't use dmalloc strdup before pike_memory is initialized. */ + #endif /* DEBUG_MALLOC */ + #if defined(__NT__) && !defined(strdup) +  /* strdup() is broken on WIN32, but _strdup() isn't... */ + #define strdup _strdup + #endif /* __NT__ */ +  master_file_location = strdup( file );   } -  strcpy(master_location + CONSTANT_STRLEN(MASTER_COOKIE), file); - } +       #ifdef __NT__   static void get_master_key(HKEY cat)   {    HKEY k;    char buffer[4096];    DWORD len=sizeof(buffer)-1,type=REG_SZ;       if(RegOpenKeyEx(cat,    (LPCTSTR)("SOFTWARE\\Pike\\"
pike.git/src/main.c:129: Inside #if defined(__NT__)
   /* FIXME: Look at len? UNICODE? */    set_master(buffer);    }    RegCloseKey(k);    }   }   #endif /* __NT__ */      static void set_default_master(const char *bin_name)   { -  char *mp = master_location + CONSTANT_STRLEN (MASTER_COOKIE); -  - #ifdef HAVE_GETENV -  if(!*mp && getenv("PIKE_MASTER")) { + #define mp master_file_location +  if(getenv("PIKE_MASTER")) {    set_master(getenv("PIKE_MASTER"));    } - #endif +       #ifdef __NT__    if(!*mp) get_master_key(HKEY_CURRENT_USER);    if(!*mp) get_master_key(HKEY_LOCAL_MACHINE);   #endif       if(!*mp && strncmp(DEFAULT_MASTER, "NONE/", 5))    { -  SNPRINTF (mp, sizeof (master_location) - CONSTANT_STRLEN (MASTER_COOKIE), +  char tmp[CONSTANT_STRLEN( DEFAULT_MASTER ) + 10 + 10 + 10]; +  snprintf (tmp, sizeof(tmp)-1,    DEFAULT_MASTER,    PIKE_MAJOR_VERSION,    PIKE_MINOR_VERSION,    PIKE_BUILD_VERSION); -  +  set_master( tmp );    }      #ifdef __NT__    if (!(*mp == '/' || *mp == '\\' || (isalpha (*mp) && mp[1] == ':'))) {    char exepath[MAXPATHLEN];    if (!GetModuleFileName (NULL, exepath, _MAX_PATH))    fprintf (stderr, "Failed to get path to exe file: %d\n",    GetLastError());    else {    char tmp[MAXPATHLEN * 2];    char *p = strrchr (exepath, '\\');    if (p) *p = 0; -  SNPRINTF (tmp, sizeof (tmp), "%s/%s", exepath, mp); -  strncpy (mp, tmp, -  sizeof (master_location) - CONSTANT_STRLEN (MASTER_COOKIE)); +  snprintf (tmp, sizeof (tmp), "%s/%s", exepath, mp); +  set_master( tmp );    }    }   #else    if (!*mp) {    /* Attempt to find a master via the path to the binary. */    /* Note: We assume that MAXPATHLEN is > 18 characters. */ -  if (strlen(bin_name) < (2*MAXPATHLEN - -  CONSTANT_STRLEN(MASTER_COOKIE "master.pike"))) { +  if (strlen(bin_name) + CONSTANT_STRLEN("master.pike") < MAXPATHLEN) { +  char tmp[MAXPATHLEN];    char *p; -  strcpy(mp, bin_name); -  p = strrchr(mp, '/'); -  if (!p) p = mp; +  strcpy(tmp, bin_name); +  p = strrchr(tmp, '/'); +  if (!p) p = tmp;    else p++;    strcpy(p, "master.pike"); -  +  set_master( tmp );    }    }   #endif    -  TRACE((stderr, "Default master at \"%s\"...\n", mp)); +  TRACE("Default master at \"%s\"...\n", mp); + #undef mp   }      #ifdef LIBPIKE   static char libpike_file[MAXPATHLEN * 2];   static void *libpike;      typedef void (*modfun)(void);   #ifdef NO_CAST_TO_FUN   /* Function pointers can't be casted to scalar pointers according to    * ISO-C (probably to support true Harward achitecture machines).
pike.git/src/main.c:216:      static void (*init_pike_var)(const char **argv, const char *file);   static void (*init_pike_runtime_var)(void (*exit_cb)(int));   static void (*add_predefine_var)(char *s);   #endif /* LIBPIKE */      static void find_lib_dir(int argc, char **argv)   {    int e;    -  TRACE((stderr, "find_lib_dir...\n")); +  TRACE("find_lib_dir...\n");       set_default_master(argv[0]);       for(e=1; e<argc; e++)    { -  TRACE((stderr, "Parse argument %d:\"%s\"...\n", e, argv[e])); +  TRACE("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])
pike.git/src/main.c:263:    case 'q':    if(!argv[e][2]) e++;    break;    }    }      #ifdef LIBPIKE    {    char *p;    char *dir; -  memcpy(libpike_file, master_location + CONSTANT_STRLEN(MASTER_COOKIE), -  sizeof(master_location) - CONSTANT_STRLEN(MASTER_COOKIE)); +  strcpy(libpike_file, master_file_location);    for (p = dir = libpike_file; *p; p++) {    if ((*p == '/')   #ifdef __NT__    || (*p == '\\')   #endif /* __NT__ */    )    dir = p+1;    }    if ((dir + CONSTANT_STRLEN("pike.so")) >= libpike_file + 2*MAXPATHLEN) {    /* Not likely to happen as long as MASTER_COOKIE is longer than "pike.so".
pike.git/src/main.c:290: Inside #if defined(LIBPIKE)
   memcpy(dir, "pike.so", CONSTANT_STRLEN("pike.so") + 1);    }   #endif /* LIBPIKE */   }      int main(int argc, char **argv)   {    JMP_BUF back;    int e, num;    char *p; -  +    #ifdef PIKE_EXTRA_DEBUG - #ifdef HAVE_SIGNAL +     if (sizeof(void *) == 8) {    /* 64-bit Solaris 10 in Xenofarm fails with SIGPIPE.    * Force a core dump.    */    signal(SIGPIPE, abort);    }   #endif - #endif +       #ifdef HAVE_MALLOPT -  TRACE((stderr, "Init malloc...\n")); +  TRACE("Init malloc...\n");       /* The malloc implementation in recent glibc (eg Linux)    * defaults to using one arena / thread. This means that    * memory once allocated from one thread can't later be    * allocated by another thread.    *    * cf [bug 6045] and http://sourceware.org/bugzilla/show_bug.cgi?id=11261    *    * We try to alleviate the problem by reducing the number    * of arenas as much as possible.
pike.git/src/main.c:326: Inside #if defined(HAVE_MALLOPT) and #if defined(M_ARENA_TEST)
  #ifdef M_ARENA_TEST    /* NB: Some versions of glibc don't support setting M_ARENA_TEST to 0. */    /* Note also that the test is inverted since mallopt returns 0 on success. */    mallopt(M_ARENA_TEST, 0) && mallopt(M_ARENA_TEST, 1);   #endif   #ifdef M_ARENA_MAX    mallopt(M_ARENA_MAX, 1);   #endif   #endif /* HAVE_MALLOPT */    -  TRACE((stderr, "Init master...\n")); +  TRACE("Init master...\n");       find_lib_dir(argc, argv);      #ifdef LIBPIKE   #ifdef HAVE_DLINIT    if (!dlinit()) {    fprintf(stderr, "dlinit failed.\n");    exit(1);    }   #endif /* HAVE_DLINIT */
pike.git/src/main.c:366:       LOOKUP(init_pike);   #define init_pike init_pike_var    LOOKUP(init_pike_runtime);   #define init_pike_runtime init_pike_runtime_var    LOOKUP(add_predefine);   #define add_predefine add_predefine_var      #endif /* LIBPIKE */    -  TRACE((stderr, "init_pike()\n")); +  TRACE("init_pike()\n");    -  init_pike(argv, master_location + CONSTANT_STRLEN(MASTER_COOKIE)); +  init_pike(argv, master_file_location);       for(e=1; e<argc; e++)    { -  TRACE((stderr, "Parse argument %d:\"%s\"...\n", e, argv[e])); +  TRACE("Parse argument %d:\"%s\"...\n", e, argv[e]);       if(argv[e][0]=='-')    {    for(p=argv[e]+1; *p;)    {    switch(*p)    {    case 'D':    add_predefine(p+1);    p+=strlen(p);
pike.git/src/main.c:427:    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); +  thread_stack_size=strtol(p,&p,0);   #endif    p+=strlen(p);    break;    }    } -  Pike_stack_size=STRTOL(p,&p,0); +  Pike_stack_size=strtol(p,&p,0);    p+=strlen(p);       if(Pike_stack_size < 256)    {    fprintf(stderr,"Stack size must at least be 256.\n");    exit(1);    }    break;       case 'q':
pike.git/src/main.c:456:    e++;    if(e >= argc)    {    fprintf(stderr,"Missing argument to -q\n");    exit(1);    }    p=argv[e];    }else{    p++;    } -  set_pike_evaluator_limit(STRTOL(p, &p, 0)); +  set_pike_evaluator_limit(strtol(p, &p, 0));    p+=strlen(p);    break;       case 'd':    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); +  d_flag+=strtol(p+1,&p,10);    break;       case 'c':    p++;   #if (defined(YYDEBUG) && (YYDEBUG==1)) && defined(PIKE_DEBUG)    yydebug++;   #endif /* YYDEBUG && PIKE_DEBUG */    break;       case 's':
pike.git/src/main.c:536:    goto more_r_flags;       default:    p++;    break;    }    break;       case 'a':    if(p[1]>='0' && p[1]<='9') -  a_flag+=STRTOL(p+1,&p,10); +  a_flag+=strtol(p+1,&p,10);    else    a_flag++,p++;    break;       case 't':    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); +  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++;
pike.git/src/main.c:569:    default_t_flag = Pike_interpreter.trace_level;    break;       case 'p':    if(p[1]=='s')    {    pike_enable_stack_profiling();    p+=strlen(p);    }else{    if(p[1]>='0' && p[1]<='9') -  p_flag+=STRTOL(p+1,&p,10); +  p_flag+=strtol(p+1,&p,10);    else    p_flag++,p++;    }    break;       case 'l':    if(p[1]>='0' && p[1]<='9') -  l_flag+=STRTOL(p+1,&p,10); +  l_flag+=strtol(p+1,&p,10);    else    l_flag++,p++;    break;       default:    p+=strlen(p);    }    }    }else{    break;
pike.git/src/main.c:623: Inside #if defined(HAVE_SETERRORMODE)
   SetErrorMode (0));    }   #endif       init_pike_runtime(exit);       /* 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)); +  _master_location, CONSTANT_STRLEN(MASTER_COOKIE));       if(SETJMP(back))    {    if(throw_severity == THROW_EXIT || throw_severity == THROW_THREAD_EXIT)    {    num=throw_value.u.integer;    }else{    if (TYPEOF(throw_value) == 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;    -  dynamic_buffer buf; -  dynbuf_string s; +  struct byte_buffer buf = BUFFER_INIT();    struct svalue t;       move_svalue (Pike_sp++, &throw_value);    mark_free_svalue (&throw_value); -  err = (struct generic_error_struct *) +  err =    get_storage (Pike_sp[-1].u.object, generic_error_program);       SET_SVAL(t, PIKE_T_STRING, 0, string, err->error_message);    -  init_buf(&buf); -  describe_svalue(&t,0,0); -  s=complex_free_buf(&buf); -  -  fputs(s.str, stderr); -  free(s.str); +  describe_svalue(&buf, &t,0,0); +  fputs(buffer_get_string(&buf), stderr); +  buffer_free(&buf);    }    else    call_handle_error();    num=10;    }    }else{    struct object *m;       back.severity=THROW_EXIT;       if ((m = load_pike_master())) { -  TRACE((stderr, "Call master->_main()...\n")); +  TRACE("Call master->_main()...\n");       pike_push_argv(argc, argv);       apply(m, "_main", 1);    pop_stack();    num=0;    } else {    num = -1;    }    }    UNSETJMP(back);    -  TRACE((stderr, "Exit %d...\n", num)); +  TRACE("Exit %d...\n", num);       pike_do_exit(num);    return num; /* avoid warning */   }