Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions litebox/src/fs/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum SeekError {
InvalidOffset,
#[error("non-seekable file")]
NonSeekable,
#[error("file descriptor is not open for seeking")]
NotOpenForSeeking,
#[error("I/O error")]
Io,
}
Expand All @@ -92,6 +94,8 @@ pub enum TruncateError {
IsDirectory,
#[error("file is not opened for writing")]
NotForWriting,
#[error("file descriptor is not open for writing")]
NotOpenForWriting,
#[error("file descriptor points to a terminal device")]
IsTerminalDevice,
#[error("I/O error")]
Expand Down Expand Up @@ -194,6 +198,8 @@ pub enum ReadDirError {
ClosedFd,
#[error("fd does not point to a directory")]
NotADirectory,
#[error("file descriptor is not open for reading")]
NotOpenForReading,
#[error("I/O error")]
Io,
}
Expand Down
27 changes: 11 additions & 16 deletions litebox/src/fs/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
.entry_handle(fd)
.ok_or(ReadError::ClosedFd)?;
let mut entry = entry.get_entry_mut();
if entry.entry.path_only {
return Err(ReadError::NotForReading);
}
// XXX(jayb): This over-holds the descriptor-entry lock across backend I/O. We need a
// smaller per-open-file-description primitive for position/append serialization, so the
// descriptor entry can be unlocked before potentially blocking backend calls.
Expand All @@ -662,10 +665,6 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
if !entry.entry.read_allowed {
return Err(ReadError::NotForReading);
}
if entry.entry.path_only {
// TODO(jayb): Add an error variant for operations not permitted on O_PATH fds.
unimplemented!("read from O_PATH fd")
}

let read_offset = match seek_behavior {
SeekBehavior::NonSeekable | SeekBehavior::ZeroPosition => 0,
Expand Down Expand Up @@ -699,6 +698,9 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
.entry_handle(fd)
.ok_or(WriteError::ClosedFd)?;
let mut entry = entry.get_entry_mut();
if entry.entry.path_only {
return Err(WriteError::NotForWriting);
}
// XXX(jayb): This over-holds the descriptor-entry lock across backend I/O. We need a
// smaller per-open-file-description primitive for position/append serialization, so the
// descriptor entry can be unlocked before potentially blocking backend calls.
Expand All @@ -710,10 +712,6 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
if !entry.entry.write_allowed {
return Err(WriteError::NotForWriting);
}
if entry.entry.path_only {
// TODO(jayb): Add an error variant for operations not permitted on O_PATH fds.
unimplemented!("write to O_PATH fd")
}

let write_offset = match seek_behavior {
SeekBehavior::NonSeekable | SeekBehavior::ZeroPosition => 0,
Expand Down Expand Up @@ -752,8 +750,7 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
Handle::Dir(_) => return Err(SeekError::NotAFile),
};
if entry.entry.path_only {
// TODO(jayb): Add an error variant for operations not permitted on O_PATH fds.
unimplemented!("seek on O_PATH fd")
return Err(SeekError::NotOpenForSeeking);
}

match entry.entry.seek_behavior {
Expand Down Expand Up @@ -806,13 +803,12 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
Handle::File(file) => file,
Handle::Dir(_) => return Err(TruncateError::IsDirectory),
};
if entry.entry.path_only {
return Err(TruncateError::NotOpenForWriting);
}
if !entry.entry.write_allowed {
return Err(TruncateError::NotForWriting);
}
if entry.entry.path_only {
// TODO(jayb): Add an error variant for operations not permitted on O_PATH fds.
unimplemented!("truncate O_PATH fd")
}

self.backend.truncate(file, length)?;
if reset_offset {
Expand Down Expand Up @@ -957,8 +953,7 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Backend: super::backend::Backend
.ok_or(ReadDirError::ClosedFd)?;
let entry = entry.get_entry();
if entry.entry.path_only {
// TODO(jayb): Add an error variant for operations not permitted on O_PATH fds.
unimplemented!("read_dir on O_PATH fd")
return Err(ReadDirError::NotOpenForReading);
}
let dir = match &entry.entry.handle {
Handle::File(_) => return Err(ReadDirError::NotADirectory),
Expand Down
3 changes: 3 additions & 0 deletions litebox_common_linux/src/errno/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl From<litebox::fs::errors::SeekError> for Errno {
}
litebox::fs::errors::SeekError::InvalidOffset => Errno::EINVAL,
litebox::fs::errors::SeekError::NonSeekable => Errno::ESPIPE,
litebox::fs::errors::SeekError::NotOpenForSeeking => Errno::EBADF,
litebox::fs::errors::SeekError::Io => Errno::EIO,
_ => unimplemented!(),
}
Expand Down Expand Up @@ -540,6 +541,7 @@ impl From<litebox::fs::errors::ReadDirError> for Errno {
fn from(value: litebox::fs::errors::ReadDirError) -> Self {
match value {
litebox::fs::errors::ReadDirError::NotADirectory => Errno::ENOTDIR,
litebox::fs::errors::ReadDirError::NotOpenForReading => Errno::EBADF,
_ => unimplemented!(),
}
}
Expand Down Expand Up @@ -601,6 +603,7 @@ impl From<litebox::fs::errors::TruncateError> for Errno {
match value {
litebox::fs::errors::TruncateError::IsDirectory => Errno::EISDIR,
litebox::fs::errors::TruncateError::NotForWriting => Errno::EACCES,
litebox::fs::errors::TruncateError::NotOpenForWriting => Errno::EBADF,
litebox::fs::errors::TruncateError::IsTerminalDevice => Errno::EINVAL,
litebox::fs::errors::TruncateError::ClosedFd => Errno::EBADF,
litebox::fs::errors::TruncateError::Io => Errno::EIO,
Expand Down
Loading