mirror of
https://github.com/wez/wezterm.git
synced 2024-10-26 15:52:29 +03:00
add socketpair, with wip on windows
This commit is contained in:
parent
f3d201a26b
commit
9ff22f9c09
@ -20,5 +20,6 @@ winapi = { version = "0.3", features = [
|
||||
"handleapi",
|
||||
"fileapi",
|
||||
"namedpipeapi",
|
||||
"processthreadsapi"
|
||||
"processthreadsapi",
|
||||
"winsock2"
|
||||
]}
|
||||
|
@ -241,3 +241,10 @@ use std::time::Duration;
|
||||
pub fn poll(pfd: &mut [pollfd], duration: Option<Duration>) -> Fallible<usize> {
|
||||
poll_impl(pfd, duration)
|
||||
}
|
||||
|
||||
/// Create a pair of connected sockets
|
||||
///
|
||||
/// This implementation creates a pair of SOCK_STREAM sockets.
|
||||
pub fn socketpair() -> Fallible<(FileDescriptor, FileDescriptor)> {
|
||||
socketpair_impl()
|
||||
}
|
||||
|
@ -209,6 +209,57 @@ impl Pipe {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[doc(hidden)]
|
||||
pub fn socketpair_impl() -> Fallible<(FileDescriptor, FileDescriptor)> {
|
||||
let mut fds = [-1i32; 2];
|
||||
let res = unsafe {
|
||||
libc::socketpair(
|
||||
libc::PF_LOCAL,
|
||||
libc::SOCK_STREAM | libc::SOCK_CLOEXEC,
|
||||
0,
|
||||
fds.as_mut_ptr(),
|
||||
)
|
||||
};
|
||||
if res == -1 {
|
||||
bail!(
|
||||
"failed to create a socketpair: {:?}",
|
||||
std::io::Error::last_os_error()
|
||||
)
|
||||
} else {
|
||||
let mut read = FileDescriptor {
|
||||
handle: OwnedHandle { handle: fds[0] },
|
||||
};
|
||||
let mut write = FileDescriptor {
|
||||
handle: OwnedHandle { handle: fds[1] },
|
||||
};
|
||||
Ok((read, write))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[doc(hidden)]
|
||||
pub fn socketpair_impl() -> Fallible<(FileDescriptor, FileDescriptor)> {
|
||||
let mut fds = [-1i32; 2];
|
||||
let res = unsafe { libc::socketpair(libc::PF_LOCAL, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
|
||||
if res == -1 {
|
||||
bail!(
|
||||
"failed to create a socketpair: {:?}",
|
||||
std::io::Error::last_os_error()
|
||||
)
|
||||
} else {
|
||||
let mut read = FileDescriptor {
|
||||
handle: OwnedHandle { handle: fds[0] },
|
||||
};
|
||||
let mut write = FileDescriptor {
|
||||
handle: OwnedHandle { handle: fds[1] },
|
||||
};
|
||||
read.handle.cloexec()?;
|
||||
write.handle.cloexec()?;
|
||||
Ok((read, write))
|
||||
}
|
||||
}
|
||||
|
||||
pub use libc::{pollfd, POLLERR, POLLHUP, POLLIN, POLLOUT};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -225,7 +276,7 @@ pub fn poll_impl(pfd: &mut [pollfd], duration: Option<Duration>) -> Fallible<usi
|
||||
)
|
||||
};
|
||||
if poll_result < 0 {
|
||||
Err(std::io::Error::last_os_error())
|
||||
Err(std::io::Error::last_os_error().into())
|
||||
} else {
|
||||
Ok(poll_result as usize)
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ use winapi::um::handleapi::*;
|
||||
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
|
||||
use winapi::um::namedpipeapi::CreatePipe;
|
||||
use winapi::um::processthreadsapi::*;
|
||||
use winapi::um::winbase::{FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE};
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use winapi::um::winsock2::{closesocket, WSAPoll};
|
||||
pub use winapi::um::winsock2::{POLLERR, POLLHUP, POLLIN, POLLOUT, WSAPOLLFD as pollfd};
|
||||
|
||||
/// `RawFileDescriptor` is a platform independent type alias for the
|
||||
@ -39,10 +41,44 @@ impl<T: FromRawHandle> FromRawFileDescriptor for T {
|
||||
|
||||
unsafe impl Send for OwnedHandle {}
|
||||
|
||||
enum HandleType {
|
||||
Char,
|
||||
Disk,
|
||||
Pipe,
|
||||
Socket,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
fn handle_type(handle: HANDLE) -> HandleType {
|
||||
match GetFileType(handle) {
|
||||
FILE_TYPE_CHAR => HandleType::Char,
|
||||
FILE_TYPE_DISK => HandleType::Disk,
|
||||
FILE_TYPE_PIPE => {
|
||||
// Could be a pipe or a socket. Test if for pipeness
|
||||
let mut flags = 0;
|
||||
let mut out_buf = 0;
|
||||
let mut in_buf = 0;
|
||||
let mut inst = 0;
|
||||
if GetNamedPipeInfo(handle, &mut flags, &mut out_buf, &mut in_buf, &mut inst) {
|
||||
HandleType::Pipe
|
||||
} else {
|
||||
HandleType::Socket
|
||||
}
|
||||
}
|
||||
_ => HandleType::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OwnedHandle {
|
||||
fn drop(&mut self) {
|
||||
if self.handle != INVALID_HANDLE_VALUE as _ && !self.handle.is_null() {
|
||||
unsafe { CloseHandle(self.handle as _) };
|
||||
unsafe {
|
||||
if handle_type(self.handle as _) == HandleType::Socket {
|
||||
closesocket(self.handle as _);
|
||||
} else {
|
||||
CloseHandle(self.handle as _);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,6 +230,24 @@ impl Pipe {
|
||||
}
|
||||
}
|
||||
|
||||
fn init_winsock() {
|
||||
static START: Once = Once::new();
|
||||
START.call_once(|| unsafe {
|
||||
let mut data: WSADATA = mem::zeroed();
|
||||
let ret = WSAStartup(
|
||||
0x202, // version 2.2
|
||||
&mut data,
|
||||
);
|
||||
assert_eq!(ret, 0, "failed to initialize winsock");
|
||||
});
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn socketpair_impl() -> Fallible<(FileDescriptor, FileDescriptor)> {
|
||||
init_winsock();
|
||||
bail!("not implemented yet");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn poll_impl(pfd: &mut [pollfd], duration: Option<Duration>) -> Fallible<usize> {
|
||||
let poll_result = unsafe {
|
||||
@ -206,7 +260,7 @@ pub fn poll_impl(pfd: &mut [pollfd], duration: Option<Duration>) -> Fallible<usi
|
||||
)
|
||||
};
|
||||
if poll_result < 0 {
|
||||
Err(std::io::Error::last_os_error())
|
||||
Err(std::io::Error::last_os_error().into())
|
||||
} else {
|
||||
Ok(poll_result as usize)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user