Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Lib_Find.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Lib_Find.cpp,v 1.1.1.2.2.1 2003/03/13 19:44:21 chad Exp $
00003 
00004 #include "ace/Lib_Find.h"
00005 #include "ace/Log_Msg.h"
00006 
00007 ACE_RCSID(ace, Lib_Find, "$Id: Lib_Find.cpp,v 1.1.1.2.2.1 2003/03/13 19:44:21 chad Exp $")
00008 
00009 
00010 #if ! defined (ACE_PSOS_DIAB_MIPS)
00011 int
00012 ACE_Lib_Find::ldfind (const ACE_TCHAR* filename,
00013                       ACE_TCHAR pathname[],
00014                       size_t maxpathnamelen)
00015 {
00016   ACE_TRACE ("ACE_Lib_Find::ldfind");
00017 
00018 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && \
00019     !defined (ACE_HAS_PHARLAP)
00020   ACE_TCHAR expanded_filename[MAXPATHLEN];
00021   if (ACE_TEXT_ExpandEnvironmentStrings (filename,
00022                                          expanded_filename,
00023                                          sizeof expanded_filename
00024                                          / sizeof (ACE_TCHAR)))
00025     filename = expanded_filename;
00026 #endif /* ACE_WIN32 && !ACE_HAS_WINCE && !ACE_HAS_PHARLAP */
00027 
00028   ACE_TCHAR tempcopy[MAXPATHLEN + 1];
00029   ACE_TCHAR searchpathname[MAXPATHLEN + 1];
00030 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00031   ACE_TCHAR decorator[] = ACE_LD_DECORATOR_STR;
00032   ACE_TCHAR searchfilename[MAXPATHLEN + sizeof(decorator) / sizeof (ACE_TCHAR)];
00033 #else
00034   ACE_TCHAR searchfilename[MAXPATHLEN + 1];
00035 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00036 
00037   // Create a copy of filename to work with.
00038   if (ACE_OS::strlen (filename) + 1
00039       > (sizeof tempcopy / sizeof (ACE_TCHAR)))
00040     {
00041       errno = ENOMEM;
00042       return -1;
00043     }
00044   else
00045     ACE_OS::strcpy (tempcopy, filename);
00046 
00047   // Insert canonical directory separators.
00048   ACE_TCHAR *separator_ptr;
00049 
00050 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00051   // Make all the directory separators "canonical" to simplify
00052   // subsequent code.
00053   ACE_Lib_Find::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
00054 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
00055 
00056   // Separate filename from pathname.
00057   separator_ptr = ACE_OS::strrchr (tempcopy, '/');
00058 
00059   // This is a relative path.
00060   if (separator_ptr == 0)
00061     {
00062       searchpathname[0] = '\0';
00063       ACE_OS::strcpy (searchfilename, tempcopy);
00064     }
00065   else // This is an absolute path.
00066     {
00067       ACE_OS::strcpy (searchfilename, separator_ptr + 1);
00068       separator_ptr[1] = '\0';
00069       ACE_OS::strcpy (searchpathname, tempcopy);
00070     }
00071 
00072   int got_suffix = 0;
00073 
00074   // Check to see if this has an appropriate DLL suffix for the OS
00075   // platform.
00076   ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
00077 
00078   const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
00079 
00080   if (s != 0)
00081     {
00082       // If we have a dot, we have a suffix
00083       got_suffix = 1;
00084 
00085       // Check whether this matches the appropriate platform-specific
00086       // suffix.
00087 #if defined (ACE_WIN32)
00088       // Use <ACE_OS::strcasecmp> on any platform with
00089       // case-insensitive filenames.
00090       if (ACE_OS::strcasecmp (s, dll_suffix) != 0)
00091 #else
00092       if (ACE_OS::strcmp (s, dll_suffix) != 0)
00093 #endif /* ACE_WIN32 */
00094         {
00095           ACE_ERROR ((LM_WARNING,
00096                       ACE_LIB_TEXT ("Warning: improper suffix for a ")
00097                       ACE_LIB_TEXT ("shared library on this platform: %s\n"),
00098                       s));
00099         }
00100     }
00101 
00102   // Make sure we've got enough space in searchfilename.
00103   if (ACE_OS::strlen (searchfilename)
00104       + ACE_OS::strlen (ACE_DLL_PREFIX)
00105       + got_suffix ? 0 : ACE_OS::strlen (dll_suffix) >= (sizeof searchfilename /
00106                                                          sizeof (ACE_TCHAR)))
00107     {
00108       errno = ENOMEM;
00109       return -1;
00110     }
00111 
00112 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00113   size_t len_searchfilename = ACE_OS::strlen (searchfilename);
00114   if (! got_suffix)
00115     ACE_OS_String::strcpy (searchfilename + len_searchfilename,
00116                            decorator);
00117 
00118   for (int tag = 1; tag >= 0; tag --)
00119     {
00120       if (tag == 0)
00121         searchfilename [len_searchfilename] = 0;
00122 
00123 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00124       // Use absolute pathname if there is one.
00125       if (ACE_OS::strlen (searchpathname) > 0)
00126         {
00127           if (ACE_OS::strlen (searchfilename)
00128               + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
00129             {
00130               errno = ENOMEM;
00131               return -1;
00132             }
00133           else
00134             {
00135 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00136               // Revert to native path name separators.
00137               ACE_Lib_Find::strrepl (searchpathname,
00138                                      '/',
00139                                      ACE_DIRECTORY_SEPARATOR_CHAR);
00140 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
00141               // First, try matching the filename *without* adding a
00142               // prefix.
00143 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00144               ACE_OS::sprintf (pathname,
00145                                ACE_LIB_TEXT ("%s%s%s"),
00146                                searchpathname,
00147                                searchfilename,
00148                                got_suffix ? ACE_static_cast (ACE_TCHAR *,
00149                                                              ACE_LIB_TEXT (""))
00150                                : ACE_static_cast (ACE_TCHAR *,
00151                                                   dll_suffix));
00152 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00153               ACE_OS::sprintf (pathname,
00154                                ACE_LIB_TEXT ("%s%s%s"),
00155                                searchpathname,
00156                                searchfilename,
00157                                got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00158 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00159               if (ACE_OS::access (pathname, F_OK) == 0)
00160                 return 0;
00161 
00162               // Second, try matching the filename *with* adding a prefix.
00163 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00164               ACE_OS::sprintf (pathname,
00165                                ACE_LIB_TEXT ("%s%s%s%s"),
00166                                searchpathname,
00167                                ACE_DLL_PREFIX,
00168                                searchfilename,
00169                                got_suffix ? ACE_static_cast (ACE_TCHAR *,
00170                                                              ACE_LIB_TEXT (""))
00171                                : ACE_static_cast (ACE_TCHAR *,
00172                                                   dll_suffix));
00173 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00174               ACE_OS::sprintf (pathname,
00175                                ACE_LIB_TEXT ("%s%s%s%s"),
00176                                searchpathname,
00177                                ACE_DLL_PREFIX,
00178                                searchfilename,
00179                                got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00180 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00181               if (ACE_OS::access (pathname, F_OK) == 0)
00182                 return 0;
00183             }
00184         }
00185 
00186       // Use relative filenames via LD_LIBRARY_PATH or PATH (depending on
00187       // OS platform).
00188       else
00189         {
00190 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00191           ACE_TCHAR *file_component = 0;
00192           DWORD pathlen = ACE_TEXT_SearchPath (0,
00193                                                searchfilename,
00194                                                dll_suffix,
00195                                                ACE_static_cast (DWORD,
00196                                                                maxpathnamelen),
00197                                                pathname,
00198                                                &file_component);
00199           if (pathlen >= maxpathnamelen)
00200           {
00201               errno = ENOMEM;
00202               return -1;
00203           }
00204           else if (pathlen > 0)
00205               return 0;
00206 #else
00207           ACE_TCHAR *ld_path =
00208 #if defined ACE_DEFAULT_LD_SEARCH_PATH
00209             ACE_DEFAULT_LD_SEARCH_PATH;
00210 #else
00211             ACE_OS::getenv (ACE_LD_SEARCH_PATH);
00212 #endif /* ACE_DEFAULT_LD_SEARCH_PATH */
00213 
00214 #if defined (ACE_HAS_WINCE)
00215             ACE_TCHAR *ld_path_temp = 0;
00216             if (ld_path != 0)
00217               {
00218                 ld_path_temp = (ACE_TCHAR *)
00219                   ACE_OS::malloc ((ACE_OS::strlen (ld_path) + 2)
00220                                   * sizeof (ACE_TCHAR));
00221                 if (ld_path_temp != 0)
00222                   {
00223                     ACE_OS::strcpy (ld_path_temp,
00224                                     ACE_LD_SEARCH_PATH_SEPARATOR_STR);
00225 
00226                     ACE_OS::strcat (ld_path_temp, ld_path);
00227                     ld_path = ld_path_temp;
00228                   }
00229                 else
00230                   {
00231                     ACE_OS::free ((void *) ld_path_temp);
00232                     ld_path = ld_path_temp = 0;
00233                   }
00234               }
00235 #endif /* ACE_HAS_WINCE */
00236 
00237           if (ld_path != 0
00238               && (ld_path = ACE_OS::strdup (ld_path)) != 0)
00239             {
00240               // strtok has the strange behavior of not separating the
00241               // string ":/foo:/bar" into THREE tokens.  One would expect
00242               // that the first iteration the token would be an empty
00243               // string, the second iteration would be "/foo", and the
00244               // third iteration would be "/bar".  However, this is not
00245               // the case; one only gets two iterations: "/foo" followed
00246               // by "/bar".
00247 
00248               // This is especially a problem in parsing Unix paths
00249               // because it is permissible to specify 'the current
00250               // directory' as an empty entry.  So, we introduce the
00251               // following special code to cope with this:
00252 
00253               // Look at each dynamic lib directory in the search path.
00254 
00255               ACE_TCHAR *nextholder = 0;
00256               const ACE_TCHAR *path_entry =
00257                 ACE_Lib_Find::strsplit_r (ld_path,
00258                                           ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00259                                           nextholder);
00260               int result = 0;
00261 
00262               for (;;)
00263                 {
00264                   // Check if at end of search path.
00265                   if (path_entry == 0)
00266                     {
00267                       errno = ENOENT;
00268                       result = -1;
00269                       break;
00270                     }
00271                   else if (ACE_OS::strlen (path_entry)
00272                            + 1
00273                            + ACE_OS::strlen (searchfilename)
00274                            >= maxpathnamelen)
00275                     {
00276                       errno = ENOMEM;
00277                       result = -1;
00278                       break;
00279                     }
00280                   // This works around the issue where a path might have
00281                   // an empty component indicating 'current directory'.
00282                   // We need to do it here rather than anywhere else so
00283                   // that the loop condition will still work.
00284                   else if (path_entry[0] == '\0')
00285                     path_entry = ACE_LIB_TEXT (".");
00286 
00287                   // First, try matching the filename *without* adding a
00288                   // prefix.
00289 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00290                   ACE_OS::sprintf (pathname,
00291                                    ACE_LIB_TEXT ("%s%c%s%s"),
00292                                    path_entry,
00293                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00294                                    searchfilename,
00295                                    got_suffix ? ACE_static_cast (ACE_TCHAR *,
00296                                                                  ACE_LIB_TEXT (""))
00297                                    : ACE_static_cast (ACE_TCHAR *,
00298                                                       dll_suffix));
00299 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00300                   ACE_OS::sprintf (pathname,
00301                                    ACE_LIB_TEXT ("%s%c%s%s"),
00302                                    path_entry,
00303                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00304                                    searchfilename,
00305                                    got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00306 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00307                   if (ACE_OS::access (pathname, F_OK) == 0)
00308                     break;
00309 
00310                   // Second, try matching the filename *with* adding a
00311                   // prefix.
00312 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00313                   ACE_OS::sprintf (pathname,
00314                                    ACE_LIB_TEXT ("%s%c%s%s%s"),
00315                                    path_entry,
00316                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00317                                    ACE_DLL_PREFIX,
00318                                    searchfilename,
00319                                    got_suffix ? ACE_static_cast (ACE_TCHAR *,
00320                                                                  ACE_LIB_TEXT (""))
00321                                    : ACE_static_cast (ACE_TCHAR *,
00322                                                       dll_suffix));
00323 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00324                   ACE_OS::sprintf (pathname,
00325                                    ACE_LIB_TEXT ("%s%c%s%s%s"),
00326                                    path_entry,
00327                                    ACE_DIRECTORY_SEPARATOR_CHAR,
00328                                    ACE_DLL_PREFIX,
00329                                    searchfilename,
00330                                    got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00331 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00332                   if (ACE_OS::access (pathname, F_OK) == 0)
00333                     break;
00334 
00335                   // Fetch the next item in the path
00336                   path_entry = ACE_Lib_Find::strsplit_r (0,
00337                                                          ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00338                                                          nextholder);
00339                 }
00340 
00341 #if defined (ACE_HAS_WINCE)
00342               if (ld_path_temp != 0)
00343                 ACE_OS::free (ld_path_temp);
00344 #endif /* ACE_HAS_WINCE */
00345               ACE_OS::free ((void *) ld_path);
00346 #if defined (ACE_HAS_WINCE) && defined (ACE_LD_DECORATOR_STR) && \
00347             !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00348                if (result == 0 || tag == 0)
00349 #endif /* ACE_HAS_WINCE && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00350               return result;
00351             }
00352 #endif /* ACE_WIN32 && !ACE_HAS_WINCE */
00353         }
00354 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00355     }
00356 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
00357 
00358   errno = ENOENT;
00359   return -1;
00360 }
00361 
00362 FILE *
00363 ACE_Lib_Find::ldopen (const ACE_TCHAR *filename,
00364              const ACE_TCHAR *type)
00365 {
00366   ACE_TRACE ("ACE_Lib_Find::ldopen");
00367 
00368   ACE_TCHAR buf[MAXPATHLEN + 1];
00369   if (ACE_Lib_Find::ldfind (filename,
00370                    buf,
00371                    sizeof (buf) /sizeof (ACE_TCHAR)) == -1)
00372     return 0;
00373   else
00374     return ACE_OS::fopen (buf, type);
00375 }
00376 
00377 ACE_TCHAR *
00378 ACE_Lib_Find::ldname (const ACE_TCHAR *entry_point)
00379 {
00380   ACE_TRACE ("ACE_Lib_Find::ldname");
00381 
00382 #if defined (__BORLANDC__) || defined(ACE_NEEDS_DL_UNDERSCORE)
00383   size_t size =
00384     1 // leading '_'
00385     + ACE_OS::strlen (entry_point)
00386     + 1;
00387 
00388   ACE_TCHAR *new_name;
00389   ACE_NEW_RETURN (new_name,
00390                   ACE_TCHAR[size],
00391                   0);
00392 
00393   ACE_OS::strcpy (new_name, ACE_LIB_TEXT ("_"));
00394   ACE_OS::strcat (new_name, entry_point);
00395 
00396   return new_name;
00397 #else /* __BORLANDC__ || ACE_NEEDS_DL_UNDERSCORE */
00398   size_t size =
00399     ACE_OS::strlen (entry_point)
00400     + 1;
00401 
00402   ACE_TCHAR *new_name;
00403   ACE_NEW_RETURN (new_name,
00404                   ACE_TCHAR[size],
00405                   0);
00406 
00407   ACE_OS::strcpy (new_name, entry_point);
00408 
00409   return new_name;
00410 #endif /* __BORLANDC__ || ACE_NEEDS_DL_UNDERSCORE */
00411 }
00412 
00413 int
00414 ACE_Lib_Find::get_temp_dir (ACE_TCHAR *buffer, size_t buffer_len)
00415 {
00416   int result;
00417 #if defined (ACE_WIN32)
00418   result = ACE_TEXT_GetTempPath (ACE_static_cast (DWORD, buffer_len),
00419                                  buffer);
00420 
00421   // Make sure to return -1 if there is an error
00422   if (result == 0 && ::GetLastError () != ERROR_SUCCESS
00423       || result > ACE_static_cast (int, buffer_len))
00424     result = -1;
00425 
00426 #else /* ACE_WIN32 */
00427 
00428   // On non-win32 platforms, check to see what the TMPDIR environment
00429   // variable is defined to be.  If it doesn't exist, just use /tmp
00430   const ACE_TCHAR *tmpdir = ACE_OS::getenv (ACE_LIB_TEXT ("TMPDIR"));
00431 
00432   if (tmpdir == 0)
00433     tmpdir = ACE_LIB_TEXT ("/tmp");
00434 
00435   size_t len = ACE_OS::strlen (tmpdir);
00436 
00437   // Check to see if the buffer is large enough for the string,
00438   // another /, and its null character (hence the + 2)
00439   if ((len + 2) > buffer_len)
00440     {
00441       result = -1;
00442     }
00443   else
00444     {
00445       ACE_OS::strcpy (buffer, tmpdir);
00446 
00447       // Add a trailing slash because we cannot assume there is already one
00448       // at the end.  And having an extra one should not cause problems.
00449       buffer[len] = '/';
00450       buffer[len + 1] = 0;
00451       result = 0;
00452     }
00453 #endif /* ACE_WIN32 */
00454   return result;
00455 }
00456 
00457 ACE_HANDLE
00458 ACE_Lib_Find::open_temp_file (const ACE_TCHAR *name, int mode, int perm)
00459 {
00460 #if defined (ACE_WIN32)
00461   ACE_UNUSED_ARG(perm);
00462   return ACE_OS::open (name,
00463                        mode | _O_TEMPORARY);
00464 #else
00465   // Open it.
00466   ACE_HANDLE handle = ACE_OS::open (name, mode, perm);
00467 
00468   if (handle == ACE_INVALID_HANDLE)
00469     return ACE_INVALID_HANDLE;
00470 
00471   // Unlink it so that the file will be removed automatically when the
00472   // process goes away.
00473   if (ACE_OS::unlink (name) == -1)
00474     return -1;
00475   else
00476     // Return the handle.
00477     return handle;
00478 #endif /* ACE_WIN32 */
00479 }
00480 #endif /* ! ACE_PSOS_DIAB_MIPS */
00481 
00482 size_t
00483 ACE_Lib_Find::strrepl (char *s, char search, char replace)
00484 {
00485   ACE_TRACE ("ACE_Lib_Find::strrepl");
00486 
00487   size_t replaced = 0;
00488 
00489   for (size_t i = 0; s[i] != '\0'; i++)
00490     if (s[i] == search)
00491       {
00492         s[i] = replace;
00493         replaced++;
00494       }
00495 
00496   return replaced;
00497 }
00498 
00499 
00500 // Split a string up into 'token'-delimited pieces, ala Perl's
00501 // "split".
00502 
00503 char *
00504 ACE_Lib_Find::strsplit_r (char *str,
00505                           const char *token,
00506                           char *&next_start)
00507 {
00508   char *result = 0;
00509 
00510   if (str != 0)
00511     next_start = str;
00512 
00513   if (next_start != 0)
00514     {
00515       char *tok_loc = ACE_OS::strstr (next_start, token);
00516 
00517       if (tok_loc != 0)
00518         {
00519           // Return the beginning of the string.
00520           result = next_start;
00521 
00522           // Insure it's terminated.
00523           *tok_loc = '\0';
00524           next_start = tok_loc + ACE_OS::strlen (token);
00525         }
00526       else
00527         {
00528           result = next_start;
00529           next_start = (char *) 0;
00530         }
00531     }
00532 
00533   return result;
00534 }
00535 
00536 #if defined (ACE_HAS_WCHAR)
00537 wchar_t *
00538 ACE_Lib_Find::strsplit_r (wchar_t *str,
00539                           const wchar_t *token,
00540                           wchar_t *&next_start)
00541 {
00542   wchar_t *result = 0;
00543 
00544   if (str != 0)
00545     next_start = str;
00546 
00547   if (next_start != 0)
00548     {
00549       wchar_t *tok_loc = ACE_OS::strstr (next_start, token);
00550 
00551       if (tok_loc != 0)
00552         {
00553           // Return the beginning of the string.
00554           result = next_start;
00555 
00556           // Insure it's terminated.
00557           *tok_loc = '\0';
00558           next_start = tok_loc + ACE_OS::strlen (token);
00559         }
00560       else
00561         {
00562           result = next_start;
00563           next_start = (wchar_t *) 0;
00564         }
00565     }
00566 
00567   return result;
00568 }
00569 
00570 size_t
00571 ACE_Lib_Find::strrepl (wchar_t *s, wchar_t search, wchar_t replace)
00572 {
00573   ACE_TRACE ("ACE_Lib_Find::strrepl");
00574 
00575   size_t replaced = 0;
00576 
00577   for (size_t i = 0; s[i] != '\0'; i++)
00578     if (s[i] == search)
00579       {
00580         s[i] = replace;
00581         replaced++;
00582       }
00583 
00584   return replaced;
00585 }
00586 #endif /* ACE_HAS_WCHAR */

Generated on Mon Jun 16 11:19:55 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002