diff options
Diffstat (limited to 'lib/System/Unix/Path.inc')
-rw-r--r-- | lib/System/Unix/Path.inc | 121 |
1 files changed, 47 insertions, 74 deletions
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc index 3d88311..5ee3adc 100644 --- a/lib/System/Unix/Path.inc +++ b/lib/System/Unix/Path.inc @@ -78,6 +78,10 @@ using namespace sys; const char sys::PathSeparator = ':'; +StringRef Path::GetEXESuffix() { + return StringRef(); +} + Path::Path(StringRef p) : path(p) {} @@ -92,10 +96,12 @@ Path::operator=(StringRef that) { bool Path::isValid() const { - // Check some obvious things - if (path.empty()) - return false; - return path.length() < MAXPATHLEN; + // Empty paths are considered invalid here. + // This code doesn't check MAXPATHLEN because there's no need. Nothing in + // LLVM manipulates Paths with fixed-sizes arrays, and if the OS can't + // handle names longer than some limit, it'll report this on demand using + // ENAMETOLONG. + return !path.empty(); } bool @@ -137,25 +143,20 @@ Path::GetTemporaryDirectory(std::string *ErrMsg) { #if defined(HAVE_MKDTEMP) // The best way is with mkdtemp but that's not available on many systems, // Linux and FreeBSD have it. Others probably won't. - char pathname[MAXPATHLEN]; - strcpy(pathname,"/tmp/llvm_XXXXXX"); + char pathname[] = "/tmp/llvm_XXXXXX"; if (0 == mkdtemp(pathname)) { MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create temporary directory"); + std::string(pathname) + ": can't create temporary directory"); return Path(); } - Path result; - result.set(pathname); - assert(result.isValid() && "mkdtemp didn't create a valid pathname!"); - return result; + return Path(pathname); #elif defined(HAVE_MKSTEMP) // If no mkdtemp is available, mkstemp can be used to create a temporary file // which is then removed and created as a directory. We prefer this over // mktemp because of mktemp's inherent security and threading risks. We still // have a slight race condition from the time the temporary file is created to // the time it is re-created as a directoy. - char pathname[MAXPATHLEN]; - strcpy(pathname, "/tmp/llvm_XXXXXX"); + char pathname[] = "/tmp/llvm_XXXXXX"; int fd = 0; if (-1 == (fd = mkstemp(pathname))) { MakeErrMsg(ErrMsg, @@ -169,18 +170,14 @@ Path::GetTemporaryDirectory(std::string *ErrMsg) { std::string(pathname) + ": can't create temporary directory"); return Path(); } - Path result; - result.set(pathname); - assert(result.isValid() && "mkstemp didn't create a valid pathname!"); - return result; + return Path(pathname); #elif defined(HAVE_MKTEMP) // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing // the XXXXXX with the pid of the process and a letter. That leads to only // twenty six temporary files that can be generated. - char pathname[MAXPATHLEN]; - strcpy(pathname, "/tmp/llvm_XXXXXX"); + char pathname[] = "/tmp/llvm_XXXXXX"; char *TmpName = ::mktemp(pathname); if (TmpName == 0) { MakeErrMsg(ErrMsg, @@ -192,10 +189,7 @@ Path::GetTemporaryDirectory(std::string *ErrMsg) { std::string(TmpName) + ": can't create temporary directory"); return Path(); } - Path result; - result.set(TmpName); - assert(result.isValid() && "mktemp didn't create a valid pathname!"); - return result; + return Path(TmpName); #else // This is the worst case implementation. tempnam(3) leaks memory unless its // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread @@ -216,10 +210,7 @@ Path::GetTemporaryDirectory(std::string *ErrMsg) { std::string(pathname) + ": can't create temporary directory"); return Path(); } - Path result; - result.set(pathname); - assert(result.isValid() && "mkstemp didn't create a valid pathname!"); - return result; + return Path(pathname); #endif } @@ -282,14 +273,14 @@ Path::GetCurrentDirectory() { return Path(pathname); } -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix) static int test_dir(char buf[PATH_MAX], char ret[PATH_MAX], const char *dir, const char *bin) { struct stat sb; - snprintf(buf, PATH_MAX, "%s//%s", dir, bin); + snprintf(buf, PATH_MAX, "%s/%s", dir, bin); if (realpath(buf, ret) == NULL) return (1); if (stat(buf, &sb) != 0) @@ -334,7 +325,7 @@ getprogpath(char ret[PATH_MAX], const char *bin) free(pv); return (NULL); } -#endif // __FreeBSD__ +#endif // __FreeBSD__ || __NetBSD__ /// GetMainExecutable - Return the path to the main executable, given the /// value of argv[0] from program startup. @@ -348,18 +339,18 @@ Path Path::GetMainExecutable(const char *argv0, void *MainAddr) { if (_NSGetExecutablePath(exe_path, &size) == 0) { char link_path[MAXPATHLEN]; if (realpath(exe_path, link_path)) - return Path(std::string(link_path)); + return Path(link_path); } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix) char exe_path[PATH_MAX]; if (getprogpath(exe_path, argv0) != NULL) - return Path(std::string(exe_path)); + 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(std::string(exe_path, len)); + return Path(StringRef(exe_path, len)); #elif defined(HAVE_DLFCN_H) // Use dladdr to get executable path if available. Dl_info DLInfo; @@ -371,7 +362,9 @@ Path Path::GetMainExecutable(const char *argv0, void *MainAddr) { // the actual executable. char link_path[MAXPATHLEN]; if (realpath(DLInfo.dli_fname, link_path)) - return Path(std::string(link_path)); + return Path(link_path); +#else +#error GetMainExecutable is not implemented on this host yet. #endif return Path(); } @@ -437,9 +430,18 @@ Path::isDirectory() const { struct stat buf; if (0 != stat(path.c_str(), &buf)) return false; - return buf.st_mode & S_IFDIR ? true : false; + return ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false; +} + +bool +Path::isSymLink() const { + struct stat buf; + if (0 != lstat(path.c_str(), &buf)) + return false; + return S_ISLNK(buf.st_mode); } + bool Path::canRead() const { return 0 == access(path.c_str(), R_OK); @@ -590,12 +592,7 @@ bool Path::set(StringRef a_path) { if (a_path.empty()) return false; - std::string save(path); path = a_path; - if (!isValid()) { - path = save; - return false; - } return true; } @@ -603,14 +600,9 @@ bool Path::appendComponent(StringRef name) { if (name.empty()) return false; - std::string save(path); if (!lastIsSlash(path)) path += '/'; path += name; - if (!isValid()) { - path = save; - return false; - } return true; } @@ -632,20 +624,7 @@ Path::eraseComponent() { } bool -Path::appendSuffix(StringRef suffix) { - std::string save(path); - path.append("."); - path.append(suffix); - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool Path::eraseSuffix() { - std::string save = path; size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); if (dotpos != std::string::npos) { @@ -654,8 +633,6 @@ Path::eraseSuffix() { return true; } } - if (!isValid()) - path = save; return false; } @@ -690,8 +667,7 @@ static bool createDirectoryHelper(char* beg, char* end, bool create_parents) { bool Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) { // Get a writeable copy of the path name - char pathname[MAXPATHLEN]; - path.copy(pathname,MAXPATHLEN); + std::string pathname(path); // Null-terminate the last component size_t lastchar = path.length() - 1 ; @@ -699,11 +675,10 @@ Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) { if (pathname[lastchar] != '/') ++lastchar; - pathname[lastchar] = 0; + pathname[lastchar] = '\0'; - if (createDirectoryHelper(pathname, pathname+lastchar, create_parents)) - return MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create directory"); + if (createDirectoryHelper(&pathname[0], &pathname[lastchar], create_parents)) + return MakeErrMsg(ErrMsg, pathname + ": can't create directory"); return false; } @@ -768,17 +743,15 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { } // Otherwise, try to just remove the one directory. - char pathname[MAXPATHLEN]; - path.copy(pathname, MAXPATHLEN); + std::string pathname(path); size_t lastchar = path.length() - 1; if (pathname[lastchar] == '/') - pathname[lastchar] = 0; + pathname[lastchar] = '\0'; else - pathname[lastchar+1] = 0; + pathname[lastchar+1] = '\0'; - if (rmdir(pathname) != 0) - return MakeErrMsg(ErrStr, - std::string(pathname) + ": can't erase directory"); + if (rmdir(pathname.c_str()) != 0) + return MakeErrMsg(ErrStr, pathname + ": can't erase directory"); return false; } |