Skip to content

Commit

Permalink
feat(fd): implement fcntl(F_GETFL)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkroening committed Mar 4, 2025
1 parent 042f31b commit c9879f7
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/fd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ pub(crate) trait ObjectInterface: Sync + Send + core::fmt::Debug {
Err(io::Error::ENOSYS)
}

/// Returns the file status flags.
async fn status_flags(&self) -> io::Result<StatusFlags> {
Err(io::Error::ENOSYS)
}

/// Sets the file status flags.
async fn set_status_flags(&self, _status_flags: StatusFlags) -> io::Result<()> {
Err(io::Error::ENOSYS)
Expand Down
14 changes: 14 additions & 0 deletions src/fd/socket/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,16 @@ impl Socket {
}
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
let status_flags = if self.is_nonblocking {
fd::StatusFlags::O_NONBLOCK
} else {
fd::StatusFlags::empty()
};

Ok(status_flags)
}

async fn set_status_flags(&mut self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.is_nonblocking = status_flags.contains(fd::StatusFlags::O_NONBLOCK);
Ok(())
Expand Down Expand Up @@ -502,6 +512,10 @@ impl ObjectInterface for async_lock::RwLock<Socket> {
self.read().await.shutdown(how).await
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
self.read().await.status_flags().await
}

async fn set_status_flags(&self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.write().await.set_status_flags(status_flags).await
}
Expand Down
14 changes: 14 additions & 0 deletions src/fd/socket/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ impl Socket {
}
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
let status_flags = if self.nonblocking {
fd::StatusFlags::O_NONBLOCK
} else {
fd::StatusFlags::empty()
};

Ok(status_flags)
}

async fn set_status_flags(&mut self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.nonblocking = status_flags.contains(fd::StatusFlags::O_NONBLOCK);
Ok(())
Expand Down Expand Up @@ -258,6 +268,10 @@ impl ObjectInterface for async_lock::RwLock<Socket> {
self.read().await.write(buf).await
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
self.read().await.status_flags().await
}

async fn set_status_flags(&self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.write().await.set_status_flags(status_flags).await
}
Expand Down
14 changes: 14 additions & 0 deletions src/fd/socket/vsock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,16 @@ impl Socket {
Ok(())
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
let status_flags = if self.is_nonblocking {
fd::StatusFlags::O_NONBLOCK
} else {
fd::StatusFlags::empty()
};

Ok(status_flags)
}

async fn set_status_flags(&mut self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.is_nonblocking = status_flags.contains(fd::StatusFlags::O_NONBLOCK);
Ok(())
Expand Down Expand Up @@ -450,6 +460,10 @@ impl ObjectInterface for async_lock::RwLock<Socket> {
self.read().await.shutdown(how).await
}

async fn status_flags(&self) -> io::Result<fd::StatusFlags> {
self.read().await.status_flags().await
}

async fn set_status_flags(&self, status_flags: fd::StatusFlags) -> io::Result<()> {
self.write().await.set_status_flags(status_flags).await
}
Expand Down
12 changes: 12 additions & 0 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,11 +537,23 @@ pub unsafe extern "C" fn sys_ioctl(
#[unsafe(no_mangle)]
pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 {
const F_SETFD: i32 = 2;
const F_GETFL: i32 = 3;
const F_SETFL: i32 = 4;
const FD_CLOEXEC: i32 = 1;

if cmd == F_SETFD && arg == FD_CLOEXEC {
0
} else if cmd == F_GETFL {
let obj = get_object(fd);
obj.map_or_else(
|e| -num::ToPrimitive::to_i32(&e).unwrap(),
|v| {
block_on((*v).status_flags(), None).map_or_else(
|e| -num::ToPrimitive::to_i32(&e).unwrap(),
|status_flags| status_flags.bits(),
)
},
)
} else if cmd == F_SETFL {
let obj = get_object(fd);
obj.map_or_else(
Expand Down

0 comments on commit c9879f7

Please sign in to comment.