OS_NS_dlfcn.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // $Id: OS_NS_dlfcn.inl 80826 2008-03-04 14:51:23Z wotte $
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_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   //FUZZ: disable check_for_lack_ACE_OS
00099   ACE_OSCALL_RETURN (::strerror(errno), char *, 0);
00100   //FUZZ: enable check_for_lack_ACE_OS
00101 # elif defined (ACE_WIN32)
00102   static ACE_TCHAR buf[128];
00103 #   if defined (ACE_HAS_PHARLAP)
00104   ACE_OS::sprintf (buf, "error code %d", GetLastError());
00105 #   else
00106   ACE_TEXT_FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
00107                           0,
00108                           ::GetLastError (),
00109                           0,
00110                           buf,
00111                           sizeof buf / sizeof buf[0],
00112                           0);
00113 #   endif /* ACE_HAS_PHARLAP */
00114   return buf;
00115 # else
00116   ACE_NOTSUP_RETURN (0);
00117 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00118 }
00119 
00120 ACE_INLINE ACE_SHLIB_HANDLE
00121 ACE_OS::dlopen (const ACE_TCHAR *fname,
00122                 int mode)
00123 {
00124   ACE_OS_TRACE ("ACE_OS::dlopen");
00125 
00126 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00127   void *handle;
00128 #   if defined (ACE_HAS_SGIDLADD)
00129   ACE_OSCALL
00130     (::sgidladd (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00131 #   elif defined (_M_UNIX)
00132   ACE_OSCALL
00133     (::_dlopen (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00134 #   else
00135   ACE_OSCALL
00136     (::dlopen (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
00137 #   endif /* ACE_HAS_SGIDLADD */
00138 #   if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
00139   if (handle != 0)
00140     {
00141       void *ptr;
00142       // Some systems (e.g., SunOS4) do not automatically call _init(), so
00143       // we'll have to call it manually.
00144 
00145       ACE_OSCALL (::dlsym (handle, ACE_TEXT ("_init")), void *, 0, ptr);
00146 
00147       if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1) // Call _init hook explicitly.
00148         {
00149           // Close down the handle to prevent leaks.
00150           ::dlclose (handle);
00151           return 0;
00152         }
00153     }
00154 #   endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
00155   return handle;
00156 # elif defined (ACE_WIN32)
00157   ACE_UNUSED_ARG (mode);
00158 
00159   ACE_WIN32CALL_RETURN (ACE_TEXT_LoadLibrary (fname), ACE_SHLIB_HANDLE, 0);
00160 # elif defined (__hpux)
00161 
00162 #   if defined(__GNUC__) || __cplusplus >= 199707L
00163   ACE_OSCALL_RETURN (::shl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
00164 #   else
00165   ACE_OSCALL_RETURN (::cxxshl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
00166 #   endif  /* aC++ vs. Hp C++ */
00167 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
00168   MODULE* handle = 0;
00169   // Open readonly
00170   ACE_HANDLE filehandle = ACE_OS::open (fname,
00171                                         O_RDONLY,
00172                                         ACE_DEFAULT_FILE_PERMS);
00173 
00174   if (filehandle != ACE_INVALID_HANDLE)
00175     {
00176       ACE_OS::last_error(0);
00177       ACE_OSCALL ( ::loadModule (filehandle, LOAD_GLOBAL_SYMBOLS|LOAD_COMMON_MATCH_ALL ), MODULE *, 0, handle);
00178       int loaderror = ACE_OS::last_error();
00179       ACE_OS::close (filehandle);
00180 
00181       if ( (loaderror != 0) && (handle != 0) )
00182         {
00183           // ouch something went wrong most likely unresolved externals
00184           if (handle)
00185             ::unldByModuleId ( handle, 0 );
00186           handle = 0;
00187         }
00188     }
00189   else
00190     {
00191       // couldn't open file
00192       handle = 0;
00193     }
00194   return handle;
00195 # else
00196   ACE_UNUSED_ARG (fname);
00197   ACE_UNUSED_ARG (mode);
00198   ACE_NOTSUP_RETURN (0);
00199 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00200 }
00201 
00202 ACE_INLINE void *
00203 ACE_OS::dlsym (ACE_SHLIB_HANDLE handle,
00204                const ACE_TCHAR *sname)
00205 {
00206   ACE_OS_TRACE ("ACE_OS::dlsym");
00207 
00208 #if defined (ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE)
00209   // Check if the handle is valid before making any calls using it.
00210   if (handle == ACE_SHLIB_INVALID_HANDLE)
00211     return 0;
00212 #endif /* ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE */
00213 
00214   // Get the correct OS type.
00215 #if defined (ACE_HAS_WINCE)
00216   // CE (at least thru Pocket PC 2003) offers GetProcAddressW, not ...A, so
00217   // we always need a wide-char string.
00218   const wchar_t *symbolname = 0;
00219 #  if defined (ACE_USES_WCHAR)
00220   symbolname = sname;
00221 #  else
00222   ACE_Ascii_To_Wide sname_xlate (sname);
00223   symbolname = sname_xlate.wchar_rep ();
00224 #  endif /* ACE_USES_WCHAR */
00225 #elif defined (ACE_USES_WCHAR)
00226   // WinCE is WCHAR always; other platforms need a char * symbol name
00227   ACE_Wide_To_Ascii w_sname (sname);
00228   char *symbolname = w_sname.char_rep ();
00229 #elif defined (ACE_VXWORKS)
00230   char *symbolname = const_cast<char *> (sname);
00231 #else
00232   const char *symbolname = sname;
00233 #endif /* ACE_HAS_WINCE */
00234 
00235 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
00236 
00237 #   if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
00238   int l = ACE_OS::strlen (symbolname) + 2;
00239   char *asm_symbolname = 0;
00240   ACE_NEW_RETURN (asm_symbolname, char[l], 0);
00241   ACE_OS::strcpy (asm_symbolname, "_") ;
00242   ACE_OS::strcpy (asm_symbolname + 1, symbolname) ;
00243   void *ace_result;
00244   ACE_OSCALL (::dlsym (handle, asm_symbolname), void *, 0, ace_result);
00245   delete [] asm_symbolname;
00246   return ace_result;
00247 #   elif defined (_M_UNIX)
00248   ACE_OSCALL_RETURN (::_dlsym (handle, symbolname), void *, 0);
00249 #   else
00250   ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0);
00251 #   endif /* ACE_USES_ASM_SYMBOL_IN_DLSYM */
00252 
00253 # elif defined (ACE_WIN32)
00254 
00255   ACE_WIN32CALL_RETURN (::GetProcAddress (handle, symbolname), void *, 0);
00256 
00257 # elif defined (__hpux)
00258 
00259   void *value = 0;
00260   int status;
00261   shl_t _handle = handle;
00262   ACE_OSCALL (::shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value), int, -1, status);
00263   return status == 0 ? value : 0;
00264 
00265 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
00266 
00267   // For now we use the VxWorks global symbol table
00268   // which resolves the most recently loaded symbols .. which resolve mostly what we want..
00269   ACE_UNUSED_ARG (handle);
00270   SYM_TYPE symtype;
00271   char *value = 0;
00272   STATUS status;
00273   ACE_OSCALL (::symFindByName(sysSymTbl, symbolname, &value, &symtype), int, -1, status);
00274 
00275   return status == OK ? reinterpret_cast <void*>(value) : 0;
00276 
00277 # else
00278 
00279   ACE_UNUSED_ARG (handle);
00280   ACE_UNUSED_ARG (symbolname);
00281   ACE_NOTSUP_RETURN (0);
00282 
00283 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
00284 }
00285 
00286 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7