mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-03 07:38:57 +00:00
[libcxx] Hook up a number of operation functions to their windows counterparts
Use the corresponding wchar functions, named "_wfunc" instead of "func", where feasible, or reimplement functions with native windows APIs. Differential Revision: https://reviews.llvm.org/D91143
This commit is contained in:
parent
592d623529
commit
efec3cc652
@ -405,7 +405,7 @@ struct FileDescriptor {
|
||||
static FileDescriptor create(const path* p, error_code& ec, Args... args) {
|
||||
ec.clear();
|
||||
int fd;
|
||||
if ((fd = ::open(p->c_str(), args...)) == -1) {
|
||||
if ((fd = detail::open(p->c_str(), args...)) == -1) {
|
||||
ec = capture_errno();
|
||||
return FileDescriptor{p};
|
||||
}
|
||||
@ -431,7 +431,7 @@ struct FileDescriptor {
|
||||
|
||||
void close() noexcept {
|
||||
if (fd != -1)
|
||||
::close(fd);
|
||||
detail::close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ file_status posix_lstat(path const& p, error_code* ec) {
|
||||
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
|
||||
bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
|
||||
if (::ftruncate(fd.fd, to_size) == -1) {
|
||||
if (detail::ftruncate(fd.fd, to_size) == -1) {
|
||||
ec = capture_errno();
|
||||
return true;
|
||||
}
|
||||
@ -828,8 +828,8 @@ bool __copy_file(const path& from, const path& to, copy_options options,
|
||||
ErrorHandler<bool> err("copy_file", ec, &to, &from);
|
||||
|
||||
error_code m_ec;
|
||||
FileDescriptor from_fd =
|
||||
FileDescriptor::create_with_status(&from, m_ec, O_RDONLY | O_NONBLOCK);
|
||||
FileDescriptor from_fd = FileDescriptor::create_with_status(
|
||||
&from, m_ec, O_RDONLY | O_NONBLOCK | O_BINARY);
|
||||
if (m_ec)
|
||||
return err.report(m_ec);
|
||||
|
||||
@ -881,7 +881,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
|
||||
|
||||
// Don't truncate right away. We may not be opening the file we originally
|
||||
// looked at; we'll check this later.
|
||||
int to_open_flags = O_WRONLY;
|
||||
int to_open_flags = O_WRONLY | O_BINARY;
|
||||
if (!to_exists)
|
||||
to_open_flags |= O_CREAT;
|
||||
FileDescriptor to_fd = FileDescriptor::create_with_status(
|
||||
@ -917,10 +917,13 @@ void __copy_symlink(const path& existing_symlink, const path& new_symlink,
|
||||
if (ec && *ec) {
|
||||
return;
|
||||
}
|
||||
// NOTE: proposal says you should detect if you should call
|
||||
// create_symlink or create_directory_symlink. I don't think this
|
||||
// is needed with POSIX
|
||||
__create_symlink(real_path, new_symlink, ec);
|
||||
#if defined(_LIBCPP_WIN32API)
|
||||
error_code local_ec;
|
||||
if (is_directory(real_path, local_ec))
|
||||
__create_directory_symlink(real_path, new_symlink, ec);
|
||||
else
|
||||
#endif
|
||||
__create_symlink(real_path, new_symlink, ec);
|
||||
}
|
||||
|
||||
bool __create_directories(const path& p, error_code* ec) {
|
||||
@ -953,7 +956,7 @@ bool __create_directories(const path& p, error_code* ec) {
|
||||
bool __create_directory(const path& p, error_code* ec) {
|
||||
ErrorHandler<bool> err("create_directory", ec, &p);
|
||||
|
||||
if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
|
||||
if (detail::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
|
||||
return true;
|
||||
|
||||
if (errno == EEXIST) {
|
||||
@ -981,7 +984,7 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) {
|
||||
return err.report(errc::not_a_directory,
|
||||
"the specified attribute path is invalid");
|
||||
|
||||
if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
|
||||
if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0)
|
||||
return true;
|
||||
|
||||
if (errno == EEXIST) {
|
||||
@ -1000,19 +1003,19 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) {
|
||||
void __create_directory_symlink(path const& from, path const& to,
|
||||
error_code* ec) {
|
||||
ErrorHandler<void> err("create_directory_symlink", ec, &from, &to);
|
||||
if (::symlink(from.c_str(), to.c_str()) != 0)
|
||||
if (detail::symlink_dir(from.c_str(), to.c_str()) == -1)
|
||||
return err.report(capture_errno());
|
||||
}
|
||||
|
||||
void __create_hard_link(const path& from, const path& to, error_code* ec) {
|
||||
ErrorHandler<void> err("create_hard_link", ec, &from, &to);
|
||||
if (::link(from.c_str(), to.c_str()) == -1)
|
||||
if (detail::link(from.c_str(), to.c_str()) == -1)
|
||||
return err.report(capture_errno());
|
||||
}
|
||||
|
||||
void __create_symlink(path const& from, path const& to, error_code* ec) {
|
||||
ErrorHandler<void> err("create_symlink", ec, &from, &to);
|
||||
if (::symlink(from.c_str(), to.c_str()) == -1)
|
||||
if (detail::symlink_file(from.c_str(), to.c_str()) == -1)
|
||||
return err.report(capture_errno());
|
||||
}
|
||||
|
||||
@ -1032,7 +1035,7 @@ path __current_path(error_code* ec) {
|
||||
|
||||
void __current_path(const path& p, error_code* ec) {
|
||||
ErrorHandler<void> err("current_path", ec, &p);
|
||||
if (::chdir(p.c_str()) == -1)
|
||||
if (detail::chdir(p.c_str()) == -1)
|
||||
err.report(capture_errno());
|
||||
}
|
||||
|
||||
@ -1236,7 +1239,7 @@ path __read_symlink(const path& p, error_code* ec) {
|
||||
|
||||
bool __remove(const path& p, error_code* ec) {
|
||||
ErrorHandler<bool> err("remove", ec, &p);
|
||||
if (::remove(p.c_str()) == -1) {
|
||||
if (detail::remove(p.c_str()) == -1) {
|
||||
if (errno != ENOENT)
|
||||
err.report(capture_errno());
|
||||
return false;
|
||||
@ -1285,13 +1288,13 @@ uintmax_t __remove_all(const path& p, error_code* ec) {
|
||||
|
||||
void __rename(const path& from, const path& to, error_code* ec) {
|
||||
ErrorHandler<void> err("rename", ec, &from, &to);
|
||||
if (::rename(from.c_str(), to.c_str()) == -1)
|
||||
if (detail::rename(from.c_str(), to.c_str()) == -1)
|
||||
err.report(capture_errno());
|
||||
}
|
||||
|
||||
void __resize_file(const path& p, uintmax_t size, error_code* ec) {
|
||||
ErrorHandler<void> err("resize_file", ec, &p);
|
||||
if (::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
|
||||
if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
|
||||
return err.report(capture_errno());
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
// These generally behave like the proper posix functions, with these
|
||||
// exceptions:
|
||||
// On Windows, they take paths in wchar_t* form, instead of char* form.
|
||||
// The symlink() function is split into two frontends, symlink_file()
|
||||
// and symlink_dir().
|
||||
//
|
||||
// These are provided within an anonymous namespace within the detail
|
||||
// namespace - callers need to include this header and call them as
|
||||
@ -82,6 +84,8 @@ namespace {
|
||||
#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
|
||||
#define S_ISSOCK(m) (((m) & _S_IFMT) == _S_IFSOCK)
|
||||
|
||||
#define O_NONBLOCK 0
|
||||
|
||||
|
||||
// There were 369 years and 89 leap days from the Windows epoch
|
||||
// (1601) to the Unix epoch (1970).
|
||||
@ -190,10 +194,108 @@ int fstat(int fd, StatT *buf) {
|
||||
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
|
||||
return stat_handle(h, buf);
|
||||
}
|
||||
|
||||
int mkdir(const wchar_t *path, int permissions) {
|
||||
(void)permissions;
|
||||
return _wmkdir(path);
|
||||
}
|
||||
|
||||
int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
|
||||
bool is_dir) {
|
||||
DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
|
||||
if (CreateSymbolicLinkW(newname, oldname,
|
||||
flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
|
||||
return 0;
|
||||
int e = GetLastError();
|
||||
if (e != ERROR_INVALID_PARAMETER)
|
||||
return set_errno(e);
|
||||
if (CreateSymbolicLinkW(newname, oldname, flags))
|
||||
return 0;
|
||||
return set_errno();
|
||||
}
|
||||
|
||||
int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
|
||||
return symlink_file_dir(oldname, newname, false);
|
||||
}
|
||||
|
||||
int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
|
||||
return symlink_file_dir(oldname, newname, true);
|
||||
}
|
||||
|
||||
int link(const wchar_t *oldname, const wchar_t *newname) {
|
||||
if (CreateHardLinkW(newname, oldname, nullptr))
|
||||
return 0;
|
||||
return set_errno();
|
||||
}
|
||||
|
||||
int remove(const wchar_t *path) {
|
||||
detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
|
||||
if (!h)
|
||||
return set_errno();
|
||||
FILE_DISPOSITION_INFO info;
|
||||
info.DeleteFile = TRUE;
|
||||
if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info)))
|
||||
return set_errno();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int truncate_handle(HANDLE h, off_t length) {
|
||||
LARGE_INTEGER size_param;
|
||||
size_param.QuadPart = length;
|
||||
if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
|
||||
return set_errno();
|
||||
if (!SetEndOfFile(h))
|
||||
return set_errno();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ftruncate(int fd, off_t length) {
|
||||
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
|
||||
return truncate_handle(h, length);
|
||||
}
|
||||
|
||||
int truncate(const wchar_t *path, off_t length) {
|
||||
detail::WinHandle h(path, GENERIC_WRITE, 0);
|
||||
if (!h)
|
||||
return set_errno();
|
||||
return truncate_handle(h, length);
|
||||
}
|
||||
|
||||
int rename(const wchar_t *from, const wchar_t *to) {
|
||||
if (!(MoveFileExW(from, to,
|
||||
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
|
||||
MOVEFILE_WRITE_THROUGH)))
|
||||
return set_errno();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class... Args> int open(const wchar_t *filename, Args... args) {
|
||||
return _wopen(filename, args...);
|
||||
}
|
||||
int close(int fd) { return _close(fd); }
|
||||
int chdir(const wchar_t *path) { return _wchdir(path); }
|
||||
#else
|
||||
int symlink_file(const char *oldname, const char *newname) {
|
||||
return ::symlink(oldname, newname);
|
||||
}
|
||||
int symlink_dir(const char *oldname, const char *newname) {
|
||||
return ::symlink(oldname, newname);
|
||||
}
|
||||
using ::chdir;
|
||||
using ::close;
|
||||
using ::fstat;
|
||||
using ::ftruncate;
|
||||
using ::link;
|
||||
using ::lstat;
|
||||
using ::mkdir;
|
||||
using ::open;
|
||||
using ::remove;
|
||||
using ::rename;
|
||||
using ::stat;
|
||||
using ::truncate;
|
||||
|
||||
#define O_BINARY 0
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user