Lib_Find.cpp

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

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