Struct cap_primitives::fs::Metadata
source · pub struct Metadata { /* private fields */ }
Expand description
Metadata information about a file.
This corresponds to std::fs::Metadata
.
Implementations§
source§impl Metadata
impl Metadata
sourcepub fn from_file(file: &File) -> Result<Self>
pub fn from_file(file: &File) -> Result<Self>
Constructs a new instance of Self
from the given std::fs::File
.
Examples found in repository?
More examples
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
pub(crate) fn stat_unchecked(
start: &fs::File,
path: &Path,
follow: FollowSymlinks,
) -> io::Result<Metadata> {
// When we have `windows_by_handle`, we just call `fs::metadata` etc. and it
// has everything.
#[cfg(windows_by_handle)]
{
let full_path = concatenate(start, path)?;
match follow {
FollowSymlinks::Yes => fs::metadata(full_path),
FollowSymlinks::No => fs::symlink_metadata(full_path),
}
.map(Metadata::from_just_metadata)
}
// Otherwise, attempt to open the file to get the metadata that way, as
// that gives us all the info.
#[cfg(not(windows_by_handle))]
{
let mut opts = OpenOptions::new();
opts.access_mode(0);
match follow {
FollowSymlinks::Yes => {
opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS);
opts.follow(FollowSymlinks::Yes);
}
FollowSymlinks::No => {
opts.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
opts.follow(FollowSymlinks::No);
}
}
let file = open_unchecked(start, path, &opts)?;
Metadata::from_file(&file)
}
}
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
pub(crate) fn stat(start: &fs::File, path: &Path, follow: FollowSymlinks) -> io::Result<Metadata> {
// POSIX returns `ENOENT` on an empty path. TODO: On Windows, we should
// be compatible with what Windows does instead.
if path.as_os_str().is_empty() {
return Err(errors::no_such_file_or_directory());
}
let mut options = OpenOptions::new();
options.follow(follow);
let mut symlink_count = 0;
let mut ctx = Context::new(MaybeOwnedFile::borrowed(start), path, &options, None);
assert!(!ctx.dir_precluded);
while let Some(c) = ctx.components.pop() {
match c {
CowComponent::PrefixOrRootDir => return Err(errors::escape_attempt()),
CowComponent::CurDir => ctx.cur_dir()?,
CowComponent::ParentDir => ctx.parent_dir()?,
CowComponent::Normal(one) => {
if ctx.components.is_empty() {
// If this is the last component, do a non-following
// `stat_unchecked` on it.
let stat = stat_unchecked(&ctx.base, one.as_ref(), FollowSymlinks::No)?;
// If we weren't asked to follow symlinks, or it wasn't a
// symlink, we're done.
if options.follow == FollowSymlinks::No || !stat.file_type().is_symlink() {
if stat.is_dir() {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
} else if ctx.dir_required {
return Err(errors::is_not_directory());
}
return Ok(stat);
}
// On Windows, symlinks know whether they are a file or
// directory.
#[cfg(windows)]
if stat.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0 {
ctx.dir_required = true;
} else {
ctx.dir_precluded = true;
}
// If it was a symlink and we're asked to follow symlinks,
// dereference it.
ctx.symlink(&one, &mut symlink_count)?
} else {
// Otherwise open the path component normally.
ctx.normal(&one, &options, &mut symlink_count)?
}
}
}
}
// If the path ended in `.` (explicit or implied) or `..`, we may have
// opened the directory with eg. `O_PATH` on Linux, or we may have skipped
// checking for search access to `.`, so re-check it.
if ctx.follow_with_dot {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
ctx.check_dot_access()?;
}
// If the path ended in `.` or `..`, we already have it open, so just do
// `.metadata()` on it.
Metadata::from_file(&*ctx.base)
}
sourcepub fn from_just_metadata(std: Metadata) -> Self
pub fn from_just_metadata(std: Metadata) -> Self
Constructs a new instance of Self
from the given
std::fs::Metadata
.
As with the comments in std::fs::Metadata::volume_serial_number
and
nearby functions, some fields of the resulting metadata will be None
.
sourcepub const fn file_type(&self) -> FileType
pub const fn file_type(&self) -> FileType
Returns the file type for this metadata.
This corresponds to std::fs::Metadata::file_type
.
Examples found in repository?
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
pub(crate) fn stat(start: &fs::File, path: &Path, follow: FollowSymlinks) -> io::Result<Metadata> {
// POSIX returns `ENOENT` on an empty path. TODO: On Windows, we should
// be compatible with what Windows does instead.
if path.as_os_str().is_empty() {
return Err(errors::no_such_file_or_directory());
}
let mut options = OpenOptions::new();
options.follow(follow);
let mut symlink_count = 0;
let mut ctx = Context::new(MaybeOwnedFile::borrowed(start), path, &options, None);
assert!(!ctx.dir_precluded);
while let Some(c) = ctx.components.pop() {
match c {
CowComponent::PrefixOrRootDir => return Err(errors::escape_attempt()),
CowComponent::CurDir => ctx.cur_dir()?,
CowComponent::ParentDir => ctx.parent_dir()?,
CowComponent::Normal(one) => {
if ctx.components.is_empty() {
// If this is the last component, do a non-following
// `stat_unchecked` on it.
let stat = stat_unchecked(&ctx.base, one.as_ref(), FollowSymlinks::No)?;
// If we weren't asked to follow symlinks, or it wasn't a
// symlink, we're done.
if options.follow == FollowSymlinks::No || !stat.file_type().is_symlink() {
if stat.is_dir() {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
} else if ctx.dir_required {
return Err(errors::is_not_directory());
}
return Ok(stat);
}
// On Windows, symlinks know whether they are a file or
// directory.
#[cfg(windows)]
if stat.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0 {
ctx.dir_required = true;
} else {
ctx.dir_precluded = true;
}
// If it was a symlink and we're asked to follow symlinks,
// dereference it.
ctx.symlink(&one, &mut symlink_count)?
} else {
// Otherwise open the path component normally.
ctx.normal(&one, &options, &mut symlink_count)?
}
}
}
}
// If the path ended in `.` (explicit or implied) or `..`, we may have
// opened the directory with eg. `O_PATH` on Linux, or we may have skipped
// checking for search access to `.`, so re-check it.
if ctx.follow_with_dot {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
ctx.check_dot_access()?;
}
// If the path ended in `.` or `..`, we already have it open, so just do
// `.metadata()` on it.
Metadata::from_file(&*ctx.base)
}
sourcepub fn is_dir(&self) -> bool
pub fn is_dir(&self) -> bool
Returns true
if this metadata is for a directory.
This corresponds to std::fs::Metadata::is_dir
.
Examples found in repository?
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
pub(crate) fn stat(start: &fs::File, path: &Path, follow: FollowSymlinks) -> io::Result<Metadata> {
// POSIX returns `ENOENT` on an empty path. TODO: On Windows, we should
// be compatible with what Windows does instead.
if path.as_os_str().is_empty() {
return Err(errors::no_such_file_or_directory());
}
let mut options = OpenOptions::new();
options.follow(follow);
let mut symlink_count = 0;
let mut ctx = Context::new(MaybeOwnedFile::borrowed(start), path, &options, None);
assert!(!ctx.dir_precluded);
while let Some(c) = ctx.components.pop() {
match c {
CowComponent::PrefixOrRootDir => return Err(errors::escape_attempt()),
CowComponent::CurDir => ctx.cur_dir()?,
CowComponent::ParentDir => ctx.parent_dir()?,
CowComponent::Normal(one) => {
if ctx.components.is_empty() {
// If this is the last component, do a non-following
// `stat_unchecked` on it.
let stat = stat_unchecked(&ctx.base, one.as_ref(), FollowSymlinks::No)?;
// If we weren't asked to follow symlinks, or it wasn't a
// symlink, we're done.
if options.follow == FollowSymlinks::No || !stat.file_type().is_symlink() {
if stat.is_dir() {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
} else if ctx.dir_required {
return Err(errors::is_not_directory());
}
return Ok(stat);
}
// On Windows, symlinks know whether they are a file or
// directory.
#[cfg(windows)]
if stat.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0 {
ctx.dir_required = true;
} else {
ctx.dir_precluded = true;
}
// If it was a symlink and we're asked to follow symlinks,
// dereference it.
ctx.symlink(&one, &mut symlink_count)?
} else {
// Otherwise open the path component normally.
ctx.normal(&one, &options, &mut symlink_count)?
}
}
}
}
// If the path ended in `.` (explicit or implied) or `..`, we may have
// opened the directory with eg. `O_PATH` on Linux, or we may have skipped
// checking for search access to `.`, so re-check it.
if ctx.follow_with_dot {
if ctx.dir_precluded {
return Err(errors::is_directory());
}
ctx.check_dot_access()?;
}
// If the path ended in `.` or `..`, we already have it open, so just do
// `.metadata()` on it.
Metadata::from_file(&*ctx.base)
}
sourcepub fn is_file(&self) -> bool
pub fn is_file(&self) -> bool
Returns true
if this metadata is for a regular file.
This corresponds to std::fs::Metadata::is_file
.
sourcepub fn is_symlink(&self) -> bool
pub fn is_symlink(&self) -> bool
Returns true
if this metadata is for a symbolic link.
This corresponds to std::fs::Metadata::is_symlink
.
Examples found in repository?
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
pub(crate) fn remove_dir_all_impl(start: &fs::File, path: &Path) -> io::Result<()> {
// Open the directory, following symlinks, to make sure it is a directory.
let file = open_dir(start, path)?;
// Test whether the path is a symlink.
let md = stat(start, path, FollowSymlinks::No)?;
drop(file);
if md.is_symlink() {
// If so, just remove the link.
remove_dir(start, path)
} else {
// Otherwise, remove the tree.
let dir = open_dir_nofollow(start, path)?;
remove_open_dir_all_impl(dir)
}
}
sourcepub const fn len(&self) -> u64
pub const fn len(&self) -> u64
Returns the size of the file, in bytes, this metadata is for.
This corresponds to std::fs::Metadata::len
.
sourcepub fn permissions(&self) -> Permissions
pub fn permissions(&self) -> Permissions
Returns the permissions of the file this metadata is for.
This corresponds to std::fs::Metadata::permissions
.
sourcepub fn modified(&self) -> Result<SystemTime>
pub fn modified(&self) -> Result<SystemTime>
Returns the last modification time listed in this metadata.
This corresponds to std::fs::Metadata::modified
.
sourcepub fn accessed(&self) -> Result<SystemTime>
pub fn accessed(&self) -> Result<SystemTime>
Returns the last access time of this metadata.
This corresponds to std::fs::Metadata::accessed
.
sourcepub fn created(&self) -> Result<SystemTime>
pub fn created(&self) -> Result<SystemTime>
Returns the creation time listed in this metadata.
This corresponds to std::fs::Metadata::created
.