aboutsummaryrefslogtreecommitdiffstats
path: root/lib/System
diff options
context:
space:
mode:
Diffstat (limited to 'lib/System')
-rw-r--r--lib/System/ErrorCode.cpp38
-rw-r--r--lib/System/Path.cpp90
-rw-r--r--lib/System/linux/ErrorCode.cpp57
-rw-r--r--lib/System/linux/LinuxCommon.h157
-rw-r--r--lib/System/linux/Path.cpp450
5 files changed, 792 insertions, 0 deletions
diff --git a/lib/System/ErrorCode.cpp b/lib/System/ErrorCode.cpp
new file mode 100644
index 0000000..5f340cc
--- /dev/null
+++ b/lib/System/ErrorCode.cpp
@@ -0,0 +1,38 @@
+//===- ErrorCode.cpp - Define the ErrorCode class ---------------*- C++ -*-===//
+//
+// Copyright (C) 2004 eXtensible Systems, Inc. All Rights Reserved.
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the University of Illinois Open Source License. See
+// LICENSE.TXT (distributed with this software) for details.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the members of the llvm::sys::ErrorCode class. This class
+// is used to hold operating system and other error codes in a platform
+// agnostic manner.
+//
+//===----------------------------------------------------------------------===//
+/// @file lib/System/ErrorCode.h
+/// @author Reid Spencer <raspencer@x10sys.com> (original author)
+/// @version \verbatim $Id$ \endverbatim
+/// @date 2004/08/14
+/// @since 1.4
+/// @brief Declares the llvm::sys::ErrorCode class.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/ErrorCode.h"
+
+namespace llvm {
+namespace sys {
+
+}
+}
+
+#include "linux/ErrorCode.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp
new file mode 100644
index 0000000..a0c76db
--- /dev/null
+++ b/lib/System/Path.cpp
@@ -0,0 +1,90 @@
+//===- Path.cpp - Path Operating System Concept -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Copyright (C) 2004 eXtensible Systems, Inc. All Rights Reserved.
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the University of Illinois Open Source License. See
+// LICENSE.TXT (distributed with this software) for details.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the common Path concept for a variety of platforms.
+// A path is simply the name of some file system storage place. Paths can be
+// either directories or files.
+//
+//===----------------------------------------------------------------------===//
+/// @file lib/System/Path.cpp
+/// @author Reid Spencer <raspencer@x10sys.com> (original author)
+/// @version \verbatim $Id$ \endverbatim
+/// @date 2004/08/14
+/// @since 1.4
+/// @brief Defines the llvm::sys::Path class.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Path.h"
+
+namespace llvm {
+namespace sys {
+
+ErrorCode
+Path::append_directory( const std::string& dirname ) throw() {
+ this->append( dirname );
+ make_directory();
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::append_file( const std::string& filename ) throw() {
+ this->append( filename );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::create( bool create_parents)throw() {
+ ErrorCode result ( NOT_AN_ERROR );
+ if ( is_directory() ) {
+ if ( create_parents ) {
+ result = this->create_directories( );
+ } else {
+ result = this->create_directory( );
+ }
+ } else if ( is_file() ) {
+ if ( create_parents ) {
+ result = this->create_directories( );
+ }
+ if ( result ) {
+ result = this->create_file( );
+ }
+ } else {
+ result = ErrorCode(ERR_SYS_INVALID_ARG);
+ }
+ return result;
+}
+
+ErrorCode
+Path::remove() throw() {
+ ErrorCode result( NOT_AN_ERROR );
+ if ( is_directory() ) {
+ if ( exists() )
+ this->remove_directory( );
+ } else if ( is_file() ) {
+ if ( exists() ) this->remove_file( );
+ } else {
+ result = ErrorCode(ERR_SYS_INVALID_ARG);
+ }
+ return result;
+}
+
+}
+}
+
+// Include the platform specific portions of this class
+#include "linux/Path.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/linux/ErrorCode.cpp b/lib/System/linux/ErrorCode.cpp
new file mode 100644
index 0000000..193964a
--- /dev/null
+++ b/lib/System/linux/ErrorCode.cpp
@@ -0,0 +1,57 @@
+//===- ErrorCode.cpp - Define the ErrorCode class ---------------*- C++ -*-===//
+//
+// Copyright (C) 2004 eXtensible Systems, Inc. All Rights Reserved.
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the University of Illinois Open Source License. See
+// LICENSE.TXT (distributed with this software) for details.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the linux specific members of the llvm::sys::ErrorCode
+// class.
+//
+//===----------------------------------------------------------------------===//
+/// @file lib/System/ErrorCode.h
+/// @author Reid Spencer <raspencer@x10sys.com> (original author)
+/// @version \verbatim $Id$ \endverbatim
+/// @date 2004/08/14
+/// @since 1.4
+/// @brief Declares the linux specific methods of llvm::sys::ErrorCode class.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace sys {
+
+std::string
+ErrorCode::description() const throw()
+{
+ switch (domain()) {
+ case OSDomain:
+ char buffer[1024];
+ if (0 != strerror_r(index(),buffer,1024) )
+ return "<Error Message Unavalabile>";
+ return buffer;
+
+ case SystemDomain:
+ switch (index()) {
+ case ERR_SYS_INVALID_ARG:
+ return "Invalid argument to lib/System call";
+ default:
+ return "Unknown lib/System Error";
+ }
+ break;
+
+ default:
+ return "Unknown Error";
+ }
+}
+
+}
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/linux/LinuxCommon.h b/lib/System/linux/LinuxCommon.h
new file mode 100644
index 0000000..ac850aa
--- /dev/null
+++ b/lib/System/linux/LinuxCommon.h
@@ -0,0 +1,157 @@
+//===- LinuxCommon.h - Common Declarations For Linux ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Copyright (C) 2004 eXtensible Systems, Inc. All Rights Reserved.
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the University of Illinois Open Source License. See
+// LICENSE.TXT (distributed with this software) for details.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//===----------------------------------------------------------------------===//
+/// @file lib/System/linux/Common.h
+/// @author Reid Spencer <rspencer@x10sys.com> (original author)
+/// @version \verbatim $Id$ \endverbatim
+/// @date 2004/08/14
+/// @since 1.4
+/// @brief Provides common linux specific declarations and includes.
+//===----------------------------------------------------------------------===//
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <pthread.h>
+
+#define FATAL(arg) \
+ { llvm::sys::panic(LLVM_CONTEXT, arg); }
+
+#define RETURN_ERRNO \
+ return ErrorCode(LLVM_ERROR_CODE(OSDomain,errno))
+
+#define RETURN_OSERROR(code) \
+ return ErrorCode(LLVM_ERROR_CODE(OSDomain,code))
+
+#ifdef assert
+#define ASSERT_ARG(expr) \
+ if ( ! (expr) ) {\
+ return ErrorCode(ERR_SYS_INVALID_ARG);\
+ }
+#else
+#define ASSERT_ARG(expr)
+#endif
+
+#define CHECK(var,call,args,msg) \
+ { \
+ if ( -1 == ( var = ::call args )) { \
+ panic(LLVM_CONTEXT, msg); \
+ } \
+ }
+
+#define RETURN_ON_ERROR(call,args) \
+ { \
+ errno = 0; \
+ if ( 0 > ( call args ) ) { \
+ RETURN_ERRNO; \
+ } \
+ }
+
+#define RETURN_ON_ERRORCODE(call,args) \
+ { \
+ ErrorCode code = call args ; \
+ if ( ! code ) \
+ return code; \
+ }
+
+#define PTHREAD_CALL( call, args, cleanup ) \
+ { \
+ int errcode = ::call args ; \
+ if ( errcode != 0 ) { \
+ cleanup ; \
+ RETURN_ERRNO ; \
+ } \
+ }
+
+#define CLEANUP_CALL( call, args, cleanup ) \
+ { \
+ int result = call args ; \
+ if ( result != 0 ) { \
+ cleanup ; \
+ RETURN_ERRNO ; \
+ } \
+ }
+
+// Define our realtime signals
+#define SIG_LOOP_TERMINATE ( SIGRTMIN + 3 )
+#define SIG_USER_EVENT_1 ( SIGRTMIN + 4 )
+#define SIG_USER_EVENT_2 ( SIGRTMIN + 5 )
+#define SIG_USER_EVENT_3 ( SIGRTMIN + 6 )
+#define SIG_USER_EVENT_4 ( SIGRTMIN + 7 )
+#define SIG_USER_EVENT_5 ( SIGRTMIN + 8 )
+#define SIG_USER_EVENT_6 ( SIGRTMIN + 9 )
+#define SIG_USER_EVENT_7 ( SIGRTMIN + 10 )
+#define SIG_USER_EVENT_8 ( SIGRTMIN + 11 )
+#define SIG_AIO_1 ( SIGRTMIN + 12 )
+#define SIG_AIO_2 ( SIGRTMIN + 13 )
+#define SIG_AIO_3 ( SIGRTMIN + 14 )
+#define SIG_AIO_4 ( SIGRTMIN + 15 )
+#define SIG_AIO_5 ( SIGRTMIN + 16 )
+#define SIG_AIO_6 ( SIGRTMIN + 17 )
+#define SIG_AIO_7 ( SIGRTMIN + 18 )
+#define SIG_AIO_8 ( SIGRTMIN + 19 )
+
+namespace llvm {
+namespace sys {
+
+#if 0
+inline void
+time_t2TimeValue( time_t t, TimeValue &tv )
+{
+ TimeValue::Seconds_Type seconds = t;
+ seconds -= TimeValue::posix_zero_time.seconds();
+ tv.set( seconds, 0 );
+}
+
+inline void
+TimeValue2timespec( const TimeValue& tv, struct timespec & ts )
+{
+ uint64_t seconds;
+ uint64_t nanos;
+ tv.timespec_time( seconds, nanos );
+ ts.tv_sec = static_cast<time_t>(seconds);
+ ts.tv_nsec = static_cast<long int>(nanos);
+}
+
+inline void
+timeval2TimeValue( struct timeval& tval, TimeValue& tv )
+{
+ TimeValue::Seconds_Type seconds = tval.tv_sec;
+ seconds -= TimeValue::posix_zero_time.seconds();
+ tv.set( seconds, tval.tv_usec * XPS_NANOSECONDS_PER_MICROSECOND );
+}
+
+extern pid_t pid_; ///< This processes' process identification number
+extern int pagesize_; ///< The virtual memory page size of this machine
+extern long arg_max_; ///< The maximum size in bytes of arguments to exec()
+extern long child_max_; ///< The maximum processes per user.
+extern long clk_tck_; ///< The number of clock ticks per second on this machine
+extern long stream_max_; ///< The maximum number of streams that can be opened
+extern long tzname_max_; ///< The maximum length of a timezone name
+extern long file_max_; ///< The maximum number of files that can be opened
+extern long line_max_; ///< The maximum length of an I/O line
+extern long job_control_; ///< Non-zero if POSIX job control enabled
+extern long saved_ids_; ///< ?
+extern long phys_pages_; ///< Total number of physical pages
+extern long avphys_pages_; ///< Average number of free physical pages
+
+#endif
+
+}
+}
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/linux/Path.cpp b/lib/System/linux/Path.cpp
new file mode 100644
index 0000000..a0eed86
--- /dev/null
+++ b/lib/System/linux/Path.cpp
@@ -0,0 +1,450 @@
+//===- Path.cpp - Path Operating System Concept -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Copyright (C) 2004 eXtensible Systems, Inc. All Rights Reserved.
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the University of Illinois Open Source License. See
+// LICENSE.TXT (distributed with this software) for details.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+/// @file lib/System/linux/Path.cpp
+/// @author Reid Spencer <raspencer@users.sourceforge.net> (original author)
+/// @version \verbatim $Id$ \endverbatim
+/// @date 2003/04/17
+/// @since 1.4
+/// @brief Implements the linux specific portion of class llvm::sys::Path
+////////////////////////////////////////////////////////////////////////////////
+
+#include "LinuxCommon.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+
+namespace llvm {
+namespace sys {
+
+Path::Path(ConstructSpecial which) throw() {
+ switch (which) {
+ case CONSTRUCT_TEMP_FILE:
+ this->make_temp_file();
+ break;
+ case CONSTRUCT_TEMP_DIR:
+ this->make_temp_directory();
+ break;
+ }
+}
+
+bool
+Path::is_file() const throw() {
+ if ( !empty() && ((*this)[length()-1] != '/' ))
+ return true;
+ return false;
+}
+
+bool
+Path::is_directory() const throw() {
+ if ((!empty()) && ((*this)[length()-1] == '/' ))
+ return true;
+ return false;
+}
+
+ErrorCode
+Path::make_directory() throw() {
+ char end[2];
+ end[0] = '/';
+ end[1] = 0;
+ if ( empty() )
+ this->assign( end );
+ else if ( (*this)[length()-1] != '/' )
+ this->append( end );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::make_temp_directory() throw() {
+ char temp_name[64];
+ ::strcpy(temp_name,"/tmp/llvm_XXXXXX");
+ char* res = ::mkdtemp(temp_name);
+ if ( res == 0 )
+ RETURN_ERRNO;
+ *this = temp_name;
+ make_directory();
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::make_file() throw() {
+ if ( (*this)[length()-1] == '/' )
+ this->erase( this->length()-1, 1 );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::make_temp_file() throw() {
+ char temp_name[64];
+ ::strcpy(temp_name,"/tmp/llvm_XXXXXX");
+ int fd = ::mkstemp(temp_name);
+ if ( fd == -1 )
+ RETURN_ERRNO;
+ ::close(fd);
+ *this = temp_name;
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::exists() throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ RETURN_ON_ERROR( access,( pathname, F_OK | R_OK ) );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::create_directory() throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ RETURN_ON_ERROR( mkdir, ( pathname, S_IRWXU | S_IRWXG ) );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::create_directories() throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ char * next = index(pathname,'/');
+ if ( pathname[0] == '/' )
+ next = index(&pathname[1],'/');
+ while ( next != 0 )
+ {
+ *next = 0;
+ if ( 0 != access( pathname, F_OK | R_OK ) )
+ RETURN_ON_ERROR( mkdir, (pathname, S_IRWXU | S_IRWXG ) );
+ char* save = next;
+ next = index(pathname,'/');
+ *save = '/';
+ }
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::remove_directory( ) throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ RETURN_ON_ERROR( rmdir, (pathname) );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::create_file( ) throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ RETURN_ON_ERROR( creat, ( pathname, S_IRUSR | S_IWUSR ) );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::remove_file( ) throw() {
+ char pathname[MAXPATHLEN];
+ this->fill(pathname,MAXPATHLEN);
+ int lastchar = this->length() - 1 ;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = 0;
+ RETURN_ON_ERROR( unlink, (pathname) );
+ return NOT_AN_ERROR;
+}
+
+ErrorCode
+Path::find_lib( const char * file ) throw()
+{
+ ASSERT_ARG( file != 0 );
+
+#if 0
+ ACE_TCHAR tempcopy[MAXPATHLEN + 1];
+ ACE_TCHAR searchpathname[MAXPATHLEN + 1];
+ ACE_TCHAR searchfilename[MAXPATHLEN + 1];
+
+ // Create a copy of filename to work with.
+ if (ACE_OS::strlen (filename) + 1
+ > (sizeof tempcopy / sizeof (ACE_TCHAR)))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ else
+ ACE_OS::strcpy (tempcopy, filename);
+
+ // Insert canonical directory separators.
+ ACE_TCHAR *separator_ptr;
+
+#if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
+ // Make all the directory separators "canonical" to simplify
+ // subsequent code.
+ ACE_Lib_Find::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
+#endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
+
+ // Separate filename from pathname.
+ separator_ptr = ACE_OS::strrchr (tempcopy, '/');
+
+ // This is a relative path.
+ if (separator_ptr == 0)
+ {
+ searchpathname[0] = '\0';
+ ACE_OS::strcpy (searchfilename, tempcopy);
+ }
+ else // This is an absolute path.
+ {
+ ACE_OS::strcpy (searchfilename, separator_ptr + 1);
+ separator_ptr[1] = '\0';
+ ACE_OS::strcpy (searchpathname, tempcopy);
+ }
+
+ int got_suffix = 0;
+
+ // Check to see if this has an appropriate DLL suffix for the OS
+ // platform.
+ ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
+
+ const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
+
+ if (s != 0)
+ {
+ // If we have a dot, we have a suffix
+ got_suffix = 1;
+
+ // Check whether this matches the appropriate platform-specific
+ // suffix.
+ if (ACE_OS::strcmp (s, dll_suffix) != 0)
+ {
+ ACE_ERROR ((LM_WARNING,
+ ACE_LIB_TEXT ("Warning: improper suffix for a ")
+ ACE_LIB_TEXT ("shared library on this platform: %s\n"),
+ s));
+ }
+ }
+
+ // Make sure we've got enough space in searchfilename.
+ if (ACE_OS::strlen (searchfilename)
+ + ACE_OS::strlen (ACE_DLL_PREFIX)
+ + got_suffix ? 0 : ACE_OS::strlen (dll_suffix) >= (sizeof searchfilename /
+ sizeof (ACE_TCHAR)))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ // Use absolute pathname if there is one.
+ if (ACE_OS::strlen (searchpathname) > 0)
+ {
+ if (ACE_OS::strlen (searchfilename)
+ + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ else
+ {
+#if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
+ // Revert to native path name separators.
+ ACE_Lib_Find::strrepl (searchpathname,
+ '/',
+ ACE_DIRECTORY_SEPARATOR_CHAR);
+#endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
+ // First, try matching the filename *without* adding a
+ // prefix.
+#if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%s%s"),
+ searchpathname,
+ searchfilename,
+ got_suffix ? ACE_static_cast (ACE_TCHAR *,
+ ACE_LIB_TEXT (""))
+ : ACE_static_cast (ACE_TCHAR *,
+ dll_suffix));
+#else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%s%s"),
+ searchpathname,
+ searchfilename,
+ got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
+#endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ if (ACE_OS::access (pathname, F_OK) == 0)
+ return 0;
+
+ // Second, try matching the filename *with* adding a prefix.
+#if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%s%s%s"),
+ searchpathname,
+ ACE_DLL_PREFIX,
+ searchfilename,
+ got_suffix ? ACE_static_cast (ACE_TCHAR *,
+ ACE_LIB_TEXT (""))
+ : ACE_static_cast (ACE_TCHAR *,
+ dll_suffix));
+#else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%s%s%s"),
+ searchpathname,
+ ACE_DLL_PREFIX,
+ searchfilename,
+ got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
+#endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ if (ACE_OS::access (pathname, F_OK) == 0)
+ return 0;
+ }
+ }
+
+ // Use relative filenames via LD_LIBRARY_PATH or PATH (depending on
+ // OS platform).
+ else
+ {
+ ACE_TCHAR *ld_path =
+#if defined ACE_DEFAULT_LD_SEARCH_PATH
+ ACE_DEFAULT_LD_SEARCH_PATH;
+#else
+ ACE_OS::getenv (ACE_LD_SEARCH_PATH);
+#endif /* ACE_DEFAULT_LD_SEARCH_PATH */
+
+ if (ld_path != 0
+ && (ld_path = ACE_OS::strdup (ld_path)) != 0)
+ {
+ // strtok has the strange behavior of not separating the
+ // string ":/foo:/bar" into THREE tokens. One would expect
+ // that the first iteration the token would be an empty
+ // string, the second iteration would be "/foo", and the
+ // third iteration would be "/bar". However, this is not
+ // the case; one only gets two iterations: "/foo" followed
+ // by "/bar".
+
+ // This is especially a problem in parsing Unix paths
+ // because it is permissible to specify 'the current
+ // directory' as an empty entry. So, we introduce the
+ // following special code to cope with this:
+
+ // Look at each dynamic lib directory in the search path.
+
+ ACE_TCHAR *nextholder = 0;
+ const ACE_TCHAR *path_entry =
+ ACE_Lib_Find::strsplit_r (ld_path,
+ ACE_LD_SEARCH_PATH_SEPARATOR_STR,
+ nextholder);
+ int result = 0;
+
+ for (;;)
+ {
+ // Check if at end of search path.
+ if (path_entry == 0)
+ {
+ errno = ENOENT;
+ result = -1;
+ break;
+ }
+ else if (ACE_OS::strlen (path_entry)
+ + 1
+ + ACE_OS::strlen (searchfilename)
+ >= maxpathnamelen)
+ {
+ errno = ENOMEM;
+ result = -1;
+ break;
+ }
+ // This works around the issue where a path might have
+ // an empty component indicating 'current directory'.
+ // We need to do it here rather than anywhere else so
+ // that the loop condition will still work.
+ else if (path_entry[0] == '\0')
+ path_entry = ACE_LIB_TEXT (".");
+
+ // First, try matching the filename *without* adding a
+ // prefix.
+#if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%c%s%s"),
+ path_entry,
+ ACE_DIRECTORY_SEPARATOR_CHAR,
+ searchfilename,
+ got_suffix ? ACE_static_cast (ACE_TCHAR *,
+ ACE_LIB_TEXT (""))
+ : ACE_static_cast (ACE_TCHAR *,
+ dll_suffix));
+#else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%c%s%s"),
+ path_entry,
+ ACE_DIRECTORY_SEPARATOR_CHAR,
+ searchfilename,
+ got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
+#endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ if (ACE_OS::access (pathname, F_OK) == 0)
+ break;
+
+ // Second, try matching the filename *with* adding a
+ // prefix.
+#if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%c%s%s%s"),
+ path_entry,
+ ACE_DIRECTORY_SEPARATOR_CHAR,
+ ACE_DLL_PREFIX,
+ searchfilename,
+ got_suffix ? ACE_static_cast (ACE_TCHAR *,
+ ACE_LIB_TEXT (""))
+ : ACE_static_cast (ACE_TCHAR *,
+ dll_suffix));
+#else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ ACE_OS::sprintf (pathname,
+ ACE_LIB_TEXT ("%s%c%s%s%s"),
+ path_entry,
+ ACE_DIRECTORY_SEPARATOR_CHAR,
+ ACE_DLL_PREFIX,
+ searchfilename,
+ got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
+#endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
+ if (ACE_OS::access (pathname, F_OK) == 0)
+ break;
+
+ // Fetch the next item in the path
+ path_entry = ACE_Lib_Find::strsplit_r (0,
+ ACE_LD_SEARCH_PATH_SEPARATOR_STR,
+ nextholder);
+ }
+
+ ACE_OS::free ((void *) ld_path);
+ return result;
+ }
+ }
+ errno = ENOENT;
+ return -1;
+#endif
+
+ /// @todo FIXME: Convert ACE code
+ *this = Path( file );
+
+ return NOT_AN_ERROR;
+}
+
+}
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab