Lib_Find.cpp

Go to the documentation of this file.
00001 // $Id: Lib_Find.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/Lib_Find.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/OS_NS_stdio.h"
00008 #include "ace/OS_NS_unistd.h"
00009 #include "ace/OS_NS_stdlib.h"
00010 #include "ace/OS_Memory.h"
00011 #include "ace/OS_NS_fcntl.h"
00012 
00013 #if defined (ACE_WIN32)
00014 #  include "ace/OS_NS_strings.h"
00015 #endif /* ACE_WIN32 */
00016 
00017 #if defined (ACE_OPENVMS)
00018 #include "ace/RB_Tree.h"
00019 #include "ace/Thread_Mutex.h"
00020 #include "ace/Singleton.h"
00021 
00022 #include /**/ "descrip.h"
00023 #include /**/ "chfdef.h"
00024 #include /**/ "stsdef.h"
00025 #include /**/ "libdef.h"
00026 
00027 extern "C" int LIB$FIND_IMAGE_SYMBOL(...);
00028 
00029 class ACE_LD_Symbol_Registry
00030 {
00031   // @internal
00032   // = TITLE
00033   //   Implements a class to register symbols and addresses for use with DLL
00034   //   symbol retrieval.
00035   //
00036   // = DESCRIPTION
00037   //   OpenVMS restricts symbol length to 31 characters encoding any symbols
00038   //   longer than that. In these cases dlsym() only works with the encoded
00039   //   names.
00040   //   This creates serious problems for the service configurator framework
00041   //   where the factory method names often exceed 31 chars and where loading
00042   //   is based on retrieval of method pointers using the *full* name.
00043   //   For OpenVMS we therefor added this singleton class and the
00044   //   ACE_Dynamic_Svc_Registrar class which registers full names and function
00045   //   pointers with this singleton at the time the static ACE_Dynamic_Svc_Registrar
00046   //   object is created in a (service) DLL.
00047   //   By forcing the DLL to load using a common symbol ("NULL") we trigger static
00048   //   object creation *before* the full names are referenced.
00049   //   Symbol references will be resolved as follows on OpenVMS:
00050   //   - first try directly from DLL using the RTL dlsym() function and if that fails;
00051   //   - try to find symbol in singleton registry.
00052 public:
00053 
00054   typedef ACE_RB_Tree<const ACE_TCHAR*,
00055                       void*,
00056                       ACE_Less_Than<const ACE_TCHAR*>,
00057                       ACE_Thread_Mutex>
00058           TREE;
00059 
00060   void register_symbol (const ACE_TCHAR* symname, void* symaddr);
00061 
00062   void* find_symbol (const ACE_TCHAR* symname);
00063 
00064   ACE_LD_Symbol_Registry () {}
00065 private:
00066 
00067   TREE symbol_registry_;
00068 };
00069 
00070 void
00071 ACE_LD_Symbol_Registry::register_symbol (const ACE_TCHAR* symname,
00072                                          void* symaddr)
00073 {
00074   int const result = symbol_registry_.bind (symname, symaddr);
00075   if (result == 1)
00076     {
00077       ACE_DEBUG((LM_INFO, ACE_TEXT ("ACE_LD_Symbol_Registry:")
00078                           ACE_TEXT (" duplicate symbol %s registered\n"),
00079                           ACE_TEXT_ALWAYS_CHAR (symname)));
00080     }
00081   else if (result == -1)
00082     {
00083       ACE_ERROR((LM_ERROR, ACE_TEXT ("ACE_LD_Symbol_Registry:")
00084                            ACE_TEXT (" failed to register symbol %s\n"),
00085                            ACE_TEXT_ALWAYS_CHAR (symname)));
00086     }
00087 }
00088 
00089 void*
00090 ACE_LD_Symbol_Registry::find_symbol (const ACE_TCHAR* symname)
00091 {
00092   void* symaddr = 0;
00093   int const result = symbol_registry_.find (symname, symaddr);
00094 
00095   return (result == 0 ? symaddr : 0);
00096 }
00097 
00098 /// Declare a process wide singleton
00099 ACE_SINGLETON_DECLARE (ACE_Singleton,
00100                        ACE_LD_Symbol_Registry,
00101                        ACE_Thread_Mutex)
00102 
00103 typedef ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>
00104         ACE_LD_SYMBOL_REGISTRY;
00105 
00106 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00107 template ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex> *
00108   ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>::singleton_;
00109 #endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
00110 #endif
00111 
00112 ACE_RCSID(ace, Lib_Find, "$Id: Lib_Find.cpp 80826 2008-03-04 14:51:23Z wotte $")
00113 
00114 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00115 
00116 int
00117 ACE::ldfind (const ACE_TCHAR* filename,
00118              ACE_TCHAR pathname[],
00119              size_t maxpathnamelen)
00120 {
00121   ACE_TRACE ("ACE::ldfind");
00122 #if defined (ACE_OPENVMS)
00123   if (ACE_OS::strlen(filename) >= maxpathnamelen)
00124   {
00125     errno = ENOMEM;
00126     return -1;
00127   }
00128 
00129   dsc$descriptor nameDsc;
00130   nameDsc.dsc$b_class = DSC$K_CLASS_S;
00131   nameDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00132   nameDsc.dsc$w_length = ACE_OS::strlen(filename);
00133   nameDsc.dsc$a_pointer = (char*)filename;
00134 
00135   char symbol[] = "NULL";
00136   dsc$descriptor symbolDsc;
00137   symbolDsc.dsc$b_class = DSC$K_CLASS_S;
00138   symbolDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00139   symbolDsc.dsc$w_length = ACE_OS::strlen(symbol);
00140   symbolDsc.dsc$a_pointer = symbol;
00141 
00142   int symbolValue;
00143   int result;
00144   try
00145   {
00146     result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00147   }
00148   catch (chf$signal_array& sig)
00149   {
00150     result = sig.chf$l_sig_name;
00151   }
00152 
00153   int severity = result & STS$M_SEVERITY;
00154   int conditionId = result & STS$M_COND_ID;
00155   if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00156       (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00157   {
00158     ACE_OS::strcpy(pathname, filename);
00159     return 0;
00160   }
00161 
00162   if (ACE_OS::strlen(filename) + ACE_OS::strlen(ACE_DLL_PREFIX) >= maxpathnamelen)
00163   {
00164     errno = ENOMEM;
00165     return -1;
00166   }
00167 
00168 
00169   ACE_OS::strcpy(pathname, ACE_DLL_PREFIX);
00170   ACE_OS::strcat(pathname, filename);
00171   nameDsc.dsc$w_length = ACE_OS::strlen(pathname);
00172   nameDsc.dsc$a_pointer = pathname;
00173   try
00174   {
00175     result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00176   }
00177   catch (chf$signal_array& sig)
00178   {
00179     result = sig.chf$l_sig_name;
00180   }
00181 
00182   severity = result & STS$M_SEVERITY;
00183   conditionId = result & STS$M_COND_ID;
00184   if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00185       (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00186   {
00187     return 0;
00188   }
00189   errno = ENOENT;
00190   return -1;
00191 #endif /* ACE_OPENVMS */
00192 
00193 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && \
00194     !defined (ACE_HAS_PHARLAP)
00195   ACE_TCHAR expanded_filename[MAXPATHLEN];
00196   if (ACE_TEXT_ExpandEnvironmentStrings (filename,
00197                                          expanded_filename,
00198                                          sizeof expanded_filename
00199                                          / sizeof (ACE_TCHAR)))
00200     filename = expanded_filename;
00201 #endif /* ACE_WIN32 && !ACE_HAS_WINCE && !ACE_HAS_PHARLAP */
00202 
00203   ACE_TCHAR tempcopy[MAXPATHLEN + 1];
00204   ACE_TCHAR searchpathname[MAXPATHLEN + 1];
00205 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00206   ACE_TCHAR decorator[] = ACE_LD_DECORATOR_STR;
00207   ACE_TCHAR searchfilename[MAXPATHLEN + sizeof(decorator) / sizeof (ACE_TCHAR)];
00208 #else
00209   ACE_TCHAR searchfilename[MAXPATHLEN + 1];
00210 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00211 
00212   // Create a copy of filename to work with.
00213   if (ACE_OS::strlen (filename) + 1
00214       > (sizeof tempcopy / sizeof (ACE_TCHAR)))
00215     {
00216       errno = ENOMEM;
00217       return -1;
00218     }
00219   else
00220     ACE_OS::strcpy (tempcopy, filename);
00221 
00222   // Insert canonical directory separators.
00223   ACE_TCHAR *separator_ptr;
00224 
00225 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00226   // Make all the directory separators "canonical" to simplify
00227   // subsequent code.
00228   ACE::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
00229 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
00230 
00231   // Separate filename from pathname.
00232   separator_ptr = ACE_OS::strrchr (tempcopy, '/');
00233 
00234   // This is a relative path.
00235   if (separator_ptr == 0)
00236     {
00237       searchpathname[0] = '\0';
00238       ACE_OS::strcpy (searchfilename, tempcopy);
00239     }
00240   else // This is an absolute path.
00241     {
00242       ACE_OS::strcpy (searchfilename, separator_ptr + 1);
00243       separator_ptr[1] = '\0';
00244       ACE_OS::strcpy (searchpathname, tempcopy);
00245     }
00246 
00247   bool has_suffix = false;
00248 
00249   // Check to see if this has an appropriate DLL suffix for the OS
00250   // platform.
00251   ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
00252 
00253   const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
00254 
00255   if (s != 0)
00256     {
00257       // If we have a dot, we have a suffix
00258       has_suffix = true;
00259 
00260       // Check whether this matches the appropriate platform-specific
00261       // suffix.
00262 #if defined (ACE_WIN32)
00263       // Use <ACE_OS::strcasecmp> on any platform with
00264       // case-insensitive filenames.
00265       if (ACE_OS::strcasecmp (s, dll_suffix) != 0)
00266 #else
00267       if (ACE_OS::strcmp (s, dll_suffix) != 0)
00268 #endif /* ACE_WIN32 */
00269         {
00270           ACE_ERROR ((LM_WARNING,
00271                       ACE_TEXT ("Warning: improper suffix for a ")
00272                       ACE_TEXT ("shared library on this platform: %s\n"),
00273                       s));
00274         }
00275     }
00276 
00277   // Make sure we've got enough space in searchfilename.
00278   if (ACE_OS::strlen (searchfilename)
00279       + ACE_OS::strlen (ACE_DLL_PREFIX)
00280       + (has_suffix ? 0 : ACE_OS::strlen (dll_suffix))
00281       >= (sizeof searchfilename / sizeof (ACE_TCHAR)))
00282     {
00283       errno = ENOMEM;
00284       return -1;
00285     }
00286 
00287 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00288   size_t len_searchfilename = ACE_OS::strlen (searchfilename);
00289   if (! has_suffix)
00290     ACE_OS::strcpy (searchfilename + len_searchfilename,
00291                            decorator);
00292 
00293   for (int tag = 1; tag >= 0; tag --)
00294     {
00295       if (tag == 0)
00296         searchfilename [len_searchfilename] = 0;
00297 
00298 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00299       // Use absolute pathname if there is one.
00300       if (ACE_OS::strlen (searchpathname) > 0)
00301         {
00302           if (ACE_OS::strlen (searchfilename)
00303               + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
00304             {
00305               errno = ENOMEM;
00306               return -1;
00307             }
00308           else
00309             {
00310 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00311               // Revert to native path name separators.
00312               ACE::strrepl (searchpathname,
00313                             '/',
00314                             ACE_DIRECTORY_SEPARATOR_CHAR);
00315 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
00316               // First, try matching the filename *without* adding a
00317               // prefix.
00318               ACE_OS::sprintf (pathname,
00319                                ACE_TEXT ("%s%s%s"),
00320                                searchpathname,
00321                                searchfilename,
00322                                has_suffix ? ACE_TEXT ("") : dll_suffix);
00323               if (ACE_OS::access (pathname, F_OK) == 0)
00324                 return 0;
00325 
00326               // Second, try matching the filename *with* adding a prefix.
00327               ACE_OS::sprintf (pathname,
00328                                ACE_TEXT ("%s%s%s%s"),
00329                                searchpathname,
00330                                ACE_DLL_PREFIX,
00331                                searchfilename,
00332                                has_suffix ? ACE_TEXT ("") : dll_suffix);
00333               if (ACE_OS::access (pathname, F_OK) == 0)
00334                 return 0;
00335             }
00336         }
00337 
00338       // Use relative filenames via LD_LIBRARY_PATH or PATH (depending on
00339       // OS platform).
00340       else
00341         {
00342 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00343           ACE_TCHAR *file_component = 0;
00344           DWORD pathlen =
00345             ACE_TEXT_SearchPath (0,
00346                                  searchfilename,
00347                                  dll_suffix,
00348                                  static_cast<DWORD> (maxpathnamelen),
00349                                  pathname,
00350                                  &file_component);
00351           if (pathlen >= maxpathnamelen)
00352           {
00353               errno = ENOMEM;
00354               return -1;
00355           }
00356           else if (pathlen > 0)
00357               return 0;
00358 
00359           // In case not found we should try again with the ACE_DLL_PREFIX
00360           // prefixed
00361           ACE_OS::strcpy (searchfilename, ACE_DLL_PREFIX);
00362           ACE_OS::strcat (searchfilename, tempcopy);
00363           pathlen =
00364             ACE_TEXT_SearchPath (0,
00365                                  searchfilename,
00366                                  dll_suffix,
00367                                  static_cast<DWORD> (maxpathnamelen),
00368                                  pathname,
00369                                  &file_component);
00370           if (pathlen >= maxpathnamelen)
00371           {
00372               errno = ENOMEM;
00373               return -1;
00374           }
00375           else if (pathlen > 0)
00376               return 0;
00377 #else
00378           ACE_TCHAR *ld_path;
00379 #  if defined ACE_DEFAULT_LD_SEARCH_PATH
00380           ld_path = ACE_DEFAULT_LD_SEARCH_PATH;
00381 #  else
00382 #    if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
00383           ld_path = ACE_OS::getenv (ACE_LD_SEARCH_PATH);
00384 #    else
00385           // Wide-char, non-Windows only offers char * getenv. So capture
00386           // it, translate to wide-char, and continue.
00387           ACE_Ascii_To_Wide wide_ldpath
00388             (ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH)));
00389           ld_path = wide_ldpath.wchar_rep ();
00390 #    endif /* ACE_WIN32 || !ACE_USES_WCHAR */
00391 #  endif /* ACE_DEFAULT_LD_SEARCH_PATH */
00392 
00393 #if defined (ACE_HAS_WINCE)
00394             ACE_TCHAR *ld_path_temp = 0;
00395             if (ld_path != 0)
00396               {
00397                 ld_path_temp = (ACE_TCHAR *)
00398                   ACE_OS::malloc ((ACE_OS::strlen (ld_path) + 2)
00399                                   * sizeof (ACE_TCHAR));
00400                 if (ld_path_temp != 0)
00401                   {
00402                     ACE_OS::strcpy (ld_path_temp,
00403                                     ACE_LD_SEARCH_PATH_SEPARATOR_STR);
00404 
00405                     ACE_OS::strcat (ld_path_temp, ld_path);
00406                     ld_path = ld_path_temp;
00407                   }
00408                 else
00409                   {
00410                     ACE_OS::free ((void *) ld_path_temp);
00411                     ld_path = ld_path_temp = 0;
00412                   }
00413               }
00414 #endif /* ACE_HAS_WINCE */
00415 
00416           if (ld_path != 0
00417               && (ld_path = ACE_OS::strdup (ld_path)) != 0)
00418             {
00419               // strtok has the strange behavior of not separating the
00420               // string ":/foo:/bar" into THREE tokens.  One would expect
00421               // that the first iteration the token would be an empty
00422               // string, the second iteration would be "/foo", and the
00423               // third iteration would be "/bar".  However, this is not
00424               // the case; one only gets two iterations: "/foo" followed
00425               // by "/bar".
00426 
00427               // This is especially a problem in parsing Unix paths
00428               // because it is permissible to specify 'the current
00429               // directory' as an empty entry.  So, we introduce the
00430               // following special code to cope with this:
00431 
00432               // Look at each dynamic lib directory in the search path.
00433 
00434               ACE_TCHAR *nextholder = 0;
00435               const ACE_TCHAR *path_entry =
00436                 ACE::strsplit_r (ld_path,
00437                                  ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00438                                  nextholder);
00439               int result = 0;
00440 
00441               for (;;)
00442                 {
00443                   // Check if at end of search path.
00444                   if (path_entry == 0)
00445                     {
00446                       errno = ENOENT;
00447                       result = -1;
00448                       break;
00449                     }
00450                   else if (ACE_OS::strlen (path_entry)
00451                            + 1
00452                            + ACE_OS::strlen (searchfilename)
00453                            >= maxpathnamelen)
00454                     {
00455                       errno = ENOMEM;
00456                       result = -1;
00457                       break;
00458                     }
00459                   // This works around the issue where a path might have
00460                   // an empty component indicating 'current directory'.
00461                   // We need to do it here rather than anywhere else so
00462                   // that the loop condition will still work.
00463                   else if (path_entry[0] == '\0')
00464                     path_entry = ACE_TEXT (".");
00465 
00466                   // First, try matching the filename *without* adding a
00467                   // prefix.
00468                   ACE_OS::sprintf (pathname,
00469                                    ACE_TEXT ("%s%c%s%s"),
00470                                    path_entry,
00471                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00472                                    searchfilename,
00473                                    has_suffix ? ACE_TEXT ("") : dll_suffix);
00474                   if (ACE_OS::access (pathname, F_OK) == 0)
00475                     break;
00476 
00477                   // Second, try matching the filename *with* adding a
00478                   // prefix.
00479                   ACE_OS::sprintf (pathname,
00480                                    ACE_TEXT ("%s%c%s%s%s"),
00481                                    path_entry,
00482                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00483                                    ACE_DLL_PREFIX,
00484                                    searchfilename,
00485                                    has_suffix ? ACE_TEXT ("") : dll_suffix);
00486                   if (ACE_OS::access (pathname, F_OK) == 0)
00487                     break;
00488 
00489                   // Fetch the next item in the path
00490                   path_entry =
00491                     ACE::strsplit_r (0,
00492                                      ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00493                                      nextholder);
00494                 }
00495 
00496 #if defined (ACE_HAS_WINCE)
00497               if (ld_path_temp != 0)
00498                 ACE_OS::free (ld_path_temp);
00499 #endif /* ACE_HAS_WINCE */
00500               ACE_OS::free ((void *) ld_path);
00501 #if defined (ACE_HAS_WINCE) && defined (ACE_LD_DECORATOR_STR) && \
00502             !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00503                if (result == 0 || tag == 0)
00504 #endif /* ACE_HAS_WINCE && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00505               return result;
00506             }
00507 #endif /* ACE_WIN32 && !ACE_HAS_WINCE */
00508         }
00509 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00510     }
00511 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00512 
00513   errno = ENOENT;
00514   return -1;
00515 }
00516 
00517 FILE *
00518 ACE::ldopen (const ACE_TCHAR *filename,
00519              const ACE_TCHAR *type)
00520 {
00521   ACE_TRACE ("ACE::ldopen");
00522 
00523   ACE_TCHAR buf[MAXPATHLEN + 1];
00524   if (ACE::ldfind (filename,
00525                    buf,
00526                    sizeof (buf) /sizeof (ACE_TCHAR)) == -1)
00527     return 0;
00528   else
00529     return ACE_OS::fopen (buf, type);
00530 }
00531 
00532 ACE_TCHAR *
00533 ACE::ldname (const ACE_TCHAR *entry_point)
00534 {
00535   ACE_TRACE ("ACE::ldname");
00536 
00537 #if defined(ACE_NEEDS_DL_UNDERSCORE)
00538   size_t size =
00539     1 // leading '_'
00540     + ACE_OS::strlen (entry_point)
00541     + 1;
00542 
00543   ACE_TCHAR *new_name;
00544   ACE_NEW_RETURN (new_name,
00545                   ACE_TCHAR[size],
00546                   0);
00547 
00548   ACE_OS::strcpy (new_name, ACE_TEXT ("_"));
00549   ACE_OS::strcat (new_name, entry_point);
00550 
00551   return new_name;
00552 #else /* ACE_NEEDS_DL_UNDERSCORE */
00553   size_t size =
00554     ACE_OS::strlen (entry_point)
00555     + 1;
00556 
00557   ACE_TCHAR *new_name;
00558   ACE_NEW_RETURN (new_name,
00559                   ACE_TCHAR[size],
00560                   0);
00561 
00562   ACE_OS::strcpy (new_name, entry_point);
00563   return new_name;
00564 #endif /* ACE_NEEDS_DL_UNDERSCORE */
00565 }
00566 
00567 #if defined (ACE_OPENVMS)
00568 void
00569 ACE::ldregister (const ACE_TCHAR *entry_point,
00570                  void* entry_addr)
00571 {
00572   ACE_LD_SYMBOL_REGISTRY::instance ()->register_symbol (entry_point,
00573                                                         entry_addr);
00574 }
00575 
00576 void *
00577 ACE::ldsymbol (ACE_SHLIB_HANDLE sh, const ACE_TCHAR *entry_point)
00578 {
00579   void* symaddr = ACE_OS::dlsym (sh, entry_point);
00580   // if not found through dlsym() try registry
00581   if (symaddr == 0)
00582     symaddr = ACE_LD_SYMBOL_REGISTRY::instance ()->find_symbol (entry_point);
00583 
00584   return symaddr;
00585 }
00586 #endif
00587 
00588 int
00589 ACE::get_temp_dir (ACE_TCHAR *buffer, size_t buffer_len)
00590 {
00591   int result;
00592 #if defined (ACE_WIN32)
00593   result = ACE_TEXT_GetTempPath (static_cast<DWORD> (buffer_len),
00594                                  buffer);
00595 
00596   // Make sure to return -1 if there is an error
00597   if (result == 0 && ::GetLastError () != ERROR_SUCCESS
00598       || result > static_cast<int> (buffer_len))
00599     result = -1;
00600 
00601 #else /* ACE_WIN32 */
00602 
00603   // NOTE! Non-Windows platforms don't deal with wide chars for env.
00604   // variables, so do this narrow-char and convert to wide for the
00605   // caller if necessary.
00606 
00607   // On non-win32 platforms, check to see what the TMPDIR environment
00608   // variable is defined to be.  If it doesn't exist, just use /tmp
00609   const char *tmpdir = ACE_OS::getenv ("TMPDIR");
00610 
00611   if (tmpdir == 0)
00612     tmpdir = "/tmp";
00613 
00614   size_t len = ACE_OS::strlen (tmpdir);
00615 
00616   // Check to see if the buffer is large enough for the string,
00617   // another /, and its null character (hence the + 2)
00618   if ((len + 2) > buffer_len)
00619     {
00620       result = -1;
00621     }
00622   else
00623     {
00624       ACE_OS::strcpy (buffer, ACE_TEXT_CHAR_TO_TCHAR (tmpdir));
00625 
00626       // Add a trailing slash because we cannot assume there is already one
00627       // at the end.  And having an extra one should not cause problems.
00628       buffer[len] = ACE_TEXT ('/');
00629       buffer[len + 1] = 0;
00630       result = 0;
00631     }
00632 #endif /* ACE_WIN32 */
00633   return result;
00634 }
00635 
00636 ACE_HANDLE
00637 ACE::open_temp_file (const ACE_TCHAR *name, int mode, int perm)
00638 {
00639 #if defined (ACE_WIN32)
00640   ACE_UNUSED_ARG (perm);
00641   ACE_HANDLE handle = ACE_OS::open (name,
00642                                     mode,
00643                                     FILE_SHARE_READ
00644                                     | FILE_SHARE_WRITE
00645                                     | FILE_SHARE_DELETE);
00646 #else
00647   // Open it.
00648   ACE_HANDLE handle = ACE_OS::open (name, mode, perm);
00649 #endif /* ACE_WIN32 */
00650 
00651   if (handle == ACE_INVALID_HANDLE)
00652     return ACE_INVALID_HANDLE;
00653 
00654   // Unlink it so that the file will be removed automatically when the
00655   // process goes away.
00656   if (ACE_OS::unlink (name) == -1)
00657     return ACE_INVALID_HANDLE;
00658   else
00659     // Return the handle.
00660     return handle;
00661 }
00662 
00663 size_t
00664 ACE::strrepl (char *s, char search, char replace)
00665 {
00666   ACE_TRACE ("ACE::strrepl");
00667 
00668   size_t replaced = 0;
00669 
00670   for (size_t i = 0; s[i] != '\0'; i++)
00671     if (s[i] == search)
00672       {
00673         s[i] = replace;
00674         ++replaced;
00675       }
00676 
00677   return replaced;
00678 }
00679 
00680 
00681 // Split a string up into 'token'-delimited pieces, ala Perl's
00682 // "split".
00683 
00684 char *
00685 ACE::strsplit_r (char *str,
00686                  const char *token,
00687                  char *&next_start)
00688 {
00689   char *result = 0;
00690 
00691   if (str != 0)
00692     next_start = str;
00693 
00694   if (next_start != 0)
00695     {
00696       char *tok_loc = ACE_OS::strstr (next_start, token);
00697 
00698       if (tok_loc != 0)
00699         {
00700           // Return the beginning of the string.
00701           result = next_start;
00702 
00703           // Insure it's terminated.
00704           *tok_loc = '\0';
00705           next_start = tok_loc + ACE_OS::strlen (token);
00706         }
00707       else
00708         {
00709           result = next_start;
00710           next_start = (char *) 0;
00711         }
00712     }
00713 
00714   return result;
00715 }
00716 
00717 #if defined (ACE_HAS_WCHAR)
00718 wchar_t *
00719 ACE::strsplit_r (wchar_t *str,
00720                  const wchar_t *token,
00721                  wchar_t *&next_start)
00722 {
00723   wchar_t *result = 0;
00724 
00725   if (str != 0)
00726     next_start = str;
00727 
00728   if (next_start != 0)
00729     {
00730       wchar_t *tok_loc = ACE_OS::strstr (next_start, token);
00731 
00732       if (tok_loc != 0)
00733         {
00734           // Return the beginning of the string.
00735           result = next_start;
00736 
00737           // Insure it's terminated.
00738           *tok_loc = '\0';
00739           next_start = tok_loc + ACE_OS::strlen (token);
00740         }
00741       else
00742         {
00743           result = next_start;
00744           next_start = (wchar_t *) 0;
00745         }
00746     }
00747 
00748   return result;
00749 }
00750 
00751 size_t
00752 ACE::strrepl (wchar_t *s, wchar_t search, wchar_t replace)
00753 {
00754   ACE_TRACE ("ACE::strrepl");
00755 
00756   size_t replaced = 0;
00757 
00758   for (size_t i = 0; s[i] != '\0'; i++)
00759     if (s[i] == search)
00760       {
00761         s[i] = replace;
00762         ++replaced;
00763       }
00764 
00765   return replaced;
00766 }
00767 #endif /* ACE_HAS_WCHAR */
00768 
00769 ACE_END_VERSIONED_NAMESPACE_DECL

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