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

📄 ltdl.c

📁 Small Device C Compiler 面向Inter8051
💻 C
📖 第 1 页 / 共 5 页
字号:
  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' */	  filename	= LT_EMALLOC (char, filenamesize);	  if (!filename)	    goto cleanup;	}	strncpy (filename, dir_name, lendir);	if (base_name && *base_name)	  {	    if (filename[lendir -1] != '/')	      filename[lendir++] = '/';	    strcpy (filename +lendir, base_name);	  }	if ((result = (*func) (filename, data1, data2)))	  {	    break;	  }      }  } cleanup:  LT_DLFREE (argz);  LT_DLFREE (canonical);  LT_DLFREE (filename);  LT_DLMUTEX_UNLOCK ();  return result;}/* If FILEPATH can be opened, store the name of the directory component   in DATA1, and the opened FILE* structure address in DATA2.  Otherwise   DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */static intfind_file_callback (filename, data1, data2)     char *filename;     lt_ptr data1;     lt_ptr data2;{  char	     **pdir	= (char **) data1;  FILE	     **pfile	= (FILE **) data2;  int	     is_done	= 0;  assert (filename && *filename);  assert (pdir);  assert (pfile);  if ((*pfile = fopen (filename, LT_READTEXT_MODE)))    {      char *dirend = strrchr (filename, '/');      if (dirend > filename)	*dirend   = LT_EOS_CHAR;      LT_DLFREE (*pdir);      *pdir   = lt_estrdup (filename);      is_done = (*pdir == 0) ? -1 : 1;    }  return is_done;}static FILE *find_file (search_path, base_name, pdir)     const char *search_path;     const char *base_name;     char **pdir;{  FILE *file = 0;  foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);  return file;}static intfind_handle_callback (filename, data, ignored)     char *filename;     lt_ptr data;     lt_ptr ignored;{  lt_dlhandle  *handle	= (lt_dlhandle *) data;  int		found	= access (filename, R_OK);  /* Bail out if file cannot be read...  */  if (!found)    return 0;  /* Try to dlopen the file, but do not continue searching in any     case.  */  if (tryall_dlopen (handle, filename) != 0)    *handle = 0;  return 1;}/* If HANDLE was found return it, otherwise return 0.  If HANDLE was   found but could not be opened, *HANDLE will be set to 0.  */static lt_dlhandle *find_handle (search_path, base_name, handle)     const char *search_path;     const char *base_name;     lt_dlhandle *handle;{  if (!search_path)    return 0;  if (!foreach_dirinpath (search_path, base_name, find_handle_callback,			  handle, 0))    return 0;  return handle;}static intload_deplibs (handle, deplibs)     lt_dlhandle handle;     char *deplibs;{#if LTDL_DLOPEN_DEPLIBS  char	*p, *save_search_path = 0;  int   depcount = 0;  int	i;  char	**names = 0;#endif  int	errors = 0;  handle->depcount = 0;#if LTDL_DLOPEN_DEPLIBS  if (!deplibs)    {      return errors;    }  ++errors;  LT_DLMUTEX_LOCK ();  if (user_search_path)    {      save_search_path = lt_estrdup (user_search_path);      if (!save_search_path)	goto cleanup;    }  /* extract search paths and count deplibs */  p = deplibs;  while (*p)    {      if (!isspace ((int) *p))	{	  char *end = p+1;	  while (*end && !isspace((int) *end))	    {	      ++end;	    }	  if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)	    {	      char save = *end;	      *end = 0; /* set a temporary string terminator */	      if (lt_dladdsearchdir(p+2))		{		  goto cleanup;		}	      *end = save;	    }	  else	    {	      ++depcount;	    }	  p = end;	}      else	{	  ++p;	}    }  /* restore the old search path */  LT_DLFREE (user_search_path);  user_search_path = save_search_path;  LT_DLMUTEX_UNLOCK ();  if (!depcount)    {      errors = 0;      goto cleanup;    }  names = LT_EMALLOC (char *, depcount * sizeof (char*));  if (!names)    goto cleanup;  /* now only extract the actual deplibs */  depcount = 0;  p = deplibs;  while (*p)    {      if (isspace ((int) *p))	{	  ++p;	}      else	{	  char *end = p+1;	  while (*end && !isspace ((int) *end))	    {	      ++end;	    }	  if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)	    {	      char *name;	      char save = *end;

⌨️ 快捷键说明

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