-
Notifications
You must be signed in to change notification settings - Fork 130
Open
Description
Hi,
If a file is deleted while still opened by a process, the fd under /proc/$pid/fd/$fd
will show up as
[tatref@srv dev]$ ls -ld /proc/12779/fd/*
lr-x------ 1 tatref tatref 64 Oct 16 01:00 /proc/12779/fd/4 -> '/home/tatref/dev/tes (deleted)'
We can get that info with
use std::fs::File;
use std::fs::Metadata;
use std::os::unix::fs::MetadataExt;
let f = File::open(&format!("/proc/{}/fd/{}", p.pid, fd.fd)).unwrap();
let metadata = f.metadata().unwrap();
if metadata.nlink() == 0 {}
So this means format a String, open a file, and do a syscall to get metadata.
Currently it seems there is no easier API in procfs
to access this information (please correct me if I'm wrong).
FDTarget
has a Path
variant, but there is no guarantee that another file with the same name hasn't be created.
Maybe we could store a File
in the FDInfo
, and add it where it is created:
procfs/procfs/src/process/mod.rs
Lines 149 to 175 in e303757
fn from_process_at<P: AsRef<Path>, Q: AsRef<Path>>( | |
base: P, | |
dirfd: BorrowedFd, | |
path: Q, | |
fd: i32, | |
) -> ProcResult<Self> { | |
let p = path.as_ref(); | |
let root = base.as_ref().join(p); | |
// for 2.6.39 <= kernel < 3.6 fstat doesn't support O_PATH see https://github.com/eminence/procfs/issues/265 | |
let flags = match Version::cached() { | |
Ok(v) if v < KernelVersion::new(3, 6, 0) => OFlags::NOFOLLOW | OFlags::CLOEXEC, | |
Ok(_) => OFlags::NOFOLLOW | OFlags::PATH | OFlags::CLOEXEC, | |
Err(_) => OFlags::NOFOLLOW | OFlags::PATH | OFlags::CLOEXEC, | |
}; | |
let file = wrap_io_error!(root, rustix::fs::openat(dirfd, p, flags, Mode::empty()))?; | |
let link = rustix::fs::readlinkat(&file, "", Vec::new()).map_err(io::Error::from)?; | |
let md = | |
rustix::fs::statat(&file, "", AtFlags::SYMLINK_NOFOLLOW | AtFlags::EMPTY_PATH).map_err(io::Error::from)?; | |
let link_os = link.to_string_lossy(); | |
let target = FDTarget::from_str(link_os.as_ref())?; | |
Ok(FDInfo { | |
fd, | |
mode: (md.st_mode & Mode::RWXU.bits()) as u16, | |
target, | |
}) | |
} |
What do you think?
5121f and irthaal
Metadata
Metadata
Assignees
Labels
No labels