mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 09:37:29 +08:00
fds: add make_fd_{,non}blocking implementations in Rust
This commit is contained in:
parent
0b291355b2
commit
35aa7636eb
|
@ -3,10 +3,10 @@ use crate::ffi;
|
||||||
use crate::wchar::{wstr, L};
|
use crate::wchar::{wstr, L};
|
||||||
use crate::wutil::perror;
|
use crate::wutil::perror;
|
||||||
use libc::EINTR;
|
use libc::EINTR;
|
||||||
use libc::O_CLOEXEC;
|
use libc::{fcntl, F_GETFL, F_SETFL, O_CLOEXEC, O_NONBLOCK};
|
||||||
use nix::unistd;
|
use nix::unistd;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::io::{Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||||
|
|
||||||
pub const PIPE_ERROR: &wstr = L!("An error occurred while setting up pipe");
|
pub const PIPE_ERROR: &wstr = L!("An error occurred while setting up pipe");
|
||||||
|
@ -187,3 +187,29 @@ pub fn exec_close(fd: RawFd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark an fd as nonblocking
|
||||||
|
pub fn make_fd_nonblocking(fd: RawFd) -> Result<(), io::Error> {
|
||||||
|
let flags = unsafe { fcntl(fd, F_GETFL, 0) };
|
||||||
|
let nonblocking = (flags & O_NONBLOCK) == O_NONBLOCK;
|
||||||
|
if !nonblocking {
|
||||||
|
match unsafe { fcntl(fd, F_SETFL, flags | O_NONBLOCK) } {
|
||||||
|
0 => return Ok(()),
|
||||||
|
_ => return Err(io::Error::last_os_error()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark an fd as blocking
|
||||||
|
pub fn make_fd_blocking(fd: RawFd) -> Result<(), io::Error> {
|
||||||
|
let flags = unsafe { fcntl(fd, F_GETFL, 0) };
|
||||||
|
let nonblocking = (flags & O_NONBLOCK) == O_NONBLOCK;
|
||||||
|
if nonblocking {
|
||||||
|
match unsafe { fcntl(fd, F_SETFL, flags & !O_NONBLOCK) } {
|
||||||
|
0 => return Ok(()),
|
||||||
|
_ => return Err(io::Error::last_os_error()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ include_cpp! {
|
||||||
|
|
||||||
generate_pod!("wcharz_t")
|
generate_pod!("wcharz_t")
|
||||||
generate!("wcstring_list_ffi_t")
|
generate!("wcstring_list_ffi_t")
|
||||||
generate!("make_fd_nonblocking")
|
|
||||||
generate!("wperror")
|
generate!("wperror")
|
||||||
|
|
||||||
generate_pod!("pipes_ffi_t")
|
generate_pod!("pipes_ffi_t")
|
||||||
|
|
|
@ -3,8 +3,9 @@ use crate::common::{str2wcstring, wcs2string, EMPTY_STRING};
|
||||||
use crate::fd_monitor::{
|
use crate::fd_monitor::{
|
||||||
FdMonitor, FdMonitorItem, FdMonitorItemId, ItemWakeReason, NativeCallback,
|
FdMonitor, FdMonitorItem, FdMonitorItemId, ItemWakeReason, NativeCallback,
|
||||||
};
|
};
|
||||||
use crate::fds::{make_autoclose_pipes, wopen_cloexec, AutoCloseFd, PIPE_ERROR};
|
use crate::fds::{
|
||||||
use crate::ffi;
|
make_autoclose_pipes, make_fd_nonblocking, wopen_cloexec, AutoCloseFd, PIPE_ERROR,
|
||||||
|
};
|
||||||
use crate::flog::{should_flog, FLOG, FLOGF};
|
use crate::flog::{should_flog, FLOG, FLOGF};
|
||||||
use crate::global_safety::RelaxedAtomicBool;
|
use crate::global_safety::RelaxedAtomicBool;
|
||||||
use crate::job_group::JobGroup;
|
use crate::job_group::JobGroup;
|
||||||
|
@ -13,7 +14,7 @@ use crate::redirection::{RedirectionMode, RedirectionSpecList};
|
||||||
use crate::signal::SigChecker;
|
use crate::signal::SigChecker;
|
||||||
use crate::topic_monitor::topic_t;
|
use crate::topic_monitor::topic_t;
|
||||||
use crate::wchar::{wstr, WString, L};
|
use crate::wchar::{wstr, WString, L};
|
||||||
use crate::wutil::{perror, wdirname, wstat, wwrite_to_fd};
|
use crate::wutil::{perror, perror_io, wdirname, wstat, wwrite_to_fd};
|
||||||
use errno::Errno;
|
use errno::Errno;
|
||||||
use libc::{EAGAIN, EEXIST, EINTR, ENOENT, ENOTDIR, EPIPE, EWOULDBLOCK, O_EXCL, STDERR_FILENO};
|
use libc::{EAGAIN, EEXIST, EINTR, ENOENT, ENOTDIR, EPIPE, EWOULDBLOCK, O_EXCL, STDERR_FILENO};
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
@ -343,10 +344,13 @@ impl IoBufferfill {
|
||||||
// Our buffer will read from the read end of the pipe. This end must be non-blocking. This is
|
// Our buffer will read from the read end of the pipe. This end must be non-blocking. This is
|
||||||
// because our fillthread needs to poll to decide if it should shut down, and also accept input
|
// because our fillthread needs to poll to decide if it should shut down, and also accept input
|
||||||
// from direct buffer transfers.
|
// from direct buffer transfers.
|
||||||
if ffi::make_fd_nonblocking(autocxx::c_int(pipes.read.fd())).0 != 0 {
|
match make_fd_nonblocking(&pipes.read.fd()) {
|
||||||
FLOG!(warning, PIPE_ERROR);
|
Ok(_) => (),
|
||||||
perror("fcntl");
|
Err(e) => {
|
||||||
return None;
|
FLOG!(warning, PIPE_ERROR);
|
||||||
|
perror_io("fcntl", &e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Our fillthread gets the read end of the pipe; out_pipe gets the write end.
|
// Our fillthread gets the read end of the pipe; out_pipe gets the write end.
|
||||||
let mut buffer = Arc::new(RwLock::new(IoBuffer::new(buffer_limit)));
|
let mut buffer = Arc::new(RwLock::new(IoBuffer::new(buffer_limit)));
|
||||||
|
|
|
@ -21,8 +21,7 @@ set. This is the real power of topics: you can wait for a sigchld signal OR a th
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::fd_readable_set::fd_readable_set_t;
|
use crate::fd_readable_set::fd_readable_set_t;
|
||||||
use crate::fds::{self, AutoClosePipes};
|
use crate::fds::{self, make_fd_nonblocking, AutoClosePipes};
|
||||||
use crate::ffi::{self as ffi, c_int};
|
|
||||||
use crate::flog::{FloggableDebug, FLOG};
|
use crate::flog::{FloggableDebug, FLOG};
|
||||||
use crate::wchar::WString;
|
use crate::wchar::WString;
|
||||||
use crate::wutil::perror;
|
use crate::wutil::perror;
|
||||||
|
@ -213,7 +212,7 @@ impl binary_semaphore_t {
|
||||||
// receive SIGCHLD and so deadlock. So if tsan is enabled, we mark our fd as non-blocking
|
// receive SIGCHLD and so deadlock. So if tsan is enabled, we mark our fd as non-blocking
|
||||||
// (so reads will never block) and use select() to poll it.
|
// (so reads will never block) and use select() to poll it.
|
||||||
if cfg!(feature = "FISH_TSAN_WORKAROUNDS") {
|
if cfg!(feature = "FISH_TSAN_WORKAROUNDS") {
|
||||||
ffi::make_fd_nonblocking(c_int(pipes_.read.fd()));
|
let _ = make_fd_nonblocking(&pipes_.read.fd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binary_semaphore_t {
|
binary_semaphore_t {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user