Beispiel #1
0
/* Note: VMS filenames also contain version numbers.  The caller will have
 * to deal with that.
 *
 * The extension includes the '.'.  If no extension is present, "" is returned.
 */
char *SLpath_extname (SLFUTURE_CONST char *file)
{
   char *b;

   if (NULL == (file = SLpath_basename (file)))
     return NULL;

   b = (char *) file + strlen (file);
   while (b != file)
     {
	b--;
	if (*b == '.')
	  return b;
     }

   if (*b == '.')
     return b;

   /* Do not return a literal "" */
   return (char *) file + strlen (file);
}
Beispiel #2
0
static void path_basename (char *path)
{
   (void) SLang_push_string (SLpath_basename (path));
}
Beispiel #3
0
static Handle_Type *dynamic_link_module (SLFUTURE_CONST char *module)
{
   Handle_Type *h;
   VOID_STAR handle;
   SLFUTURE_CONST char *err;
   char filebuf[1024];
   char *save_file;
   char *save_err;
   int api_version;
   int *api_version_ptr;
#define MAX_MODULE_NAME_SIZE 256
   char module_so[MAX_MODULE_NAME_SIZE + 32];
   char *module_name;
   char *file, *pathfile;

   if (strlen (module) >= MAX_MODULE_NAME_SIZE)
     {
	_pSLang_verror (SL_LimitExceeded_Error, "module name too long");
	return NULL;
     }
   SLsnprintf (module_so, sizeof(module_so), "%s-module.%s", module, SO_SUFFIX);

   if (Module_Path != NULL)
     pathfile = SLpath_find_file_in_path (Module_Path, module_so);
   else pathfile = NULL;

   if ((pathfile == NULL)
       && (NULL != (pathfile = _pSLsecure_getenv (MODULE_PATH_ENV_NAME))))
     pathfile = SLpath_find_file_in_path (pathfile, module_so);

   if (pathfile == NULL)
     pathfile = SLpath_find_file_in_path (MODULE_INSTALL_DIR, module_so);

   if (pathfile != NULL)
     file = pathfile;
   else
     file = module_so;

   save_err = NULL;
   save_file = file;
   while (1)
     {
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
#ifdef RTLD_NOW
	handle = (VOID_STAR) dlopen (file, RTLD_NOW | RTLD_GLOBAL);
#else
	handle = (VOID_STAR) dlopen (file, RTLD_LAZY | RTLD_GLOBAL);
#endif

	if (handle != NULL)
	  {
	     if (_pSLang_Load_File_Verbose & SLANG_LOAD_MODULE_VERBOSE)
	       SLang_vmessage ("Importing %s", file);
	     if (save_err != NULL)
	       SLfree (save_err);
	     break;
	  }

	/* Purify reports that dlerror returns a pointer that generates UMR
	 * errors.  There is nothing that I can do about that....
	 */
	if ((NULL == strchr (file, '/'))
	    && (strlen(file) < sizeof(filebuf)))
	  {
	     err = (char *) dlerror ();
	     if (err != NULL)
	       save_err = SLmake_string (err);

	     SLsnprintf (filebuf, sizeof (filebuf), "./%s", file);
	     file = filebuf;
	     continue;
	  }

	if ((NULL == (err = save_err))
	    && (NULL == (err = (char *) dlerror ())))
	  err = "UNKNOWN";

	_pSLang_verror (SL_Import_Error,
		      "Error linking to %s: %s", save_file, err);

	if (save_err != NULL)
	  SLfree (save_err);
	if (pathfile != NULL)
	  SLfree (pathfile);

	return NULL;
     }

   /* Using SLpath_basename allows, e.g., import ("/path/to/module"); */
   module_name = SLpath_basename (module);

   api_version_ptr = (int *) do_dlsym (handle, file, 0, "SLmodule_%s_api_version", module_name);
   if (api_version_ptr == NULL)
     api_version_ptr = (int *) do_dlsym (handle, file, 0, "_SLmodule_%s_api_version", module_name);

   if (api_version_ptr == NULL)
     api_version = 0;
   else
     api_version = *api_version_ptr;

   if ((-1 == check_api_version (file, api_version))
       || (NULL == (h = allocate_handle_type (module, handle))))
     {
	SLfree (pathfile);	       /* NULL ok */
	dlclose (handle);
	return NULL;
     }

   if (NULL == (h->ns_init_fun = (int (*)(SLCONST char *)) do_dlsym (handle, file, 1, "init_%s_module_ns", module_name)))
     {
	SLfree (pathfile);
	free_handle_type (h);
	dlclose (handle);
	return NULL;
     }
   h->deinit_fun = (void (*)(void)) do_dlsym (handle, file, 0, "deinit_%s_module", module_name);

   SLfree (pathfile);		       /* NULL ok */
   h->next = Handle_List;
   Handle_List = h;

   return h;
}
Beispiel #4
0
/* If path looks like: A/B/C/D/whatever, it returns A/B/C/D as a malloced
 * string.
 */
char *SLpath_dirname (SLFUTURE_CONST char *drivefile)
{
   SLCONST char *b;
   const char *file;
   char *dir, *drivedir;
   size_t len;

   if (drivefile == NULL) return NULL;
   file = skip_drive (drivefile);

   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (0 == IS_PATH_SEP(*b))
	  continue;

#ifdef VMS
	b++;		       /* make sure final ] is included */
#else
	/* collapse multiple slashes */
	while ((b != file) && IS_PATH_SEP(*(b-1)))
	  b--;

	if (b == file) b++;
#endif
	break;
     }

   /* now b should point to the character after the slash:
    *    file="zzz/xxxx"
    *       b------^
    */
   if (b == file)
     {
	/* pathological cases -- what is the parent?  For simplicity
	 * simply return the current directory.
	 */
	len = file - drivefile;
	if (NULL == (dir = SLmalloc (len + 1 + strlen(THIS_DIR_STRING))))
	  return NULL;
	strncpy (dir, drivefile, len);
	strcpy (dir + len, THIS_DIR_STRING);
	return dir;
     }

   if (NULL == (drivedir = SLmake_nstring (drivefile, b - drivefile)))
     return NULL;

   dir = drivedir + (file - drivefile);
   len = b - file;		       /* len is from start of file on drive */

#ifndef VMS
   /* handle special cases
    *    /foo/.   --> /foo
    *    /.       --> /
    *    /foo/..  --> /
    * C:/.
    */
   while ((len > 1) && (dir[len-1] == '.'))
     {
	if (IS_PATH_SEP(dir[len-2]))
	  {
	     len--;		       /* lose "." */
	     while ((len > 1) && IS_PATH_SEP(dir[len-1]))
	       len--;		       /* lose "/" */
	     dir[len] = 0;
	     continue;
	  }
	if ((len > 2) && (dir[len-2] == '.') && IS_PATH_SEP(dir[len-3]))
	  {
	     len -= 2;		       /* lose ".." */
	     if (len > 1)
	       {
		  len--;		       /* lose "/" */
		  dir[len] = 0;
		  b = SLpath_basename (dir);   /* will not fail: zzz/xxx --> zzz/x */
		  len = b - dir;
		  while ((len > 1) && IS_PATH_SEP(dir[len-1]))
		    len--;
	       }
	     dir[len] = 0;
	     continue;
	  }

	break;
     }
#endif				       /* not VMS */
   return drivedir;
}