Exemplo n.º 1
0
char *
_gst_relocate_path (const char *path)
{
  const char *p;
  char *s;

  /* Detect absolute paths.  */
#if defined(MSDOS) || defined(WIN32) || defined(__OS2__)
  if ((path[0] && path[1] == ':')
      || path[0] == '/' || path[0] == '\\')
    return xstrdup (path);
#else
  if (path[0] == '/')
    return xstrdup (path);
#endif

  /* Remove filename from executable path.  */
  p = _gst_executable_path + strlen (_gst_executable_path);
  do
    --p;
  while (p >= _gst_executable_path
         && *p != '/'
#if defined(MSDOS) || defined(WIN32) || defined(__OS2__)
	 && *p != '\\'
#endif
	);
  p++;

  /* Now p points just past the last separator (if any).  */
  s = alloca (p - _gst_executable_path + strlen (path) + 1);
  sprintf (s, "%.*s%s", (int)(p - _gst_executable_path), _gst_executable_path, path);
  return _gst_get_full_file_name (s);
}
Exemplo n.º 2
0
/* Store the full pathname of the current executable.  */
void
_gst_set_executable_path (const char *argv0)
{
  char location[MAX_PATH];
  static char location_as_posix_path[2 * MAX_PATH];
  int length = GetModuleFileName (NULL, location, sizeof (location));
  if (length <= 0)
    return NULL;

  /* On Cygwin, we need to convert paths coming from Win32 system calls
     to the Unix-like slashified notation.

     There's no error return defined for cygwin_conv_to_posix_path.
     See cygwin-api/func-cygwin-conv-to-posix-path.html.
     Does it overflow the buffer of expected size MAX_PATH or does it
     truncate the path?  I don't know.  Let's catch both.  */
  cygwin_conv_to_posix_path (location, location_as_posix_path);
  location_as_posix_path[MAX_PATH - 1] = '\0';
  if (strlen (location_as_posix_path) >= MAX_PATH - 1)
    /* A sign of buffer overflow or path truncation.  */
    _gst_executable_path = NULL;
  else
    _gst_executable_path = _gst_get_full_file_name (location_as_posix_path);
}
Exemplo n.º 3
0
int
_gst_initialize (const char *kernel_dir,
		 const char *image_file,
		 int flags)
{
  char *currentDirectory = _gst_get_cur_dir_name ();
  const char *home = getenv ("HOME");
  char *str;
  mst_Boolean loadBinary, abortOnFailure;
  int rebuild_image_flags =
    flags & (GST_REBUILD_IMAGE | GST_MAYBE_REBUILD_IMAGE);

  /* Even though we're nowhere near through initialization, we set this
     to make sure we don't invoke a callin function which would recursively
     invoke us.  */
  _gst_smalltalk_initialized = true;
  _gst_init_snprintfv ();

  if (!_gst_executable_path)
    _gst_executable_path = DEFAULT_EXECUTABLE;

  /* By default, apply this kludge fpr OSes such as Windows and MS-DOS
     which have no concept of home directories.  */
  if (home == NULL)
    home = xstrdup (currentDirectory);

  asprintf ((char **) &_gst_user_file_base_path, "%s/%s",
	    home, LOCAL_BASE_DIR_NAME);

  /* Check that supplied paths are readable.  If they're not, fail unless
     they told us in advance.  */
  if (kernel_dir
      && !_gst_file_is_readable (kernel_dir))
    {
      if (flags & GST_IGNORE_BAD_KERNEL_PATH)
	kernel_dir = NULL;
      else
	{
          _gst_errorf ("kernel path %s not readable", kernel_dir);
          exit (1);
	}
    }

  /* For the image file, it is okay to find none if we can/should rebuild
     the image file.  */
  if (image_file
      && (flags & (GST_REBUILD_IMAGE | GST_MAYBE_REBUILD_IMAGE)) == 0
      && !_gst_file_is_readable (image_file))
    {
      if (flags & GST_IGNORE_BAD_IMAGE_PATH)
	image_file = NULL;
      else
	{
	  _gst_errorf ("Couldn't open image file %s", image_file);
	  exit (1);
	}
    }

  /* The image path can be used as the default kernel path, so we split
     it anyway into directory+filename.  */
  if (image_file)
    {
      const char *p;
      /* Compute the actual path of the image file */
      p = image_file + strlen (image_file);
      for (;;)
	if (*--p == '/'
#if defined(MSDOS) || defined(WIN32) || defined(__OS2__)
	    || *p == '\\'
#endif
	   )
	  {
	    char *dirname;
	    int n = p > image_file ? p - image_file : 1;
	    asprintf (&dirname, "%.*s", n, image_file);
	    _gst_image_file_path = dirname;

	    /* Remove path from image_file.  */
	    image_file = p + 1;
	    break;
	  }

	else if (p == image_file)
	  {
	    _gst_image_file_path = ".";
	    break;
	  }
    }
  else
    {
      /* No image file given, we use the system default or revert to the
	 current directory.  */
      str = _gst_relocate_path (IMAGE_PATH);
      if (_gst_file_is_readable (str))
        _gst_image_file_path = str;
      else
	{
          free (str);
          _gst_image_file_path = xstrdup (currentDirectory);
	}

      flags |= GST_IGNORE_BAD_IMAGE_PATH;
      image_file = "gst.im";
    }

  if (!kernel_dir)
    {
      str = _gst_relocate_path (KERNEL_PATH);
      if (!_gst_file_is_readable (str))
	{
          free (str);
	  asprintf (&str, "%s/kernel", _gst_image_file_path);
	}

      kernel_dir = str;
    }

  xfree (currentDirectory);

  /* Uff, we're done with the complicated part.  Set variables to mirror
     what we've decided in the above marathon.  */
  _gst_image_file_path = _gst_get_full_file_name (_gst_image_file_path);
  _gst_kernel_file_path = _gst_get_full_file_name (kernel_dir);
  asprintf (&str, "%s/%s", _gst_image_file_path, image_file);
  _gst_binary_image_name = str;

  _gst_smalltalk_passed_argc = smalltalk_argc;
  _gst_smalltalk_passed_argv = smalltalk_argv;
  no_user_files = (flags & GST_IGNORE_USER_FILES) != 0;
  _gst_no_tty = (flags & GST_NO_TTY) != 0 || !isatty (0);

  site_pre_image_file = _gst_find_file (SITE_PRE_IMAGE_FILE_NAME,
					GST_DIR_KERNEL_SYSTEM);

  user_pre_image_file = find_user_file (USER_PRE_IMAGE_FILE_NAME);

  if (!_gst_regression_testing)
    user_init_file = find_user_file (USER_INIT_FILE_NAME);
  else
    user_init_file = NULL;

  _gst_init_sysdep ();
  _gst_init_signals ();
  _gst_init_event_loop();
  _gst_init_cfuncs ();
  _gst_init_sockets ();
  _gst_init_primitives ();

  if (_gst_regression_testing)
    {
      _gst_declare_tracing = 0;
      _gst_execution_tracing = 0;
      _gst_verbosity = 2;
      setvbuf (stdout, NULL, _IOLBF, 1024);
    }

  if (rebuild_image_flags == 0)
    loadBinary = abortOnFailure = true;
  else
    {
      loadBinary = (rebuild_image_flags == GST_MAYBE_REBUILD_IMAGE
		    && ok_to_load_binary ());
      abortOnFailure = false;

      /* If we must create a new non-local image, but the directory is
         not writeable, we must resort to the current directory.  In
         practice this is what happens when a "normal user" puts stuff in
	 his ".st" directory or does "gst -i".  */

      if (!loadBinary
          && !_gst_file_is_writeable (_gst_image_file_path)
	  && (flags & GST_IGNORE_BAD_IMAGE_PATH))
        {
          _gst_image_file_path = _gst_get_cur_dir_name ();
          asprintf (&str, "%s/gst.im", _gst_image_file_path);
	  _gst_binary_image_name = str;
          loadBinary = (rebuild_image_flags == GST_MAYBE_REBUILD_IMAGE
		        && ok_to_load_binary ());
        }
    }

  if (loadBinary && _gst_load_from_file (_gst_binary_image_name))
    {
      _gst_init_interpreter ();
      _gst_init_vmproxy ();
    }
  else if (abortOnFailure)
    {
      _gst_errorf ("Couldn't load image file %s", _gst_binary_image_name);
      return 1;
    }
  else
    {
      mst_Boolean willRegressTest = _gst_regression_testing;
      int result;

      _gst_regression_testing = false;
      _gst_init_oop_table (NULL, INITIAL_OOP_TABLE_SIZE);
      _gst_init_mem_default ();
      _gst_init_dictionary ();
      _gst_init_interpreter ();
      _gst_init_vmproxy ();

      _gst_install_initial_methods ();

      result = load_standard_files ();
      _gst_regression_testing = willRegressTest;
      if (result)
	return result;

      if (!_gst_save_to_file (_gst_binary_image_name))
	_gst_errorf ("Couldn't open file %s", _gst_binary_image_name);
    }

  _gst_kernel_initialized = true;
  _gst_invoke_hook (GST_RETURN_FROM_SNAPSHOT);
  if (user_init_file)
    _gst_process_file (user_init_file, GST_DIR_ABS);

#ifdef HAVE_READLINE
  _gst_initialize_readline ();
#endif /* HAVE_READLINE */

  return 0;
}