OS_NS_dlfcn.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // OS_NS_dlfcn.inl,v 1.20 2006/01/24 16:07:10 jwillemsen Exp
00004 
00005 #include "ace/OS_NS_macros.h"
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/OS_NS_fcntl.h"
00008 #include "ace/OS_NS_string.h"
00009 #include "ace/OS_NS_unistd.h"
00010 #include "ace/Default_Constants.h"
00011 #include "ace/os_include/os_fcntl.h"
00012 #include "ace/os_include/os_string.h"
00013 
00014 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
00015 # include "ace/OS_NS_stdio.h"
00016 #endif
00017 
00018 #if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
00019 #  include "ace/OS_Memory.h"
00020 #  include "ace/OS_NS_string.h"
00021 #endif /* ACE_USES_ASM_SYMBOL_IN_DLSYM */
00022 
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 ACE_INLINE int
00026 ACE_OS::dlclose (ACE_SHLIB_HANDLE handle)
00027 {
00028   ACE_OS_TRACE ("ACE_OS::dlclose");
00029 #if defined (ACE_LACKS_DLCLOSE)
00030   ACE_UNUSED_ARG (handle);
00031   return 0;
00032 #elif defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00033 
00034 # if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
00035   // SunOS4 does not automatically call _fini()!
00036   void *ptr;
00037 
00038   ACE_OSCALL (::dlsym (handle, ACE_LIB_TEXT ("_fini")), void *, 0, ptr);
00039 
00040   if (ptr != 0)
00041     (*((int (*)(void)) ptr)) (); // Call _fini hook explicitly.
00042 # endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
00043 #if defined (_M_UNIX)
00044   ACE_OSCALL_RETURN (::_dlclose (handle), int, -1);
00045 #else /* _MUNIX */
00046     ACE_OSCALL_RETURN (::dlclose (handle), int, -1);
00047 #endif /* _M_UNIX */
00048 #elif defined (ACE_WIN32)
00049   ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::FreeLibrary (handle), ace_result_), int, -1);
00050 #elif defined (__hpux)
00051   // HP-UX 10.x and 32-bit 11.00 do not pay attention to the ref count
00052   // when unloading a dynamic lib.  So, if the ref count is more than
00053   // 1, do not unload the lib.  This will cause a library loaded more
00054   // than once to not be unloaded until the process runs down, but
00055   // that's life.  It's better than unloading a library that's in use.
00056   // So far as I know, there's no way to decrement the refcnt that the
00057   // kernel is looking at - the shl_descriptor is a copy of what the
00058   // kernel has, not the actual struct.  On 64-bit HP-UX using dlopen,
00059   // this problem has been fixed.
00060   struct shl_descriptor  desc;
00061   if (shl_gethandle_r (handle, &desc) == -1)
00062     return -1;
00063   if (desc.ref_count > 1)
00064     return 0;
00065 # if defined(__GNUC__) || __cplusplus >= 199707L
00066   ACE_OSCALL_RETURN (::shl_unload (handle), int, -1);
00067 # else
00068   ACE_OSCALL_RETURN (::cxxshl_unload (handle), int, -1);
00069 # endif  /* aC++ vs. Hp C++ */
00070 #else
00071   ACE_UNUSED_ARG (handle);
00072   ACE_NOTSUP_RETURN (-1);
00073 #endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00074 }
00075 
00076 ACE_INLINE ACE_TCHAR *
00077 ACE_OS::dlerror (void)
00078 {
00079   ACE_OS_TRACE ("ACE_OS::dlerror");
00080 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00081   const char *err;
00082 #   if defined(_M_UNIX)
00083   ACE_OSCALL (::_dlerror (), const char *, 0, err);
00084 #   else /* _M_UNIX */
00085   ACE_OSCALL (::dlerror (), const char *, 0, err);
00086 #   endif /* _M_UNIX */
00087   if (err == 0)
00088     return 0;
00089 #   if defined (ACE_USES_WCHAR)
00090   const size_t BufLen = 256;
00091   static wchar_t buf[BufLen];
00092   ACE_OS::strncpy (buf, ACE_TEXT_CHAR_TO_TCHAR (err), BufLen);
00093   return buf;
00094 #   else
00095   return const_cast <char *> (err);
00096 #   endif /* ACE_USES_WCHAR */
00097 # elif defined (__hpux) || defined (ACE_VXWORKS)
00098   ACE_OSCALL_RETURN (::strerror(errno), char *, 0);
00099 # elif defined (ACE_WIN32)
00100   static ACE_TCHAR buf[128];
00101 #   if defined (ACE_HAS_PHARLAP)
00102   ACE_OS::sprintf (buf, "error code %d", GetLastError());
00103 #   else
00104   ACE_TEXT_FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
00105                           0,
00106                           ::GetLastError (),
00107                           0,
00108                           buf,
00109                           sizeof buf / sizeof buf[0],
00110                           0);
00111 #   endif /* ACE_HAS_PHARLAP */
00112   return buf;
00113 # else
00114   ACE_NOTSUP_RETURN (0);
00115 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00116 }
00117 
00118 ACE_INLINE ACE_SHLIB_HANDLE
00119 ACE_OS::dlopen (const ACE_TCHAR *fname,
00120                 int mode)
00121 {
00122   ACE_OS_TRACE ("ACE_OS::dlopen");
00123 
00124 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00125   void *handle;
00126 #   if defined (ACE_HAS_SGIDLADD)
00127   ACE_OSCALL
00128     (::sgidladd (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00129 #   elif defined (_M_UNIX)
00130   ACE_OSCALL
00131     (::_dlopen (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00132 #   else
00133   ACE_OSCALL
00134     (::dlopen (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00135 #   endif /* ACE_HAS_SGIDLADD */
00136 #   if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
00137   if (handle != 0)
00138     {
00139       void *ptr;
00140       // Some systems (e.g., SunOS4) do not automatically call _init(), so
00141       // we'll have to call it manually.
00142 
00143       ACE_OSCALL (::dlsym (handle, ACE_LIB_TEXT ("_init")), void *, 0, ptr);
00144 
00145       if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1) // Call _init hook explicitly.
00146         {
00147           // Close down the handle to prevent leaks.
00148           ::dlclose (handle);
00149           return 0;
00150         }
00151     }
00152 #   endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
00153   return handle;
00154 # elif defined (ACE_WIN32)
00155   ACE_UNUSED_ARG (mode);
00156 
00157   ACE_WIN32CALL_RETURN (ACE_TEXT_LoadLibrary (fname), ACE_SHLIB_HANDLE, 0);
00158 # elif defined (__hpux)
00159 
00160 #   if defined(__GNUC__) || __cplusplus >= 199707L
00161   ACE_OSCALL_RETURN (::shl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
00162 #   else
00163   ACE_OSCALL_RETURN (::cxxshl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
00164 #   endif  /* aC++ vs. Hp C++ */
00165 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
00166   MODULE* handle = 0;
00167   // Open readonly
00168   ACE_HANDLE filehandle = ACE_OS::open (fname,
00169                                         O_RDONLY,
00170                                         ACE_DEFAULT_FILE_PERMS);
00171 
00172   if (filehandle != ACE_INVALID_HANDLE)
00173     {
00174       ACE_OS::last_error(0);
00175       ACE_OSCALL ( ::loadModule (filehandle, LOAD_GLOBAL_SYMBOLS|LOAD_COMMON_MATCH_ALL ), MODULE *, 0, handle);
00176       int loaderror = ACE_OS::last_error();
00177       ACE_OS::close (filehandle);
00178 
00179       if ( (loaderror != 0) && (handle != 0) )
00180         {
00181           // ouch something went wrong most likely unresolved externals
00182           if (handle)
00183             ::unldByModuleId ( handle, 0 );
00184           handle = 0;
00185         }
00186     }
00187   else
00188     {
00189       // couldn't open file
00190       handle = 0;
00191     }
00192   return handle;
00193 # else
00194   ACE_UNUSED_ARG (fname);
00195   ACE_UNUSED_ARG (mode);
00196   ACE_NOTSUP_RETURN (0);
00197 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00198 }
00199 
00200 ACE_INLINE void *
00201 ACE_OS::dlsym (ACE_SHLIB_HANDLE handle,
00202                const ACE_TCHAR *sname)
00203 {
00204   ACE_OS_TRACE ("ACE_OS::dlsym");
00205 
00206 #if defined (ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE)
00207   // Check if the handle is valid before making any calls using it.
00208   if (handle == ACE_SHLIB_INVALID_HANDLE)
00209     return 0;
00210 #endif /* ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE */
00211 
00212   // Get the correct OS type.
00213 #if defined (ACE_HAS_WINCE)
00214   // CE (at least thru Pocket PC 2003) offers GetProcAddressW, not ...A, so
00215   // we always need a wide-char string.
00216   const wchar_t *symbolname = 0;
00217 #  if defined (ACE_USES_WCHAR)
00218   symbolname = sname;
00219 #  else
00220   ACE_Ascii_To_Wide sname_xlate (sname);
00221   symbolname = sname_xlate.wchar_rep ();
00222 #  endif /* ACE_USES_WCHAR */
00223 #elif defined (ACE_USES_WCHAR)
00224   // WinCE is WCHAR always; other platforms need a char * symbol name
00225   ACE_Wide_To_Ascii w_sname (sname);
00226   char *symbolname = w_sname.char_rep ();
00227 #elif defined (ACE_VXWORKS)
00228   char *symbolname = const_cast<char *> (sname);
00229 #else
00230   const char *symbolname = sname;
00231 #endif /* ACE_HAS_WINCE */
00232 
00233 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00234 
00235 #   if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
00236   int l = ACE_OS::strlen (symbolname) + 2;
00237   char *asm_symbolname = 0;
00238   ACE_NEW_RETURN (asm_symbolname, char[l], 0);
00239   ACE_OS::strcpy (asm_symbolname, "_") ;
00240   ACE_OS::strcpy (asm_symbolname + 1, symbolname) ;
00241   void *ace_result;
00242   ACE_OSCALL (::dlsym (handle, asm_symbolname), void *, 0, ace_result);
00243   delete [] asm_symbolname;
00244   return ace_result;
00245 #   elif defined (_M_UNIX)
00246   ACE_OSCALL_RETURN (::_dlsym (handle, symbolname), void *, 0);
00247 #   else
00248   ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0);
00249 #   endif /* ACE_USES_ASM_SYMBOL_IN_DLSYM */
00250 
00251 # elif defined (ACE_WIN32)
00252 
00253   ACE_WIN32CALL_RETURN (::GetProcAddress (handle, symbolname), void *, 0);
00254 
00255 # elif defined (__hpux)
00256 
00257   void *value;
00258   int status;
00259   shl_t _handle = handle;
00260   ACE_OSCALL (::shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value), int, -1, status);
00261   return status == 0 ? value : 0;
00262 
00263 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
00264 
00265   // For now we use the VxWorks global symbol table
00266   // which resolves the most recently loaded symbols .. which resolve mostly what we want..
00267   ACE_UNUSED_ARG (handle);
00268   SYM_TYPE symtype;
00269   void *value = 0;
00270   STATUS status;
00271   ACE_OSCALL (::symFindByName(sysSymTbl, symbolname, (char **)&value, &symtype), int, -1, status);
00272 
00273   return status == OK ? value : 0;
00274 
00275 # else
00276 
00277   ACE_UNUSED_ARG (handle);
00278   ACE_UNUSED_ARG (symbolname);
00279   ACE_NOTSUP_RETURN (0);
00280 
00281 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00282 }
00283 
00284 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:57 2006 for ACE by doxygen 1.3.6