Correct feature names
[ACE_TAO.git] / ACE / ace / OS_NS_dlfcn.inl
blobdb5e15f57abad9b2d8e7caf6c7e7f582790b86a2
1 // -*- C++ -*-
2 #include "ace/OS_NS_macros.h"
3 #include "ace/OS_NS_errno.h"
4 #include "ace/OS_NS_fcntl.h"
5 #include "ace/OS_NS_string.h"
6 #include "ace/OS_NS_unistd.h"
7 #include "ace/Default_Constants.h"
8 #include "ace/os_include/os_fcntl.h"
9 #include "ace/os_include/os_string.h"
11 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
12 # include "ace/OS_NS_stdio.h"
13 #endif
15 #if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
16 #  include "ace/OS_Memory.h"
17 #  include "ace/OS_NS_string.h"
18 #endif /* ACE_USES_ASM_SYMBOL_IN_DLSYM */
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 ACE_INLINE int
23 ACE_OS::dlclose (ACE_SHLIB_HANDLE handle)
25   ACE_OS_TRACE ("ACE_OS::dlclose");
26 #if defined (ACE_LACKS_DLCLOSE)
27   ACE_UNUSED_ARG (handle);
28   return 0;
29 #elif defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
31 # if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
32   // SunOS4 does not automatically call _fini()!
33   void *ptr;
35   ACE_OSCALL (::dlsym (handle, ACE_TEXT ("_fini")), void *, 0, ptr);
37   if (ptr != 0)
38     (*((int (*)(void)) ptr)) (); // Call _fini hook explicitly.
39 # endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
40   ACE_OSCALL_RETURN (::dlclose (handle), int, -1);
41 #elif defined (ACE_WIN32)
42   ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::FreeLibrary (handle), ace_result_), int, -1);
43 #elif defined (__hpux)
44   // HP-UX 10.x and 32-bit 11.00 do not pay attention to the ref count
45   // when unloading a dynamic lib.  So, if the ref count is more than
46   // 1, do not unload the lib.  This will cause a library loaded more
47   // than once to not be unloaded until the process runs down, but
48   // that's life.  It's better than unloading a library that's in use.
49   // So far as I know, there's no way to decrement the refcnt that the
50   // kernel is looking at - the shl_descriptor is a copy of what the
51   // kernel has, not the actual struct.  On 64-bit HP-UX using dlopen,
52   // this problem has been fixed.
53   struct shl_descriptor  desc;
54   if (shl_gethandle_r (handle, &desc) == -1)
55     return -1;
56   if (desc.ref_count > 1)
57     return 0;
58 # if defined(__GNUC__) || __cplusplus >= 199707L
59   ACE_OSCALL_RETURN (::shl_unload (handle), int, -1);
60 # else
61   ACE_OSCALL_RETURN (::cxxshl_unload (handle), int, -1);
62 # endif  /* aC++ vs. Hp C++ */
63 #else
64   ACE_UNUSED_ARG (handle);
65   ACE_NOTSUP_RETURN (-1);
66 #endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
69 ACE_INLINE ACE_TCHAR *
70 ACE_OS::dlerror (void)
72   ACE_OS_TRACE ("ACE_OS::dlerror");
73 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
74   const char *err = 0;
75   ACE_OSCALL (::dlerror (), const char *, 0, err);
76   if (err == 0)
77     return 0;
78 #   if defined (ACE_USES_WCHAR)
79   const size_t BufLen = 256;
80   static wchar_t buf[BufLen];
81   ACE_OS::strncpy (buf, ACE_TEXT_CHAR_TO_TCHAR (err), BufLen);
82   return buf;
83 #   else
84   return const_cast <char *> (err);
85 #   endif /* ACE_USES_WCHAR */
86 # elif defined (__hpux) || defined (ACE_VXWORKS)
87   //FUZZ: disable check_for_lack_ACE_OS
88   ACE_OSCALL_RETURN (::strerror(errno), char *, 0);
89   //FUZZ: enable check_for_lack_ACE_OS
90 # elif defined (ACE_WIN32)
91   static ACE_TCHAR buf[128];
92 #   if defined (ACE_HAS_PHARLAP)
93   ACE_OS::sprintf (buf, "error code %d", GetLastError());
94 #   else
95   ACE_TEXT_FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
96                           0,
97                           ::GetLastError (),
98                           0,
99                           buf,
100                           sizeof buf / sizeof buf[0],
101                           0);
102 #   endif /* ACE_HAS_PHARLAP */
103   return buf;
104 # else
105   ACE_NOTSUP_RETURN (0);
106 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
109 ACE_INLINE ACE_SHLIB_HANDLE
110 ACE_OS::dlopen (const ACE_TCHAR *fname,
111                 int mode)
113   ACE_OS_TRACE ("ACE_OS::dlopen");
115 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
116   void *handle;
117   ACE_OSCALL (::dlopen (ACE_TEXT_ALWAYS_CHAR (fname), mode), void *, 0, handle);
118 #   if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
119   if (handle != 0)
120     {
121       void *ptr;
122       // Some systems (e.g., SunOS4) do not automatically call _init(), so
123       // we'll have to call it manually.
125       ACE_OSCALL (::dlsym (handle, ACE_TEXT ("_init")), void *, 0, ptr);
127       if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1) // Call _init hook explicitly.
128         {
129           // Close down the handle to prevent leaks.
130           ::dlclose (handle);
131           return 0;
132         }
133     }
134 #   endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
135   return handle;
136 # elif defined (ACE_WIN32)
137   ACE_UNUSED_ARG (mode);
139   ACE_WIN32CALL_RETURN (ACE_TEXT_LoadLibrary (fname), ACE_SHLIB_HANDLE, 0);
140 # elif defined (__hpux)
142 #   if defined(__GNUC__) || __cplusplus >= 199707L
143   ACE_OSCALL_RETURN (::shl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
144 #   else
145   ACE_OSCALL_RETURN (::cxxshl_load(fname, mode, 0L), ACE_SHLIB_HANDLE, 0);
146 #   endif  /* aC++ vs. Hp C++ */
147 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
148   ACE_UNUSED_ARG (mode);
149   MODULE* handle = 0;
150   // Open readonly
151   ACE_HANDLE filehandle = ACE_OS::open (fname,
152                                         O_RDONLY,
153                                         ACE_DEFAULT_FILE_PERMS);
155   if (filehandle != ACE_INVALID_HANDLE)
156     {
157       ACE_OS::last_error(0);
158       ACE_OSCALL ( ::loadModule (filehandle, LOAD_GLOBAL_SYMBOLS|LOAD_COMMON_MATCH_ALL ), MODULE *, 0, handle);
159       int loaderror = ACE_OS::last_error();
160       ACE_OS::close (filehandle);
162       if ( (loaderror != 0) && (handle != 0) )
163         {
164           // ouch something went wrong most likely unresolved externals
165           if (handle)
166             ::unldByModuleId ( handle, 0 );
167           handle = 0;
168         }
169     }
170   else
171     {
172       // couldn't open file
173       handle = 0;
174     }
175   return handle;
176 # else
177   ACE_UNUSED_ARG (fname);
178   ACE_UNUSED_ARG (mode);
179   ACE_NOTSUP_RETURN (0);
180 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
183 ACE_INLINE void *
184 ACE_OS::dlsym (ACE_SHLIB_HANDLE handle,
185                const ACE_TCHAR *sname)
187   ACE_OS_TRACE ("ACE_OS::dlsym");
189 #if defined (ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE)
190   // Check if the handle is valid before making any calls using it.
191   if (handle == ACE_SHLIB_INVALID_HANDLE)
192     return 0;
193 #endif /* ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE */
195   // Get the correct OS type.
196 #if defined (ACE_HAS_WINCE)
197   // CE (at least thru Pocket PC 2003) offers GetProcAddressW, not ...A, so
198   // we always need a wide-char string.
199   const wchar_t *symbolname = 0;
200 #  if defined (ACE_USES_WCHAR)
201   symbolname = sname;
202 #  else
203   ACE_Ascii_To_Wide sname_xlate (sname);
204   symbolname = sname_xlate.wchar_rep ();
205 #  endif /* ACE_USES_WCHAR */
206 #elif defined (ACE_USES_WCHAR)
207   // WinCE is WCHAR always; other platforms need a char * symbol name
208   ACE_Wide_To_Ascii w_sname (sname);
209   char *symbolname = w_sname.char_rep ();
210 #elif defined (ACE_VXWORKS)
211   char *symbolname = const_cast<char *> (sname);
212 #else
213   const char *symbolname = sname;
214 #endif /* ACE_HAS_WINCE */
216 # if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
218 #   if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
219   int l = ACE_OS::strlen (symbolname) + 2;
220   char *asm_symbolname = 0;
221   ACE_NEW_RETURN (asm_symbolname, char[l], 0);
222   ACE_OS::strcpy (asm_symbolname, "_") ;
223   ACE_OS::strcpy (asm_symbolname + 1, symbolname) ;
224   void *ace_result;
225   ACE_OSCALL (::dlsym (handle, asm_symbolname), void *, 0, ace_result);
226   delete [] asm_symbolname;
227   return ace_result;
228 #   else
229   ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0);
230 #   endif /* ACE_USES_ASM_SYMBOL_IN_DLSYM */
232 # elif defined (ACE_WIN32)
234   ACE_WIN32CALL_RETURN (::GetProcAddress (handle, symbolname), void *, 0);
236 # elif defined (__hpux)
238   void *value = 0;
239   int status;
240   shl_t _handle = handle;
241   ACE_OSCALL (::shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value), int, -1, status);
242   return status == 0 ? value : 0;
244 # elif defined (ACE_VXWORKS) && !defined (__RTP__)
246   // For now we use the VxWorks global symbol table
247   // which resolves the most recently loaded symbols, which resolve
248   // mostly what we want..
249   ACE_UNUSED_ARG (handle);
250 #if (ACE_VXWORKS < 0x690)
251   SYM_TYPE symtype;
252   char *value = 0;
253   STATUS status;
254   ACE_OSCALL (::symFindByName(sysSymTbl, symbolname, &value, &symtype), int, -1, status);
256   return status == OK ? reinterpret_cast <void*>(value) : 0;
257 #else
258   STATUS status;
260   SYMBOL_DESC symbolDesc;     /* symFind() descriptor */
261   ACE_OS::memset (&symbolDesc, 0, sizeof (SYMBOL_DESC));
262   symbolDesc.mask = SYM_FIND_BY_NAME;
263   symbolDesc.name = symbolname;
265   ACE_OSCALL (::symFind(sysSymTbl, &symbolDesc), int, -1, status);
267   return status == OK ? reinterpret_cast <void*>(symbolDesc.value) : 0;
268 #endif /* (ACE_VXWORKS < 0x690) */
270 # else
272   ACE_UNUSED_ARG (handle);
273   ACE_UNUSED_ARG (symbolname);
274   ACE_NOTSUP_RETURN (0);
276 # endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
279 ACE_END_VERSIONED_NAMESPACE_DECL