Skip to content

Commit 07993fd

Browse files
committed
Add Socket::nonblocking
Returns the status of the to nonblocking mode of the socket.
1 parent 2a62932 commit 07993fd

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

src/socket.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,21 @@ impl Socket {
357357
sys::try_clone(self.as_raw()).map(Socket::from_raw)
358358
}
359359

360-
/// Moves this TCP stream into or out of nonblocking mode.
360+
/// Returns true if this socket is set to nonblocking mode, false otherwise.
361+
///
362+
/// # Notes
363+
///
364+
/// On Unix this corresponds to calling `fcntl` returning the value of
365+
/// `O_NONBLOCK`.
366+
///
367+
/// On Windows it is not possible retrieve the nonblocking mode status.
368+
#[cfg(all(feature = "all", unix))]
369+
#[cfg_attr(docsrs, doc(all(feature = "all", unix)))]
370+
pub fn nonblocking(&self) -> io::Result<bool> {
371+
sys::nonblocking(self.as_raw())
372+
}
373+
374+
/// Moves this socket into or out of nonblocking mode.
361375
///
362376
/// # Notes
363377
///

src/sys/unix.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,12 @@ pub(crate) fn try_clone(fd: Socket) -> io::Result<Socket> {
661661
syscall!(fcntl(fd, libc::F_DUPFD_CLOEXEC, 0))
662662
}
663663

664+
#[cfg(all(feature = "all", unix))]
665+
pub(crate) fn nonblocking(fd: Socket) -> io::Result<bool> {
666+
let file_status_flags = fcntl_get(fd, libc::F_GETFL)?;
667+
Ok((file_status_flags & libc::O_NONBLOCK) != 0)
668+
}
669+
664670
pub(crate) fn set_nonblocking(fd: Socket, nonblocking: bool) -> io::Result<()> {
665671
if nonblocking {
666672
fcntl_add(fd, libc::F_GETFL, libc::F_SETFL, libc::O_NONBLOCK)
@@ -907,9 +913,14 @@ fn into_secs(duration: Duration) -> c_int {
907913
min(duration.as_secs(), c_int::MAX as u64) as c_int
908914
}
909915

916+
/// Get the flags using `cmd`.
917+
fn fcntl_get(fd: Socket, cmd: c_int) -> io::Result<c_int> {
918+
syscall!(fcntl(fd, cmd))
919+
}
920+
910921
/// Add `flag` to the current set flags of `F_GETFD`.
911922
fn fcntl_add(fd: Socket, get_cmd: c_int, set_cmd: c_int, flag: c_int) -> io::Result<()> {
912-
let previous = syscall!(fcntl(fd, get_cmd))?;
923+
let previous = fcntl_get(fd, get_cmd)?;
913924
let new = previous | flag;
914925
if new != previous {
915926
syscall!(fcntl(fd, set_cmd, new)).map(|_| ())
@@ -921,7 +932,7 @@ fn fcntl_add(fd: Socket, get_cmd: c_int, set_cmd: c_int, flag: c_int) -> io::Res
921932

922933
/// Remove `flag` to the current set flags of `F_GETFD`.
923934
fn fcntl_remove(fd: Socket, get_cmd: c_int, set_cmd: c_int, flag: c_int) -> io::Result<()> {
924-
let previous = syscall!(fcntl(fd, get_cmd))?;
935+
let previous = fcntl_get(fd, get_cmd)?;
925936
let new = previous & !flag;
926937
if new != previous {
927938
syscall!(fcntl(fd, set_cmd, new)).map(|_| ())

tests/socket.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,19 @@ fn type_nonblocking() {
227227
/// Assert that `NONBLOCK` is set on `socket`.
228228
#[cfg(unix)]
229229
#[track_caller]
230-
pub fn assert_nonblocking<S>(socket: &S, want: bool)
231-
where
232-
S: AsRawFd,
233-
{
234-
let flags = unsafe { libc::fcntl(socket.as_raw_fd(), libc::F_GETFL) };
235-
assert_eq!(flags & libc::O_NONBLOCK != 0, want, "non-blocking option");
230+
pub fn assert_nonblocking(socket: &Socket, want: bool) {
231+
#[cfg(all(feature = "all", unix))]
232+
assert_eq!(socket.nonblocking().unwrap(), want, "non-blocking option");
233+
#[cfg(not(all(feature = "all", unix)))]
234+
{
235+
let flags = unsafe { libc::fcntl(socket.as_raw_fd(), libc::F_GETFL) };
236+
assert_eq!(flags & libc::O_NONBLOCK != 0, want, "non-blocking option");
237+
}
236238
}
237239

238240
#[cfg(windows)]
239241
#[track_caller]
240-
pub fn assert_nonblocking<S>(_: &S, _: bool) {
242+
pub fn assert_nonblocking(_: &Socket, _: bool) {
241243
// No way to get this information...
242244
}
243245

0 commit comments

Comments
 (0)