X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FUnix%2FPathV2.inc;h=03ff28367e44c5e653f6080e5e89e43aaec714f5;hb=0eeca440469e23f2db2bea3d7b136f0f95f6ff1d;hp=c547e6606f776998411d9d599dce27cf5099da8b;hpb=79c3c3a1dece6408e45933ba575e05ceb6208235;p=oota-llvm.git diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc index c547e6606f7..03ff28367e4 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -23,6 +23,22 @@ #if HAVE_FCNTL_H #include #endif +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif #if HAVE_STDIO_H #include #endif @@ -214,8 +230,17 @@ error_code rename(const Twine &from, const Twine &to) { StringRef f = from.toNullTerminatedStringRef(from_storage); StringRef t = to.toNullTerminatedStringRef(to_storage); - if (::rename(f.begin(), t.begin()) == -1) - return error_code(errno, system_category()); + if (::rename(f.begin(), t.begin()) == -1) { + // If it's a cross device link, copy then delete, otherwise return the error + if (errno == EXDEV) { + if (error_code ec = copy_file(from, to, copy_option::overwrite_if_exists)) + return ec; + bool Existed; + if (error_code ec = remove(from, Existed)) + return ec; + } else + return error_code(errno, system_category()); + } return success; } @@ -324,12 +349,11 @@ error_code unique_file(const Twine &model, int &result_fd, Model.c_str(); // Make model absolute by prepending a temp directory if it's not already. - bool absolute; - if (error_code ec = path::is_absolute(Twine(Model), absolute)) return ec; + bool absolute = path::is_absolute(Twine(Model)); if (!absolute) { SmallString<128> TDir; if (error_code ec = TempDir(TDir)) return ec; - if (error_code ec = path::append(TDir, Twine(Model))) return ec; + path::append(TDir, Twine(Model)); Model.swap(TDir); } @@ -374,7 +398,7 @@ rety_open_create: SmallString<64> dir_to_create; for (path::const_iterator i = path::begin(p), e = --path::end(p); i != e; ++i) { - if (error_code ec = path::append(dir_to_create, *i)) return ec; + path::append(dir_to_create, *i); bool Exists; if (error_code ec = exists(Twine(dir_to_create), Exists)) return ec; if (!Exists) { @@ -395,9 +419,10 @@ rety_open_create: // Make the path absolute. char real_path_buff[PATH_MAX + 1]; if (realpath(RandomPath.c_str(), real_path_buff) == NULL) { + int error = errno; ::close(RandomFD); ::unlink(RandomPath.c_str()); - return error_code(errno, system_category()); + return error_code(error, system_category()); } result_path.clear(); @@ -408,6 +433,75 @@ rety_open_create: return success; } +error_code directory_iterator_construct(directory_iterator &it, StringRef path){ + SmallString<128> path_null(path); + DIR *directory = ::opendir(path_null.c_str()); + if (directory == 0) + return error_code(errno, system_category()); + + it.IterationHandle = reinterpret_cast(directory); + // Add something for replace_filename to replace. + path::append(path_null, "."); + it.CurrentEntry = directory_entry(path_null.str()); + return directory_iterator_increment(it); +} + +error_code directory_iterator_destruct(directory_iterator& it) { + if (it.IterationHandle) + ::closedir(reinterpret_cast(it.IterationHandle)); + it.IterationHandle = 0; + it.CurrentEntry = directory_entry(); + return success; +} + +error_code directory_iterator_increment(directory_iterator& it) { + errno = 0; + dirent *cur_dir = ::readdir(reinterpret_cast(it.IterationHandle)); + if (cur_dir == 0 && errno != 0) { + return error_code(errno, system_category()); + } else if (cur_dir != 0) { + StringRef name(cur_dir->d_name, NAMLEN(cur_dir)); + if ((name.size() == 1 && name[0] == '.') || + (name.size() == 2 && name[0] == '.' && name[1] == '.')) + return directory_iterator_increment(it); + it.CurrentEntry.replace_filename(name); + } else + return directory_iterator_destruct(it); + + return success; +} + +error_code get_magic(const Twine &path, uint32_t len, + SmallVectorImpl &result) { + SmallString<128> PathStorage; + StringRef Path = path.toNullTerminatedStringRef(PathStorage); + result.set_size(0); + + // Open path. + std::FILE *file = std::fopen(Path.data(), "rb"); + if (file == 0) + return error_code(errno, system_category()); + + // Reserve storage. + result.reserve(len); + + // Read magic! + size_t size = std::fread(result.data(), 1, len, file); + if (std::ferror(file) != 0) { + std::fclose(file); + return error_code(errno, system_category()); + } else if (size != result.size()) { + if (std::feof(file) != 0) { + std::fclose(file); + result.set_size(size); + return make_error_code(errc::value_too_large); + } + } + std::fclose(file); + result.set_size(len); + return success; +} + } // end namespace fs } // end namespace sys } // end namespace llvm