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

📄 ltdl.c

📁 一个很棒的视频服务器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ltdl.c -- system independent dlopen wrapper   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.   Originally by Thomas Tanner <tanner@ffii.org>   This file is part of GNU Libtool.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2 of the License, or (at your option) any later version.As a special exception to the GNU Lesser General Public License,if you distribute this file as part of a program or library thatis built using GNU libtool, you may include it under the samedistribution terms that you use for the rest of that program.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307  USA*/#if HAVE_CONFIG_H#  include <config.h>#endif#if HAVE_UNISTD_H#  include <unistd.h>#endif#if HAVE_STDIO_H#  include <stdio.h>#endif#if HAVE_STDLIB_H#  include <stdlib.h>#endif#if HAVE_STRING_H#  include <string.h>#else#  if HAVE_STRINGS_H#    include <strings.h>#  endif#endif#if HAVE_CTYPE_H#  include <ctype.h>#endif#if HAVE_MALLOC_H#  include <malloc.h>#endif#if HAVE_MEMORY_H#  include <memory.h>#endif#if HAVE_ERRNO_H#  include <errno.h>#endif#if HAVE_DIRENT_H#  include <dirent.h>#  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))#else#  define dirent direct#  define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)#  if HAVE_SYS_NDIR_H#    include <sys/ndir.h>#  endif#  if HAVE_SYS_DIR_H#    include <sys/dir.h>#  endif#  if HAVE_NDIR_H#    include <ndir.h>#  endif#endif#if HAVE_ARGZ_H#  include <argz.h>#endif#if HAVE_ASSERT_H#  include <assert.h>#else#  define assert(arg)	((void) 0)#endif#include "ltdl.h"/* --- WINDOWS SUPPORT --- */#ifdef DLL_EXPORT#  define LT_GLOBAL_DATA	__declspec(dllexport)#else#  define LT_GLOBAL_DATA#endif/* fopen() mode flags for reading a text file */#undef	LT_READTEXT_MODE#ifdef __WINDOWS__#  define LT_READTEXT_MODE "rt"#else#  define LT_READTEXT_MODE "r"#endif/* --- MANIFEST CONSTANTS --- *//* Standard libltdl search path environment variable name  */#undef  LTDL_SEARCHPATH_VAR#define LTDL_SEARCHPATH_VAR	"LTDL_LIBRARY_PATH"/* Standard libtool archive file extension.  */#undef  LTDL_ARCHIVE_EXT#define LTDL_ARCHIVE_EXT	".la"/* max. filename length */#ifndef LT_FILENAME_MAX#  define LT_FILENAME_MAX	1024#endif/* This is the maximum symbol size that won't require malloc/free */#undef	LT_SYMBOL_LENGTH#define LT_SYMBOL_LENGTH	128/* This accounts for the _LTX_ separator */#undef	LT_SYMBOL_OVERHEAD#define LT_SYMBOL_OVERHEAD	5/* --- MEMORY HANDLING --- *//* These are the functions used internally.  In addition to making   use of the associated function pointers above, they also perform   error handling.  */static char   *lt_estrdup	LT_PARAMS((const char *str));static lt_ptr lt_emalloc	LT_PARAMS((size_t size));static lt_ptr lt_erealloc	LT_PARAMS((lt_ptr addr, size_t size));static lt_ptr rpl_realloc	LT_PARAMS((lt_ptr ptr, size_t size));/* These are the pointers that can be changed by the caller:  */LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc)	LT_PARAMS((size_t size)) 			= (lt_ptr (*) LT_PARAMS((size_t))) malloc;LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)	LT_PARAMS((lt_ptr ptr, size_t size)) 			= (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;LT_GLOBAL_DATA void   (*lt_dlfree)	LT_PARAMS((lt_ptr ptr)) 			= (void (*) LT_PARAMS((lt_ptr))) free;/* The following macros reduce the amount of typing needed to cast   assigned memory.  */#define LT_DLMALLOC(tp, n)	((tp *) lt_dlmalloc ((n) * sizeof(tp)))#define LT_DLREALLOC(tp, p, n)	((tp *) rpl_realloc ((p), (n) * sizeof(tp)))#define LT_DLFREE(p)						\	LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END#define LT_EMALLOC(tp, n)	((tp *) lt_emalloc ((n) * sizeof(tp)))#define LT_EREALLOC(tp, p, n)	((tp *) lt_erealloc ((p), (n) * sizeof(tp)))#define LT_DLMEM_REASSIGN(p, q)			LT_STMT_START {	\	if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; }	\						} LT_STMT_END/* --- REPLACEMENT FUNCTIONS --- */#undef strdup#define strdup rpl_strdupstatic char *strdup LT_PARAMS((const char *str));char *strdup(str)     const char *str;{  char *tmp = 0;  if (str)    {      tmp = LT_DLMALLOC (char, 1+ strlen (str));      if (tmp)	{	  strcpy(tmp, str);	}    }  return tmp;}#if ! HAVE_STRCMP#undef strcmp#define strcmp rpl_strcmpstatic int strcmp LT_PARAMS((const char *str1, const char *str2));intstrcmp (str1, str2)     const char *str1;     const char *str2;{  if (str1 == str2)    return 0;  if (str1 == 0)    return -1;  if (str2 == 0)    return 1;  for (;*str1 && *str2; ++str1, ++str2)    {      if (*str1 != *str2)	break;    }  return (int)(*str1 - *str2);}#endif#if ! HAVE_STRCHR#  if HAVE_INDEX#    define strchr index#  else#    define strchr rpl_strchrstatic const char *strchr LT_PARAMS((const char *str, int ch));const char*strchr(str, ch)     const char *str;     int ch;{  const char *p;  for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)    /*NOWORK*/;  return (*p == (char)ch) ? p : 0;}#  endif#endif /* !HAVE_STRCHR */#if ! HAVE_STRRCHR#  if HAVE_RINDEX#    define strrchr rindex#  else#    define strrchr rpl_strrchrstatic const char *strrchr LT_PARAMS((const char *str, int ch));const char*strrchr(str, ch)     const char *str;     int ch;{  const char *p, *q = 0;  for (p = str; *p != LT_EOS_CHAR; ++p)    {      if (*p == (char) ch)	{	  q = p;	}    }  return q;}# endif#endif/* NOTE:  Neither bcopy nor the memcpy implementation below can          reliably handle copying in overlapping areas of memory.  Use          memmove (for which there is a fallback implmentation below)	  if you need that behaviour.  */#if ! HAVE_MEMCPY#  if HAVE_BCOPY#    define memcpy(dest, src, size)	bcopy (src, dest, size)#  else#    define memcpy rpl_memcpystatic lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));lt_ptrmemcpy (dest, src, size)     lt_ptr dest;     const lt_ptr src;     size_t size;{  size_t i = 0;  for (i = 0; i < size; ++i)    {      dest[i] = src[i];    }  return dest;}#  endif /* !HAVE_BCOPY */#endif   /* !HAVE_MEMCPY */#if ! HAVE_MEMMOVE#  define memmove rpl_memmovestatic lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));lt_ptrmemmove (dest, src, size)     lt_ptr dest;     const lt_ptr src;     size_t size;{  size_t i;  if (dest < src)    for (i = 0; i < size; ++i)      {	dest[i] = src[i];      }  else if (dest > src)    for (i = size -1; i >= 0; --i)      {	dest[i] = src[i];      }  return dest;}#endif /* !HAVE_MEMMOVE *//* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,    ``realloc is not entirely portable''   In any case we want to use the allocator supplied by the user without   burdening them with an lt_dlrealloc function pointer to maintain.   Instead implement our own version (with known boundary conditions)   using lt_dlmalloc and lt_dlfree. */#undef realloc#define realloc rpl_realloclt_ptrrealloc (ptr, size)     lt_ptr ptr;     size_t size;{  if (size <= 0)    {      /* For zero or less bytes, free the original memory */      if (ptr != 0)	{	  lt_dlfree (ptr);	}      return (lt_ptr) 0;    }  else if (ptr == 0)    {      /* Allow reallocation of a NULL pointer.  */      return lt_dlmalloc (size);    }  else    {      /* Allocate a new block, copy and free the old block.  */      lt_ptr mem = lt_dlmalloc (size);      if (mem)	{	  memcpy (mem, ptr, size);	  lt_dlfree (ptr);	}      /* Note that the contents of PTR are not damaged if there is	 insufficient memory to realloc.  */      return mem;    }}#if ! HAVE_ARGZ_APPEND#  define argz_append rpl_argz_appendstatic error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,					const char *buf, size_t buf_len));error_targz_append (pargz, pargz_len, buf, buf_len)     char **pargz;     size_t *pargz_len;     const char *buf;     size_t buf_len;{  size_t argz_len;  char  *argz;  assert (pargz);  assert (pargz_len);  assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));  /* If nothing needs to be appended, no more work is required.  */  if (buf_len == 0)    return 0;  /* Ensure there is enough room to append BUF_LEN.  */  argz_len = *pargz_len + buf_len;  argz = LT_DLREALLOC (char, *pargz, argz_len);  if (!argz)    return ENOMEM;  /* Copy characters from BUF after terminating '\0' in ARGZ.  */  memcpy (argz + *pargz_len, buf, buf_len);  /* Assign new values.  */  *pargz = argz;  *pargz_len = argz_len;  return 0;}#endif /* !HAVE_ARGZ_APPEND */#if ! HAVE_ARGZ_CREATE_SEP#  define argz_create_sep rpl_argz_create_sepstatic error_t argz_create_sep LT_PARAMS((const char *str, int delim,					    char **pargz, size_t *pargz_len));error_targz_create_sep (str, delim, pargz, pargz_len)     const char *str;     int delim;     char **pargz;     size_t *pargz_len;{  size_t argz_len;  char *argz = 0;  assert (str);  assert (pargz);  assert (pargz_len);  /* Make a copy of STR, but replacing each occurence of     DELIM with '\0'.  */  argz_len = 1+ LT_STRLEN (str);  if (argz_len)    {      const char *p;      char *q;      argz = LT_DLMALLOC (char, argz_len);      if (!argz)	return ENOMEM;      for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)	{	  if (*p == delim)	    {	      /* Ignore leading delimiters, and fold consecutive		 delimiters in STR into a single '\0' in ARGZ.  */	      if ((q > argz) && (q[-1] != LT_EOS_CHAR))		*q++ = LT_EOS_CHAR;	      else		--argz_len;	    }	  else	    *q++ = *p;	}      /* Copy terminating LT_EOS_CHAR.  */      *q = *p;    }  /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */  if (!argz_len)    LT_DLFREE (argz);  /* Assign new values.  */  *pargz = argz;  *pargz_len = argz_len;  return 0;}#endif /* !HAVE_ARGZ_CREATE_SEP */#if ! HAVE_ARGZ_INSERT#  define argz_insert rpl_argz_insertstatic error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,					char *before, const char *entry));error_targz_insert (pargz, pargz_len, before, entry)     char **pargz;     size_t *pargz_len;     char *before;     const char *entry;{  assert (pargz);  assert (pargz_len);  assert (entry && *entry);  /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,     or BEFORE points into an address within the ARGZ vector.  */  assert ((!*pargz && !*pargz_len && !before)	  || ((*pargz <= before) && (before < (*pargz + *pargz_len))));  /* No BEFORE address indicates ENTRY should be inserted after the     current last element.  */  if (!before)    return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));  /* This probably indicates a programmer error, but to preserve     semantics, scan back to the start of an entry if BEFORE points     into the middle of it.  */  while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))    --before;  {    size_t entry_len	= 1+ LT_STRLEN (entry);    size_t argz_len	= *pargz_len + entry_len;    size_t offset	= before - *pargz;    char   *argz	= LT_DLREALLOC (char, *pargz, argz_len);    if (!argz)      return ENOMEM;    /* Make BEFORE point to the equivalent offset in ARGZ that it       used to have in *PARGZ incase realloc() moved the block.  */    before = argz + offset;    /* Move the ARGZ entries starting at BEFORE up into the new       space at the end -- making room to copy ENTRY into the       resulting gap.  */    memmove (before + entry_len, before, *pargz_len - offset);    memcpy  (before, entry, entry_len);    /* Assign new values.  */    *pargz = argz;    *pargz_len = argz_len;  }  return 0;}#endif /* !HAVE_ARGZ_INSERT */#if ! HAVE_ARGZ_NEXT#  define argz_next rpl_argz_nextstatic char *argz_next LT_PARAMS((char *argz, size_t argz_len,				    const char *entry));char *argz_next (argz, argz_len, entry)     char *argz;     size_t argz_len;     const char *entry;{  assert ((argz && argz_len) || (!argz && !argz_len));  if (entry)    {      /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address	 within the ARGZ vector.  */      assert ((!argz && !argz_len)	      || ((argz <= entry) && (entry < (argz + argz_len))));      /* Move to the char immediately after the terminating	 '\0' of ENTRY.  */      entry = 1+ strchr (entry, LT_EOS_CHAR);      /* Return either the new ENTRY, or else NULL if ARGZ is	 exhausted.  */      return (entry >= argz + argz_len) ? 0 : (char *) entry;    }  else    {      /* This should probably be flagged as a programmer error,	 since starting an argz_next loop with the iterator set	 to ARGZ is safer.  To preserve semantics, handle the NULL	 case by returning the start of ARGZ (if any).  */      if (argz_len > 0)

⌨️ 快捷键说明

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