⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ltdl.c

📁 MPI stands for the Message Passing Interface. Written by the MPI Forum (a large committee comprising
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (list_files_by_dir (dirname, &argz, &argz_len) != 0)    goto cleanup;  if (!argz)    goto cleanup;  {    char *filename = 0;    while ((filename = argz_next (argz, argz_len, filename)))      if ((is_done = (*func) (filename, data2)))	break;  } cleanup:  FREE (argz);  return is_done;}/* Call FUNC for each unique extensionless file in SEARCH_PATH, along   with DATA.  The filenames passed to FUNC would be suitable for   passing to lt_dlopenext.  The extensions are stripped so that   individual modules do not generate several entries (e.g. libfoo.la,   libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,   then the same directories that lt_dlopen would search are examined.  */intlt_dlforeachfile (const char *search_path,		  int (*func) (const char *filename, void *data),		  void *data){  int is_done = 0;  file_worker_func **fpptr = &func;  if (search_path)    {      /* If a specific path was passed, search only the directories	 listed in it.  */      is_done = foreach_dirinpath (search_path, 0,				   foreachfile_callback, fpptr, data);    }  else    {      /* Otherwise search the default paths.  */      is_done = foreach_dirinpath (user_search_path, 0,				   foreachfile_callback, fpptr, data);      if (!is_done)	{	  is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,				       foreachfile_callback, fpptr, data);	}#if defined(LT_MODULE_PATH_VAR)      if (!is_done)	{	  is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,				       foreachfile_callback, fpptr, data);	}#endif#if defined(LT_DLSEARCH_PATH)      if (!is_done && sys_dlsearch_path)	{	  is_done = foreach_dirinpath (sys_dlsearch_path, 0,				       foreachfile_callback, fpptr, data);	}#endif    }  return is_done;}intlt_dlclose (lt_dlhandle handle){  lt__handle *cur, *last;  int errors = 0;  /* check whether the handle is valid */  last = cur = (lt__handle *) handles;  while (cur && handle != cur)    {      last = cur;      cur = cur->next;    }  if (!cur)    {      LT__SETERROR (INVALID_HANDLE);      ++errors;      goto done;    }  cur = (lt__handle *) handle;  cur->info.ref_count--;  /* Note that even with resident modules, we must track the ref_count     correctly incase the user decides to reset the residency flag     later (even though the API makes no provision for that at the     moment).  */  if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))    {      lt_user_data data = cur->vtable->dlloader_data;      if (cur != handles)	{	  last->next = cur->next;	}      else	{	  handles = cur->next;	}      errors += cur->vtable->module_close (data, cur->module);      errors += unload_deplibs (handle);      /* It is up to the callers to free the data itself.  */      FREE (cur->interface_data);      FREE (cur->info.filename);      FREE (cur->info.name);      FREE (cur);      goto done;    }  if (LT_DLIS_RESIDENT (handle))    {      LT__SETERROR (CLOSE_RESIDENT_MODULE);      ++errors;    } done:  return errors;}void *lt_dlsym (lt_dlhandle place, const char *symbol){  size_t lensym;  char	lsym[LT_SYMBOL_LENGTH];  char	*sym;  void *address;  lt_user_data data;  lt__handle *handle;  if (!place)    {      LT__SETERROR (INVALID_HANDLE);      return 0;    }  handle = (lt__handle *) place;  if (!symbol)    {      LT__SETERROR (SYMBOL_NOT_FOUND);      return 0;    }  lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)					+ LT_STRLEN (handle->info.name);  if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)    {      sym = lsym;    }  else    {      sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);      if (!sym)	{	  LT__SETERROR (BUFFER_OVERFLOW);	  return 0;	}    }  data = handle->vtable->dlloader_data;  if (handle->info.name)    {      const char *saved_error;      LT__GETERROR (saved_error);      /* this is a libtool module */      if (handle->vtable->sym_prefix)	{	  strcpy(sym, handle->vtable->sym_prefix);	  strcat(sym, handle->info.name);	}      else	{	  strcpy(sym, handle->info.name);	}      strcat(sym, "_LTX_");      strcat(sym, symbol);      /* try "modulename_LTX_symbol" */      address = handle->vtable->find_sym (data, handle->module, sym);      if (address)	{	  if (sym != lsym)	    {	      FREE (sym);	    }	  return address;	}      LT__SETERRORSTR (saved_error);    }  /* otherwise try "symbol" */  if (handle->vtable->sym_prefix)    {      strcpy(sym, handle->vtable->sym_prefix);      strcat(sym, symbol);    }  else    {      strcpy(sym, symbol);    }  address = handle->vtable->find_sym (data, handle->module, sym);  if (sym != lsym)    {      FREE (sym);    }  return address;}const char *lt_dlerror (void){  const char *error;  LT__GETERROR (error);  LT__SETERRORSTR (0);  return error ? error : NULL;}static intlt_dlpath_insertdir (char **ppath, char *before, const char *dir){  int    errors		= 0;  char  *canonical	= 0;  char  *argz		= 0;  size_t argz_len	= 0;  assert (ppath);  assert (dir && *dir);  if (canonicalize_path (dir, &canonical) != 0)    {      ++errors;      goto cleanup;    }  assert (canonical && *canonical);  /* If *PPATH is empty, set it to DIR.  */  if (*ppath == 0)    {      assert (!before);		/* BEFORE cannot be set without PPATH.  */      assert (dir);		/* Without DIR, don't call this function!  */      *ppath = lt__strdup (dir);      if (*ppath == 0)	++errors;      goto cleanup;    }  assert (ppath && *ppath);  if (argzize_path (*ppath, &argz, &argz_len) != 0)    {      ++errors;      goto cleanup;    }  /* Convert BEFORE into an equivalent offset into ARGZ.  This only works     if *PPATH is already canonicalized, and hence does not change length     with respect to ARGZ.  We canonicalize each entry as it is added to     the search path, and don't call this function with (uncanonicalized)     user paths, so this is a fair assumption.  */  if (before)    {      assert (*ppath <= before);      assert ((int) (before - *ppath) <= (int) strlen (*ppath));      before = before - *ppath + argz;    }  if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)    {      ++errors;      goto cleanup;    }  argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);  MEMREASSIGN(*ppath, argz); cleanup:  FREE (argz);  FREE (canonical);  return errors;}intlt_dladdsearchdir (const char *search_dir){  int errors = 0;  if (search_dir && *search_dir)    {      if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)	++errors;    }  return errors;}intlt_dlinsertsearchdir (const char *before, const char *search_dir){  int errors = 0;  if (before)    {      if ((before < user_search_path)	  || (before >= user_search_path + LT_STRLEN (user_search_path)))	{	  LT__SETERROR (INVALID_POSITION);	  return 1;	}    }  if (search_dir && *search_dir)    {      if (lt_dlpath_insertdir (&user_search_path,			       (char *) before, search_dir) != 0)	{	  ++errors;	}    }  return errors;}intlt_dlsetsearchpath (const char *search_path){  int   errors	    = 0;  FREE (user_search_path);  if (!search_path || !LT_STRLEN (search_path))    {      return errors;    }  if (canonicalize_path (search_path, &user_search_path) != 0)    ++errors;  return errors;}const char *lt_dlgetsearchpath (void){  const char *saved_path;  saved_path = user_search_path;  return saved_path;}intlt_dlmakeresident (lt_dlhandle handle){  int errors = 0;  if (!handle)    {      LT__SETERROR (INVALID_HANDLE);      ++errors;    }  else    {      ((lt__handle *) handle)->info.is_resident = 1;    }  return errors;}intlt_dlisresident	(lt_dlhandle handle){  if (!handle)    {      LT__SETERROR (INVALID_HANDLE);      return -1;    }  return LT_DLIS_RESIDENT (handle);}/* --- MODULE INFORMATION --- */typedef struct {  const char *id_string;  lt_dlhandle_interface *iface;} lt__interface_id;lt_dlinterface_idlt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface){  lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);  /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which     can then be detected with lt_dlerror() if we return 0.  */  if (interface_id)    {      interface_id->id_string = lt__strdup (id_string);      if (!interface_id->id_string)	FREE (interface_id);      else	interface_id->iface = iface;    }  return (lt_dlinterface_id) interface_id;}void lt_dlinterface_free (lt_dlinterface_id key){  lt__interface_id *interface_id = (lt__interface_id *)key;  FREE (interface_id->id_string);  FREE (interface_id);}void *lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data){  int n_elements = 0;  void *stale = (void *) 0;  lt__handle *cur = (lt__handle *) handle;  int i;  if (cur->interface_data)    while (cur->interface_data[n_elements].key)      ++n_elements;  for (i = 0; i < n_elements; ++i)    {      if (cur->interface_data[i].key == key)	{	  stale = cur->interface_data[i].data;	  break;	}    }  /* Ensure that there is enough room in this handle's interface_data     array to accept a new element (and an empty end marker).  */  if (i == n_elements)    {      lt_interface_data *temp	= REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);      if (!temp)	{	  stale = 0;	  goto done;	}      cur->interface_data = temp;      /* We only need this if we needed to allocate a new interface_data.  */      cur->interface_data[i].key	= key;      cur->interface_data[1+ i].key	= 0;    }  cur->interface_data[i].data = data; done:  return stale;}void *lt_dlcaller_get_data  (lt_dlinterface_id key, lt_dlhandle handle){  void *result = (void *) 0;  lt__handle *cur = (lt__handle *) handle;  /* Locate the index of the element with a matching KEY.  */  {    int i;    for (i = 0; cur->interface_data[i].key; ++i)      {	if (cur->interface_data[i].key == key)	  {	    result = cur->interface_data[i].data;	    break;	  }      }  }  return result;}const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle){  if (!handle)    {      LT__SETERROR (INVALID_HANDLE);      return 0;    }  return &(((lt__handle *) handle)->info);}lt_dlhandlelt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place){  lt__handle *handle = (lt__handle *) place;  lt__interface_id *iterator = (lt__interface_id *) iface;  assert (iface); /* iface is a required argument */  if (!handle)    handle = (lt__handle *) handles;  else    handle = handle->next;  /* advance while the interface check fails */  while (handle && iterator->iface	 && ((*iterator->iface) (handle, iterator->id_string) != 0))    {      handle = handle->next;    }  return (lt_dlhandle) handle;}lt_dlhandlelt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name){  lt_dlhandle handle = 0;  assert (iface); /* iface is a required argument */  while ((handle = lt_dlhandle_iterate (iface, handle)))    {      lt__handle *cur = (lt__handle *) handle;      if (cur && cur->info.name && streq (cur->info.name, module_name))	break;    }  return handle;}intlt_dlhandle_map (lt_dlinterface_id iface,		 int (*func) (lt_dlhandle handle, void *data), void *data){  lt__interface_id *iterator = (lt__interface_id *) iface;  lt__handle *cur = (lt__handle *) handles;  assert (iface); /* iface is a required argument */  while (cur)    {      int errorcode = 0;      /* advance while the interface check fails */      while (cur && iterator->iface	     && ((*iterator->iface) (cur, iterator->id_string) != 0))	{	  cur = cur->next;	}      if ((errorcode = (*func) (cur, data)) != 0)	return errorcode;    }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -