mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #4103 from coolreader18/no-nullablesocket
Remove nullable_socket impl now that socket2::Socket has a niche
This commit is contained in:
8 files changed
+76
-175
No files matched your search
Generated
+18
-7
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user