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

📄 ltdl.c

📁 sdcc是为51等小型嵌入式cpu设计的c语言编译器支持数种不同类型的cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
/* --- DYNAMIC MODULE LOADING --- *//* The type of a function used at each iteration of  foreach_dirinpath().  */typedef int     foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,                                                 lt_ptr data2));static  int     foreach_dirinpath     LT_PARAMS((const char *search_path,                                                 const char *base_name,                                                 foreach_callback_func *func,                                                 lt_ptr data1, lt_ptr data2));static  int     find_file_callback    LT_PARAMS((char *filename, lt_ptr data,                                                 lt_ptr ignored));static  int     find_handle_callback  LT_PARAMS((char *filename, lt_ptr data,                                                 lt_ptr ignored));static  int     foreachfile_callback  LT_PARAMS((char *filename, lt_ptr data1,                                                 lt_ptr data2));static  int     canonicalize_path     LT_PARAMS((const char *path,                                                 char **pcanonical));static  int     argzize_path          LT_PARAMS((const char *path,                                                 char **pargz,                                                 size_t *pargz_len));static  FILE   *find_file             LT_PARAMS((const char *search_path,                                                 const char *base_name,                                                 char **pdir));static  lt_dlhandle *find_handle      LT_PARAMS((const char *search_path,                                                 const char *base_name,                                                 lt_dlhandle *handle));static  int     find_module           LT_PARAMS((lt_dlhandle *handle,                                                 const char *dir,                                                 const char *libdir,                                                 const char *dlname,                                                 const char *old_name,                                                 int installed));static  int     free_vars             LT_PARAMS((char *dlname, char *oldname,                                                 char *libdir, char *deplibs));static  int     load_deplibs          LT_PARAMS((lt_dlhandle handle,                                                 char *deplibs));static  int     trim                  LT_PARAMS((char **dest,                                                 const char *str));static  int     try_dlopen            LT_PARAMS((lt_dlhandle *handle,                                                 const char *filename));static  int     tryall_dlopen         LT_PARAMS((lt_dlhandle *handle,                                                 const char *filename));static  int     unload_deplibs        LT_PARAMS((lt_dlhandle handle));static  int     lt_argz_insert        LT_PARAMS((char **pargz,                                                 size_t *pargz_len,                                                 char *before,                                                 const char *entry));static  int     lt_argz_insertinorder LT_PARAMS((char **pargz,                                                 size_t *pargz_len,                                                 const char *entry));static  int     lt_argz_insertdir     LT_PARAMS((char **pargz,                                                 size_t *pargz_len,                                                 const char *dirnam,                                                 struct dirent *dp));static  int     lt_dlpath_insertdir   LT_PARAMS((char **ppath,                                                 char *before,                                                 const char *dir));static  int     list_files_by_dir     LT_PARAMS((const char *dirnam,                                                 char **pargz,                                                 size_t *pargz_len));static  int     file_not_found        LT_PARAMS((void));static  char           *user_search_path= 0;static  lt_dlloader    *loaders         = 0;static  lt_dlhandle     handles         = 0;static  int             initialized     = 0;/* Initialize libltdl. */intlt_dlinit (){  int         errors   = 0;  LT_DLMUTEX_LOCK ();  /* Initialize only at first call. */  if (++initialized == 1)    {      handles = 0;      user_search_path = 0; /* empty search path */#if HAVE_LIBDL && !defined(__CYGWIN__)      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");#endif#if HAVE_SHL_LOAD      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");#endif#ifdef __WINDOWS__      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");#endif#ifdef __BEOS__      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");#endif#if HAVE_DLD      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");#endif      errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");      if (presym_init (presym.dlloader_data))        {          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));          ++errors;        }      else if (errors != 0)        {          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));          ++errors;        }    }  LT_DLMUTEX_UNLOCK ();  return errors;}intlt_dlpreload (preloaded)     const lt_dlsymlist *preloaded;{  int errors = 0;  if (preloaded)    {      errors = presym_add_symlist (preloaded);    }  else    {      presym_free_symlists();      LT_DLMUTEX_LOCK ();      if (default_preloaded_symbols)        {          errors = lt_dlpreload (default_preloaded_symbols);        }      LT_DLMUTEX_UNLOCK ();    }  return errors;}intlt_dlpreload_default (preloaded)     const lt_dlsymlist *preloaded;{  LT_DLMUTEX_LOCK ();  default_preloaded_symbols = preloaded;  LT_DLMUTEX_UNLOCK ();  return 0;}intlt_dlexit (){  /* shut down libltdl */  lt_dlloader *loader;  int          errors   = 0;  LT_DLMUTEX_LOCK ();  loader = loaders;  if (!initialized)    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));      ++errors;      goto done;    }  /* shut down only at last call. */  if (--initialized == 0)    {      int       level;      while (handles && LT_DLIS_RESIDENT (handles))        {          handles = handles->next;        }      /* close all modules */      for (level = 1; handles; ++level)        {          lt_dlhandle cur = handles;          int saw_nonresident = 0;          while (cur)            {              lt_dlhandle tmp = cur;              cur = cur->next;              if (!LT_DLIS_RESIDENT (tmp))                saw_nonresident = 1;              if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)                {                  if (lt_dlclose (tmp))                    {                      ++errors;                    }                }            }          /* done if only resident modules are left */          if (!saw_nonresident)            break;        }      /* close all loaders */      while (loader)        {          lt_dlloader *next = loader->next;          lt_user_data data = loader->dlloader_data;          if (loader->dlloader_exit && loader->dlloader_exit (data))            {              ++errors;            }          LT_DLMEM_REASSIGN (loader, next);        }      loaders = 0;    } done:  LT_DLMUTEX_UNLOCK ();  return errors;}static inttryall_dlopen (handle, filename)     lt_dlhandle *handle;     const char *filename;{  lt_dlhandle    cur;  lt_dlloader   *loader;  const char    *saved_error;  int            errors         = 0;  LT_DLMUTEX_GETERROR (saved_error);  LT_DLMUTEX_LOCK ();  cur    = handles;  loader = loaders;  /* check whether the module was already opened */  while (cur)    {      /* try to dlopen the program itself? */      if (!cur->info.filename && !filename)        {          break;        }      if (cur->info.filename && filename          && strcmp (cur->info.filename, filename) == 0)        {          break;        }      cur = cur->next;    }  if (cur)    {      ++cur->info.ref_count;      *handle = cur;      goto done;    }  cur = *handle;  if (filename)    {      cur->info.filename = lt_estrdup (filename);      if (!cur->info.filename)        {          ++errors;          goto done;        }    }  else    {      cur->info.filename = 0;    }  while (loader)    {      lt_user_data data = loader->dlloader_data;      cur->module = loader->module_open (data, filename);      if (cur->module != 0)        {          break;        }      loader = loader->next;    }  if (!loader)    {      LT_DLFREE (cur->info.filename);      ++errors;      goto done;    }  cur->loader   = loader;  LT_DLMUTEX_SETERROR (saved_error); done:  LT_DLMUTEX_UNLOCK ();  return errors;}static inttryall_dlopen_module (handle, prefix, dirname, dlname)     lt_dlhandle *handle;     const char *prefix;     const char *dirname;     const char *dlname;{  int      error        = 0;  char     *filename    = 0;  size_t   filename_len = 0;  size_t   dirname_len  = LT_STRLEN (dirname);  assert (handle);  assert (dirname);  assert (dlname);#ifdef LT_DIRSEP_CHAR  /* Only canonicalized names (i.e. with DIRSEP chars already converted)     should make it into this function:  */  assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);#endif  if (dirname[dirname_len -1] == '/')    --dirname_len;  filename_len = dirname_len + 1 + LT_STRLEN (dlname);  /* Allocate memory, and combine DIRNAME and MODULENAME into it.     The PREFIX (if any) is handled below.  */  filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);  if (!filename)    return 1;  sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);  /* Now that we have combined DIRNAME and MODULENAME, if there is     also a PREFIX to contend with, simply recurse with the arguments     shuffled.  Otherwise, attempt to open FILENAME as a module.  */  if (prefix)    {      error += tryall_dlopen_module (handle,                                     (const char *) 0, prefix, filename);    }  else if (tryall_dlopen (handle, filename) != 0)    {      ++error;    }  LT_DLFREE (filename);  return error;}static intfind_module (handle, dir, libdir, dlname, old_name, installed)     lt_dlhandle *handle;     const char *dir;     const char *libdir;     const char *dlname;     const char *old_name;     int installed;{  /* Try to open the old library first; if it was dlpreopened,     we want the preopened version of it, even if a dlopenable     module is available.  */  if (old_name && tryall_dlopen (handle, old_name) == 0)    {      return 0;    }  /* Try to open the dynamic library.  */  if (dlname)    {      /* try to open the installed module */      if (installed && libdir)        {          if (tryall_dlopen_module (handle,                                    (const char *) 0, libdir, dlname) == 0)            return 0;        }      /* try to open the not-installed module */      if (!installed)        {          if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)            return 0;        }      /* maybe it was moved to another directory */      {          if (tryall_dlopen_module (handle,                                    (const char *) 0, dir, dlname) == 0)            return 0;      }    }  return 1;}static intcanonicalize_path (path, pcanonical)     const char *path;     char **pcanonical;{  char *canonical = 0;  assert (path && *path);  assert (pcanonical);  canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));  if (!canonical)    return 1;  {    size_t dest = 0;    size_t src;    for (src = 0; path[src] != LT_EOS_CHAR; ++src)      {        /* Path separators are not copied to the beginning or end of           the destination, or if another separator would follow           immediately.  */        if (path[src] == LT_PATHSEP_CHAR)          {            if ((dest == 0)                || (path[1+ src] == LT_PATHSEP_CHAR)                || (path[1+ src] == LT_EOS_CHAR))              continue;          }        /* Anything other than a directory separator is copied verbatim.  */        if ((path[src] != '/')#ifdef LT_DIRSEP_CHAR            && (path[src] != LT_DIRSEP_CHAR)#endif            )          {            canonical[dest++] = path[src];          }        /* Directory separators are converted and copied only if they are           not at the end of a path -- i.e. before a path separator or           NULL terminator.  */        else if ((path[1+ src] != LT_PATHSEP_CHAR)                 && (path[1+ src] != LT_EOS_CHAR)#ifdef LT_DIRSEP_CHAR                 && (path[1+ src] != LT_DIRSEP_CHAR)#endif                 && (path[1+ src] != '/'))          {            canonical[dest++] = '/';          }      }    /* Add an end-of-string marker at the end.  */    canonical[dest] = LT_EOS_CHAR;  }  /* Assign new value.  */  *pcanonical = canonical;  return 0;}static intargzize_path (path, pargz, pargz_len)     const char *path;     char **pargz;     size_t *pargz_len;{  error_t error;  assert (path);  assert (pargz);  assert (pargz_len);  if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))    {      switch (error)        {        case ENOMEM:          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));          break;        default:          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));          break;        }      return 1;    }  return 0;}/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element   of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns   non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,   it is appended to each SEARCH_PATH element before FUNC is called.  */static intforeach_dirinpath (search_path, base_name, func, data1, data2)     const char *search_path;     const char *base_name;     foreach_callback_func *func;     lt_ptr data1;     lt_ptr data2;{  int    result         = 0;  int    filenamesize   = 0;  size_t lenbase        = LT_STRLEN (base_name);  size_t argz_len       = 0;  char *argz            = 0;  char *filename        = 0;  char *canonical       = 0;  LT_DLMUTEX_LOCK ();  if (!search_path || !*search_path)    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));      goto cleanup;    }  if (canonicalize_path (search_path, &canonical) != 0)    goto cleanup;  if (argzize_path (canonical, &argz, &argz_len) != 0)    goto cleanup;  {    char *dir_name = 0;    while ((dir_name = argz_next (argz, argz_len, dir_name)))      {        size_t lendir = LT_STRLEN (dir_name);        if (lendir +1 +lenbase >= filenamesize)        {          LT_DLFREE (filename);          filenamesize  = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */

⌨️ 快捷键说明

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