#include <mach-o/dyld.h>
#endif
+// For GNU Hurd
+#if defined(__GNU__) && !defined(MAXPATHLEN)
+# define MAXPATHLEN 4096
+#endif
+
// Put in a hack for Cygwin which falsely reports that the mkdtemp function
// is available when it is not.
#ifdef __CYGWIN__
return !path.empty();
}
-bool
-Path::isAbsolute(const char *NameStart, unsigned NameLen) {
- assert(NameStart);
- if (NameLen == 0)
- return false;
- return NameStart[0] == '/';
-}
-
-bool
-Path::isAbsolute() const {
- if (path.empty())
- return false;
- return path[0] == '/';
-}
-
-Path
-Path::GetRootDirectory() {
- Path result;
- result.set("/");
- return result;
-}
-
Path
Path::GetTemporaryDirectory(std::string *ErrMsg) {
#if defined(HAVE_MKDTEMP)
#endif
}
-void
-Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
-#ifdef LTDL_SHLIBPATH_VAR
- char* env_var = getenv(LTDL_SHLIBPATH_VAR);
- if (env_var != 0) {
- getPathList(env_var,Paths);
- }
-#endif
- // FIXME: Should this look at LD_LIBRARY_PATH too?
- Paths.push_back(sys::Path("/usr/local/lib/"));
- Paths.push_back(sys::Path("/usr/X11R6/lib/"));
- Paths.push_back(sys::Path("/usr/lib/"));
- Paths.push_back(sys::Path("/lib/"));
-}
-
-void
-Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
- char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
- if (env_var != 0) {
- getPathList(env_var,Paths);
- }
-#ifdef LLVM_LIBDIR
- {
- Path tmpPath;
- if (tmpPath.set(LLVM_LIBDIR))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
- }
-#endif
- GetSystemLibraryPaths(Paths);
-}
-
-Path
-Path::GetLLVMDefaultConfigDir() {
- return Path("/etc/llvm/");
-}
-
-Path
-Path::GetUserHomeDirectory() {
- const char* home = getenv("HOME");
- Path result;
- if (home && result.set(home))
- return result;
- result.set("/");
- return result;
-}
-
Path
Path::GetCurrentDirectory() {
char pathname[MAXPATHLEN];
- if (!getcwd(pathname,MAXPATHLEN)) {
- assert (false && "Could not query current working directory.");
+ if (!getcwd(pathname, MAXPATHLEN)) {
+ assert(false && "Could not query current working directory.");
return Path();
}
return Path(pathname);
}
-#if defined(__FreeBSD__) || defined (__NetBSD__) || \
- defined(__OpenBSD__) || defined(__minix)
+#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
+ defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
+ defined(__linux__) || defined(__CYGWIN__)
static int
test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
const char *dir, const char *bin)
free(pv);
return (NULL);
}
-#endif // __FreeBSD__ || __NetBSD__
+#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
if (realpath(exe_path, link_path))
return Path(link_path);
}
-#elif defined(__FreeBSD__) || defined (__NetBSD__) || \
- defined(__OpenBSD__) || defined(__minix)
+#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
+ defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__)
char exe_path[PATH_MAX];
if (getprogpath(exe_path, argv0) != NULL)
return Path(exe_path);
#elif defined(__linux__) || defined(__CYGWIN__)
char exe_path[MAXPATHLEN];
- ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
- if (len >= 0)
- return Path(StringRef(exe_path, len));
+ StringRef aPath("/proc/self/exe");
+ if (sys::fs::exists(aPath)) {
+ // /proc is not always mounted under Linux (chroot for example).
+ ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
+ if (len >= 0)
+ return Path(StringRef(exe_path, len));
+ } else {
+ // Fall back to the classical detection.
+ if (getprogpath(exe_path, argv0) != NULL)
+ return Path(exe_path);
+ }
#elif defined(HAVE_DLFCN_H)
// Use dladdr to get executable path if available.
Dl_info DLInfo;
return Path();
}
-
-StringRef Path::getDirname() const {
- return getDirnameCharSep(path, "/");
-}
-
-StringRef
-Path::getBasename() const {
- // Find the last slash
- std::string::size_type slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- std::string::size_type dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef(path).substr(slash);
- else
- return StringRef(path).substr(slash, dot - slash);
-}
-
-StringRef
-Path::getSuffix() const {
- // Find the last slash
- std::string::size_type slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- std::string::size_type dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef();
- else
- return StringRef(path).substr(dot + 1);
-}
-
-bool Path::getMagicNumber(std::string &Magic, unsigned len) const {
- assert(len < 1024 && "Request for magic string too long");
- char Buf[1025];
- int fd = ::open(path.c_str(), O_RDONLY);
- if (fd < 0)
- return false;
- ssize_t bytes_read = ::read(fd, Buf, len);
- ::close(fd);
- if (ssize_t(len) != bytes_read)
- return false;
- Magic.assign(Buf, len);
- return true;
-}
-
bool
Path::exists() const {
return 0 == access(path.c_str(), F_OK );
return S_ISLNK(buf.st_mode);
}
-
-bool
-Path::canRead() const {
- return 0 == access(path.c_str(), R_OK);
-}
-
-bool
-Path::canWrite() const {
- return 0 == access(path.c_str(), W_OK);
-}
-
bool
Path::isRegularFile() const {
// Get the status so we can determine if it's a file or directory
return false;
}
-bool
-Path::canExecute() const {
- if (0 != access(path.c_str(), R_OK | X_OK ))
- return false;
- struct stat buf;
- if (0 != stat(path.c_str(), &buf))
- return false;
- if (!S_ISREG(buf.st_mode))
- return false;
- return true;
-}
-
-StringRef
-Path::getLast() const {
- // Find the last slash
- size_t pos = path.rfind('/');
-
- // Handle the corner cases
- if (pos == std::string::npos)
- return path;
-
- // If the last character is a slash
- if (pos == path.length()-1) {
- // Find the second to last slash
- size_t pos2 = path.rfind('/', pos-1);
- if (pos2 == std::string::npos)
- return StringRef(path).substr(0,pos);
- else
- return StringRef(path).substr(pos2+1,pos-pos2-1);
- }
- // Return everything after the last slash
- return StringRef(path).substr(pos+1);
-}
-
const FileStatus *
PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
if (!fsIsValid || update) {
status.mode = buf.st_mode;
status.user = buf.st_uid;
status.group = buf.st_gid;
- status.uniqueID = uint64_t(buf.st_ino);
status.isDir = S_ISDIR(buf.st_mode);
status.isFile = S_ISREG(buf.st_mode);
fsIsValid = true;
return false;
}
-bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
- if (!AddPermissionBits(*this, 0111))
- return MakeErrMsg(ErrMsg, path + ": can't make file executable");
- return false;
-}
-
bool
Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
DIR* direntries = ::opendir(path.c_str());
return false;
}
-bool
-Path::createFileOnDisk(std::string* ErrMsg) {
- // Create the file
- int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
- if (fd < 0)
- return MakeErrMsg(ErrMsg, path + ": can't create file");
- ::close(fd);
- return false;
-}
-
bool
Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
// Make this into a unique file name
return false;
}
-bool
-sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
- int inFile = -1;
- int outFile = -1;
- inFile = ::open(Src.c_str(), O_RDONLY);
- if (inFile == -1)
- return MakeErrMsg(ErrMsg, Src.str() +
- ": can't open source file to copy");
-
- outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
- if (outFile == -1) {
- ::close(inFile);
- return MakeErrMsg(ErrMsg, Dest.str() +
- ": can't create destination file for copy");
- }
-
- char Buffer[16*1024];
- while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
- if (Amt == -1) {
- if (errno != EINTR && errno != EAGAIN) {
- ::close(inFile);
- ::close(outFile);
- return MakeErrMsg(ErrMsg, Src.str()+": can't read source file");
- }
- } else {
- char *BufPtr = Buffer;
- while (Amt) {
- ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
- if (AmtWritten == -1) {
- if (errno != EINTR && errno != EAGAIN) {
- ::close(inFile);
- ::close(outFile);
- return MakeErrMsg(ErrMsg, Dest.str() +
- ": can't write destination file");
- }
- } else {
- Amt -= AmtWritten;
- BufPtr += AmtWritten;
- }
- }
- }
- }
- ::close(inFile);
- ::close(outFile);
- return false;
-}
-
bool
Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
bool Exists;
#endif
return false;
}
-
-const char *Path::MapInFilePages(int FD, size_t FileSize, off_t Offset) {
- int Flags = MAP_PRIVATE;
-#ifdef MAP_FILE
- Flags |= MAP_FILE;
-#endif
- void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, Offset);
- if (BasePtr == MAP_FAILED)
- return 0;
- return (const char*)BasePtr;
-}
-
-void Path::UnMapFilePages(const char *BasePtr, size_t FileSize) {
- ::munmap((void*)BasePtr, FileSize);
-}
-
} // end llvm namespace