Merge pull request #4103 from coolreader18/no-nullablesocket

Remove nullable_socket impl now that socket2::Socket has a niche
This commit is contained in:
Jeong YunWon authored and GitHub committed 2022-08-19 13:06:57 +09:00
commit 5c58b320c9
8 files changed
+76 -175

No files matched your search

Generated
+18 -7
View File
@@ -1073,7 +1073,7 @@ version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d1bc1084549d60725ccc53a2bfa07f67fe4689fda07b05a36531f2988104a"
dependencies = [
"nix",
"nix 0.23.1",
"winapi",
]
@@ -1177,6 +1177,18 @@ dependencies = [
"memoffset",
]
[[package]]
name = "nix"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc"
dependencies = [
"bitflags",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
@@ -1891,7 +1903,7 @@ dependencies = [
"memchr",
"memmap2",
"mt19937",
"nix",
"nix 0.24.2",
"num-bigint",
"num-complex",
"num-integer",
@@ -1962,7 +1974,7 @@ dependencies = [
"log",
"memchr",
"memoffset",
"nix",
"nix 0.24.2",
"num-bigint",
"num-complex",
"num-integer",
@@ -2036,9 +2048,9 @@ checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
[[package]]
name = "rustyline"
version = "9.1.2"
version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db7826789c0e25614b03e5a54a0717a86f9ff6e6e5247f92b369472869320039"
checksum = "1d1cd5ae51d3f7bf65d7969d579d502168ef578f289452bd8ccc91de28fda20e"
dependencies = [
"bitflags",
"cfg-if",
@@ -2048,10 +2060,9 @@ dependencies = [
"libc",
"log",
"memchr",
"nix",
"nix 0.24.2",
"radix_trie",
"scopeguard",
"smallvec",
"unicode-segmentation",
"unicode-width",
"utf8parse",
+1 -1
View File
@@ -49,7 +49,7 @@ flame = { version = "0.2.2", optional = true }
flamescope = { version = "0.1.2", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
rustyline = "9.1.2"
rustyline = "10.0.0"
[dev-dependencies]
cpython = "0.7.0"
-4
View File
@@ -112,10 +112,6 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
ReadlineResult::Eof => {
break;
}
ReadlineResult::EncodingError => {
eprintln!("Invalid UTF-8 entered");
Ok(())
}
ReadlineResult::Other(err) => {
eprintln!("Readline error: {:?}", err);
break;
+1 -1
View File
@@ -56,7 +56,7 @@ base64 = "0.13.0"
csv-core = "0.1.10"
hex = "0.4.3"
puruspe = "0.1.5"
nix = "0.23.1"
nix = "0.24"
xml-rs = "0.8.4"
libc = "0.2.126"
cfg-if = "1.0.0"
+41 -140
View File
@@ -738,72 +738,6 @@ mod _socket {
.map(|sock| sock as RawSocket)
}
#[cfg(unix)]
mod nullable_socket {
use super::*;
use std::os::unix::io::AsRawFd;
#[derive(Debug)]
#[repr(transparent)]
pub struct NullableSocket(Option<socket2::Socket>);
impl From<socket2::Socket> for NullableSocket {
fn from(sock: socket2::Socket) -> Self {
NullableSocket(Some(sock))
}
}
impl NullableSocket {
pub fn invalid() -> Self {
Self(None)
}
pub fn get(&self) -> Option<&socket2::Socket> {
self.0.as_ref()
}
pub fn fd(&self) -> RawSocket {
self.get().map_or(INVALID_SOCKET, |sock| sock.as_raw_fd())
}
pub fn insert(&mut self, sock: socket2::Socket) -> &mut socket2::Socket {
self.0.insert(sock)
}
}
}
#[cfg(windows)]
mod nullable_socket {
use super::*;
use std::os::windows::io::{AsRawSocket, FromRawSocket};
// TODO: may change if windows changes its TcpStream repr
#[derive(Debug)]
#[repr(transparent)]
pub struct NullableSocket(socket2::Socket);
impl From<socket2::Socket> for NullableSocket {
fn from(sock: socket2::Socket) -> Self {
NullableSocket(sock)
}
}
impl NullableSocket {
pub fn invalid() -> Self {
// TODO: may become UB in the future; maybe see rust-lang/rust#74699
Self(unsafe { socket2::Socket::from_raw_socket(INVALID_SOCKET) })
}
pub fn get(&self) -> Option<&socket2::Socket> {
(self.0.as_raw_socket() != INVALID_SOCKET).then(|| &self.0)
}
pub fn fd(&self) -> RawSocket {
self.0.as_raw_socket()
}
pub fn insert(&mut self, sock: socket2::Socket) -> &mut socket2::Socket {
self.0 = sock;
&mut self.0
}
}
}
use nullable_socket::NullableSocket;
impl Default for NullableSocket {
fn default() -> Self {
Self::invalid()
}
}
#[pyattr(name = "socket")]
#[pyattr(name = "SocketType")]
#[pyclass(name = "socket")]
@@ -813,9 +747,11 @@ mod _socket {
family: AtomicCell<i32>,
proto: AtomicCell<i32>,
pub(crate) timeout: AtomicCell<f64>,
sock: PyRwLock<NullableSocket>,
sock: PyRwLock<Option<Socket>>,
}
const _: () = assert!(std::mem::size_of::<Option<Socket>>() == std::mem::size_of::<Socket>());
impl Default for PySocket {
fn default() -> Self {
PySocket {
@@ -823,7 +759,7 @@ mod _socket {
family: AtomicCell::default(),
proto: AtomicCell::default(),
timeout: AtomicCell::new(-1.0),
sock: PyRwLock::new(NullableSocket::invalid()),
sock: PyRwLock::new(None),
}
}
}
@@ -850,7 +786,7 @@ mod _socket {
impl PySocket {
pub fn sock_opt(&self) -> Option<PyMappedRwLockReadGuard<'_, Socket>> {
PyRwLockReadGuard::try_map(self.sock.read(), |sock| sock.get()).ok()
PyRwLockReadGuard::try_map(self.sock.read(), |sock| sock.as_ref()).ok()
}
pub fn sock(&self) -> io::Result<PyMappedRwLockReadGuard<'_, Socket>> {
@@ -1406,13 +1342,16 @@ mod _socket {
#[pymethod]
#[inline]
fn detach(&self) -> RawSocket {
let sock = std::mem::replace(&mut *self.sock.write(), NullableSocket::invalid());
std::mem::ManuallyDrop::new(sock).fd()
let sock = self.sock.write().take();
sock.map_or(INVALID_SOCKET, into_sock_fileno)
}
#[pymethod]
fn fileno(&self) -> RawSocket {
self.sock.read().fd()
self.sock
.read()
.as_ref()
.map_or(INVALID_SOCKET, sock_fileno)
}
#[pymethod]
@@ -1465,15 +1404,16 @@ mod _socket {
name: i32,
buflen: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult {
let fd = self.sock.read().fd() as _;
) -> Result<PyObjectRef, IoOrPyException> {
let sock = self.sock()?;
let fd = sock_fileno(&sock);
let buflen = buflen.unwrap_or(0);
if buflen == 0 {
let mut flag: libc::c_int = 0;
let mut flagsize = std::mem::size_of::<libc::c_int>() as _;
let ret = unsafe {
c::getsockopt(
fd,
fd as _,
level,
name,
&mut flag as *mut libc::c_int as *mut _,
@@ -1481,22 +1421,30 @@ mod _socket {
)
};
if ret < 0 {
return Err(crate::vm::stdlib::os::errno_err(vm));
return Err(crate::common::os::errno().into());
}
Ok(vm.ctx.new_int(flag).into())
} else {
if buflen <= 0 || buflen > 1024 {
return Err(vm.new_os_error("getsockopt buflen out of range".to_owned()));
return Err(vm
.new_os_error("getsockopt buflen out of range".to_owned())
.into());
}
let mut buf = vec![0u8; buflen as usize];
let mut buflen = buflen as _;
let ret = unsafe {
c::getsockopt(fd, level, name, buf.as_mut_ptr() as *mut _, &mut buflen)
c::getsockopt(
fd as _,
level,
name,
buf.as_mut_ptr() as *mut _,
&mut buflen,
)
};
buf.truncate(buflen as usize);
if ret < 0 {
return Err(crate::vm::stdlib::os::errno_err(vm));
return Err(crate::common::os::errno().into());
}
buf.truncate(buflen as usize);
Ok(vm.ctx.new_bytes(buf).into())
}
}
@@ -1509,15 +1457,16 @@ mod _socket {
value: Option<Either<ArgBytesLike, i32>>,
optlen: OptionalArg<u32>,
vm: &VirtualMachine,
) -> PyResult<()> {
let fd = self.sock.read().fd() as _;
) -> Result<(), IoOrPyException> {
let sock = self.sock()?;
let fd = sock_fileno(&sock);
let ret = match (value, optlen) {
(Some(Either::A(b)), OptionalArg::Missing) => b.with_ref(|b| unsafe {
c::setsockopt(fd, level, name, b.as_ptr() as *const _, b.len() as _)
c::setsockopt(fd as _, level, name, b.as_ptr() as *const _, b.len() as _)
}),
(Some(Either::B(ref val)), OptionalArg::Missing) => unsafe {
c::setsockopt(
fd,
fd as _,
level,
name,
val as *const i32 as *const _,
@@ -1525,16 +1474,16 @@ mod _socket {
)
},
(None, OptionalArg::Present(optlen)) => unsafe {
c::setsockopt(fd, level, name, std::ptr::null(), optlen as _)
c::setsockopt(fd as _, level, name, std::ptr::null(), optlen as _)
},
_ => {
return Err(
vm.new_type_error("expected the value arg xor the optlen arg".to_owned())
);
return Err(vm
.new_type_error("expected the value arg xor the optlen arg".to_owned())
.into());
}
};
if ret < 0 {
Err(crate::vm::stdlib::os::errno_err(vm))
Err(crate::common::os::errno().into())
} else {
Ok(())
}
@@ -1573,7 +1522,7 @@ mod _socket {
format!(
"<socket object, fd={}, family={}, type={}, proto={}>",
// cast because INVALID_SOCKET is unsigned, so would show usize::MAX instead of -1
self.sock.read().fd() as i64,
self.fileno() as i64,
self.family.load(),
self.kind.load(),
self.proto.load(),
@@ -2135,7 +2084,7 @@ mod _socket {
fn if_nameindex(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
#[cfg(not(windows))]
{
let list = if_nameindex()
let list = nix::net::if_::if_nameindex()
.map_err(|err| err.into_pyexception(vm))?
.to_slice()
.iter()
@@ -2146,55 +2095,7 @@ mod _socket {
})
.collect();
return Ok(list);
// all the stuff below should be in nix soon, hopefully
use ffi::CStr;
use std::ptr::NonNull;
#[repr(transparent)]
struct Interface(libc::if_nameindex);
impl Interface {
fn index(&self) -> libc::c_uint {
self.0.if_index
}
fn name(&self) -> &CStr {
unsafe { CStr::from_ptr(self.0.if_name) }
}
}
struct Interfaces {
ptr: NonNull<libc::if_nameindex>,
}
impl Interfaces {
fn to_slice(&self) -> &[Interface] {
let ifs = self.ptr.as_ptr() as *const Interface;
let mut len = 0;
unsafe {
while (*ifs.add(len)).0.if_index != 0 {
len += 1
}
std::slice::from_raw_parts(ifs, len)
}
}
}
impl Drop for Interfaces {
fn drop(&mut self) {
unsafe { libc::if_freenameindex(self.ptr.as_ptr()) };
}
}
fn if_nameindex() -> nix::Result<Interfaces> {
unsafe {
let ifs = libc::if_nameindex();
let ptr = NonNull::new(ifs).ok_or_else(nix::Error::last)?;
Ok(Interfaces { ptr })
}
}
Ok(list)
}
#[cfg(windows)]
{
+2 -2
View File
@@ -50,7 +50,7 @@ indexmap = "1.8.1"
ahash = "0.7.6"
bitflags = "1.3.2"
libc = "0.2.126"
nix = "0.23.1"
nix = "0.24.2"
paste = "1.0.7"
is-macro = "0.2.0"
result-like = "0.4.5"
@@ -101,7 +101,7 @@ strum = "0.24.0"
strum_macros = "0.24.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
rustyline = "9"
rustyline = "10.0.0"
which = "4.2.5"
[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies]
+13 -17
View File
@@ -8,7 +8,6 @@ pub enum ReadlineResult {
Eof,
Interrupt,
Io(std::io::Error),
EncodingError,
Other(OtherError),
}
@@ -51,11 +50,8 @@ mod basic_readline {
match next_line {
Some(Ok(line)) => ReadlineResult::Line(line),
None => ReadlineResult::Eof,
Some(Err(e)) => match e.kind() {
io::ErrorKind::Interrupted => ReadlineResult::Interrupt,
io::ErrorKind::InvalidData => ReadlineResult::EncodingError,
_ => ReadlineResult::Io(e),
},
Some(Err(e)) if e.kind() == io::ErrorKind::Interrupted => ReadlineResult::Interrupt,
Some(Err(e)) => ReadlineResult::Io(e),
}
}
}
@@ -82,7 +78,8 @@ mod rustyline_readline {
.tab_stop(8)
.bracketed_paste(false) // multi-line paste
.build(),
);
)
.expect("failed to initialize line editor");
repl.set_helper(Some(helper));
Readline { repl }
}
@@ -109,16 +106,15 @@ mod rustyline_readline {
pub fn readline(&mut self, prompt: &str) -> ReadlineResult {
use rustyline::error::ReadlineError;
match self.repl.readline(prompt) {
Ok(line) => ReadlineResult::Line(line),
Err(ReadlineError::Interrupted) => ReadlineResult::Interrupt,
Err(ReadlineError::Eof) => ReadlineResult::Eof,
Err(ReadlineError::Io(e)) => ReadlineResult::Io(e),
#[cfg(unix)]
Err(ReadlineError::Utf8Error) => ReadlineResult::EncodingError,
#[cfg(windows)]
Err(ReadlineError::Decode(_)) => ReadlineResult::EncodingError,
Err(e) => ReadlineResult::Other(e.into()),
loop {
break match self.repl.readline(prompt) {
Ok(line) => ReadlineResult::Line(line),
Err(ReadlineError::Interrupted) => ReadlineResult::Interrupt,
Err(ReadlineError::Eof) => ReadlineResult::Eof,
Err(ReadlineError::Io(e)) => ReadlineResult::Io(e),
Err(ReadlineError::WindowResized) => continue,
Err(e) => ReadlineResult::Other(e.into()),
};
}
}
}
-3
View File
@@ -408,9 +408,6 @@ mod builtins {
Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.to_owned()))
}
ReadlineResult::Io(e) => Err(vm.new_os_error(e.to_string())),
ReadlineResult::EncodingError => {
Err(vm.new_unicode_decode_error("Error decoding readline input".to_owned()))
}
ReadlineResult::Other(e) => Err(vm.new_runtime_error(e.to_string())),
}
} else {