Skip to content

Commit b7af685

Browse files
committed
Refactor: Extract new method FileDesc::get_access_mode
ALso fixed a bug in the original implementation Signed-off-by: Jiahao XU <[email protected]>
1 parent d60438f commit b7af685

File tree

3 files changed

+47
-42
lines changed

3 files changed

+47
-42
lines changed

library/std/src/sys/anonymous_pipe.rs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -161,42 +161,22 @@ mod unix {
161161
}
162162
}
163163

164-
enum AccessMode {
165-
Readable,
166-
Writable,
167-
}
168-
169-
fn check_access_mode(pipe: AnonPipe, expected_access_mode: AccessMode) -> io::Result<AnonPipe> {
170-
let ret = unsafe { libc::fcntl(pipe.as_raw_fd(), libc::F_GETFL) };
171-
let access_mode = ret & libc::O_ACCMODE;
172-
let expected_access_mode_str = match expected_access_mode {
173-
AccessMode::Readable => "readable",
174-
AccessMode::Writable => "writable",
175-
};
176-
let expected_access_mode = match expected_access_mode {
177-
AccessMode::Readable => libc::O_RDONLY,
178-
AccessMode::Writable => libc::O_WRONLY,
179-
};
180-
181-
if ret == -1 {
182-
Err(io::Error::last_os_error())
183-
} else if access_mode == libc::O_RDWR && access_mode == expected_access_mode {
184-
Err(io::Error::new(
185-
io::ErrorKind::InvalidInput,
186-
format!("Pipe {} is not {}", pipe.as_raw_fd(), expected_access_mode_str),
187-
))
188-
} else {
189-
Ok(pipe)
190-
}
191-
}
192-
193164
#[unstable(feature = "anonymous_pipe", issue = "127154")]
194165
impl TryFrom<OwnedFd> for PipeReader {
195166
type Error = io::Error;
196167

197168
fn try_from(owned_fd: OwnedFd) -> Result<Self, Self::Error> {
198169
convert_to_pipe(owned_fd)
199-
.and_then(|pipe| check_access_mode(pipe, AccessMode::Readable))
170+
.and_then(|pipe| {
171+
if pipe.as_file_desc().get_access_mode()?.readable {
172+
Ok(pipe)
173+
} else {
174+
Err(io::Error::new(
175+
io::ErrorKind::InvalidInput,
176+
format!("Pipe {} is not readable", pipe.as_raw_fd()),
177+
))
178+
}
179+
})
200180
.map(Self)
201181
}
202182
}
@@ -207,7 +187,16 @@ mod unix {
207187

208188
fn try_from(owned_fd: OwnedFd) -> Result<Self, Self::Error> {
209189
convert_to_pipe(owned_fd)
210-
.and_then(|pipe| check_access_mode(pipe, AccessMode::Writable))
190+
.and_then(|pipe| {
191+
if pipe.as_file_desc().get_access_mode()?.writable {
192+
Ok(pipe)
193+
} else {
194+
Err(io::Error::new(
195+
io::ErrorKind::InvalidInput,
196+
format!("Pipe {} is not writable", pipe.as_raw_fd()),
197+
))
198+
}
199+
})
211200
.map(Self)
212201
}
213202
}

library/std/src/sys/pal/unix/fd.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ use libc::off64_t;
2626
)))]
2727
use libc::off_t as off64_t;
2828

29+
pub struct AccessMode {
30+
pub readable: bool,
31+
pub writable: bool,
32+
}
33+
2934
#[derive(Debug)]
3035
pub struct FileDesc(OwnedFd);
3136

@@ -518,20 +523,27 @@ impl FileDesc {
518523
}
519524
}
520525

526+
fn get_flags(&self) -> io::Result<libc::c_int> {
527+
unsafe { cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFL)) }
528+
}
529+
530+
pub fn get_access_mode(&self) -> io::Result<AccessMode> {
531+
let access_mode = self.get_flags()? & libc::O_ACCMODE;
532+
Ok(AccessMode {
533+
readable: access_mode == libc::O_RDWR || access_mode == libc::O_RDONLY,
534+
writable: access_mode == libc::O_RDWR || access_mode == libc::O_WRONLY,
535+
})
536+
}
537+
521538
#[cfg(not(target_os = "linux"))]
522539
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
523-
unsafe {
524-
let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFL))?;
525-
let new = if nonblocking {
526-
previous | libc::O_NONBLOCK
527-
} else {
528-
previous & !libc::O_NONBLOCK
529-
};
530-
if new != previous {
531-
cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFL, new))?;
532-
}
533-
Ok(())
540+
let previous = self.get_flags()?;
541+
let new =
542+
if nonblocking { previous | libc::O_NONBLOCK } else { previous & !libc::O_NONBLOCK };
543+
if new != previous {
544+
unsafe { cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFL, new)) }?;
534545
}
546+
Ok(())
535547
}
536548

537549
#[inline]

library/std/src/sys/pal/unix/pipe.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ impl AnonPipe {
8484
pub fn is_write_vectored(&self) -> bool {
8585
self.0.is_write_vectored()
8686
}
87+
88+
pub fn as_file_desc(&self) -> &FileDesc {
89+
&self.0
90+
}
8791
}
8892

8993
impl IntoInner<FileDesc> for AnonPipe {

0 commit comments

Comments
 (0)