Add Stat.is_symbolic_link_.
This commit is contained in:
parent
0d35ce485f
commit
8df67f0c3a
@ -182,6 +182,8 @@ Result<FileFd> FileFd::open(CSlice filepath, int32 flags, int32 mode) {
|
||||
// TODO: share mode
|
||||
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE;
|
||||
|
||||
DWORD native_flags = 0;
|
||||
|
||||
DWORD creation_disposition = 0;
|
||||
if (flags & Create) {
|
||||
if (flags & Truncate) {
|
||||
@ -197,9 +199,9 @@ Result<FileFd> FileFd::open(CSlice filepath, int32 flags, int32 mode) {
|
||||
} else {
|
||||
creation_disposition = OPEN_EXISTING;
|
||||
}
|
||||
native_flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
}
|
||||
|
||||
DWORD native_flags = 0;
|
||||
if (flags & Direct) {
|
||||
native_flags |= FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING;
|
||||
}
|
||||
@ -593,7 +595,19 @@ Result<Stat> FileFd::stat() const {
|
||||
res.atime_nsec_ = filetime_to_unix_time_nsec(basic_info.LastAccessTime.QuadPart);
|
||||
res.mtime_nsec_ = filetime_to_unix_time_nsec(basic_info.LastWriteTime.QuadPart);
|
||||
res.is_dir_ = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
res.is_reg_ = !res.is_dir_; // TODO this is still wrong
|
||||
if ((basic_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
|
||||
FILE_ATTRIBUTE_TAG_INFO tag_info;
|
||||
status = GetFileInformationByHandleEx(get_native_fd().fd(), FileAttributeTagInfo, &tag_info, sizeof(tag_info));
|
||||
if (!status) {
|
||||
return OS_ERROR("Get FileAttributeTagInfo failed");
|
||||
}
|
||||
res.is_reg_ = false;
|
||||
res.is_symbolic_link_ =
|
||||
(tag_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 && tag_info.ReparseTag == IO_REPARSE_TAG_SYMLINK;
|
||||
} else {
|
||||
res.is_reg_ = !res.is_dir_;
|
||||
res.is_symbolic_link_ = false;
|
||||
}
|
||||
|
||||
TRY_RESULT(file_size, get_file_size(*this));
|
||||
res.size_ = file_size.size_;
|
||||
|
@ -126,6 +126,7 @@ Stat from_native_stat(const struct ::stat &buf) {
|
||||
res.real_size_ = buf.st_blocks * 512;
|
||||
res.is_dir_ = (buf.st_mode & S_IFMT) == S_IFDIR;
|
||||
res.is_reg_ = (buf.st_mode & S_IFMT) == S_IFREG;
|
||||
res.is_symbolic_link_ = (buf.st_mode & S_IFMT) == S_IFLNK;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ namespace td {
|
||||
struct Stat {
|
||||
bool is_dir_;
|
||||
bool is_reg_;
|
||||
bool is_symbolic_link_;
|
||||
int64 size_;
|
||||
int64 real_size_;
|
||||
uint64 atime_nsec_;
|
||||
|
@ -434,6 +434,7 @@ Result<string> realpath(CSlice slice, bool ignore_access_denied) {
|
||||
if (res.empty()) {
|
||||
return Status::Error("Empty path");
|
||||
}
|
||||
// TODO GetFullPathName doesn't resolve symbolic links
|
||||
if (!slice.empty() && slice.end()[-1] == TD_DIR_SLASH) {
|
||||
if (res.back() != TD_DIR_SLASH) {
|
||||
res += TD_DIR_SLASH;
|
||||
|
@ -167,6 +167,14 @@ TEST(Port, Writev) {
|
||||
td::string content(expected_content.size(), '\0');
|
||||
ASSERT_EQ(content.size(), fd.read(content).move_as_ok());
|
||||
ASSERT_EQ(expected_content, content);
|
||||
|
||||
auto stat = td::stat(test_file_path).move_as_ok();
|
||||
CHECK(!stat.is_dir_);
|
||||
CHECK(stat.is_reg_);
|
||||
CHECK(!stat.is_symbolic_link_);
|
||||
CHECK(stat.size_ == static_cast<td::int64>(expected_content.size()));
|
||||
|
||||
td::unlink(test_file_path).ignore();
|
||||
}
|
||||
|
||||
#if TD_PORT_POSIX && !TD_THREAD_UNSUPPORTED
|
||||
|
Loading…
Reference in New Issue
Block a user