mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #1205 from Lynskylate/impl-socket-module
Extend Socket module
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -417,6 +417,15 @@ dependencies = [
|
||||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
@@ -1041,6 +1050,7 @@ dependencies = [
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flame 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flamer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gethostname 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hexf-parse 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1924,6 +1934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum gethostname 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4ab273ca2a31eb6ca40b15837ccf1aa59a43c5db69ac10c542be342fae2e01d"
|
||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
"checksum hexf-parse 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79296f72d53a89096cbc9a88c9547ee8dfe793388674620e2207593d370550ac"
|
||||
|
||||
@@ -115,3 +115,17 @@ with assertRaises(OSError):
|
||||
|
||||
with assertRaises(OSError):
|
||||
socket.socket(socket.AF_INET, 1000)
|
||||
|
||||
with assertRaises(OSError):
|
||||
socket.inet_aton("test")
|
||||
|
||||
assert socket.inet_aton("127.0.0.1")==b"\x7f\x00\x00\x01"
|
||||
assert socket.inet_aton("255.255.255.255")==b"\xff\xff\xff\xff"
|
||||
|
||||
|
||||
assert socket.inet_ntoa(b"\x7f\x00\x00\x01")=="127.0.0.1"
|
||||
assert socket.inet_ntoa(b"\xff\xff\xff\xff")=="255.255.255.255"
|
||||
|
||||
with assertRaises(OSError):
|
||||
socket.inet_ntoa(b"\xff\xff\xff\xff\xff")
|
||||
|
||||
|
||||
@@ -70,3 +70,6 @@ flamer = { version = "0.3", optional = true }
|
||||
|
||||
[target.'cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))'.dependencies]
|
||||
pwd = "1"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
gethostname = "0.2.0"
|
||||
|
||||
@@ -17,6 +17,7 @@ mod platform;
|
||||
mod pystruct;
|
||||
mod random;
|
||||
mod re;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod socket;
|
||||
mod string;
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
|
||||
@@ -183,7 +183,7 @@ fn convert_io_error(vm: &VirtualMachine, err: io::Error) -> PyObjectRef {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn convert_nix_error(vm: &VirtualMachine, err: nix::Error) -> PyObjectRef {
|
||||
pub fn convert_nix_error(vm: &VirtualMachine, err: nix::Error) -> PyObjectRef {
|
||||
let nix_error = match err {
|
||||
nix::Error::InvalidPath => {
|
||||
let exc_type = vm.ctx.exceptions.file_not_found_error.clone();
|
||||
|
||||
@@ -2,7 +2,14 @@ use std::cell::RefCell;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket};
|
||||
use std::net::{Ipv4Addr, SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket};
|
||||
|
||||
#[cfg(unix)]
|
||||
use nix::unistd::sethostname;
|
||||
|
||||
use gethostname::gethostname;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
|
||||
use crate::obj::objbytes::PyBytesRef;
|
||||
use crate::obj::objint::PyIntRef;
|
||||
@@ -12,6 +19,8 @@ use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
#[cfg(unix)]
|
||||
use crate::stdlib::os::convert_nix_error;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -372,6 +381,34 @@ fn get_addr_tuple(vm: &VirtualMachine, addr: SocketAddr) -> PyResult {
|
||||
Ok(vm.ctx.new_tuple(vec![ip, port]))
|
||||
}
|
||||
|
||||
fn socket_gethostname(vm: &VirtualMachine) -> PyResult {
|
||||
gethostname()
|
||||
.into_string()
|
||||
.map(|hostname| vm.new_str(hostname))
|
||||
.map_err(|err| vm.new_os_error(err.into_string().unwrap()))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn socket_sethostname(hostname: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
sethostname(hostname.value.as_str()).map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
fn socket_inet_aton(ip_string: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
ip_string
|
||||
.as_str()
|
||||
.parse::<Ipv4Addr>()
|
||||
.map(|ip_addr| vm.ctx.new_bytes(ip_addr.octets().to_vec()))
|
||||
.map_err(|_| vm.new_os_error("illegal IP address string passed to inet_aton".to_string()))
|
||||
}
|
||||
|
||||
fn socket_inet_ntoa(packed_ip: PyBytesRef, vm: &VirtualMachine) -> PyResult {
|
||||
if packed_ip.len() != 4 {
|
||||
return Err(vm.new_os_error("packed IP wrong length for inet_ntoa".to_string()));
|
||||
}
|
||||
let ip_num = BigEndian::read_u32(packed_ip.get_value());
|
||||
Ok(vm.new_str(Ipv4Addr::from(ip_num).to_string()))
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
@@ -390,10 +427,31 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"fileno" => ctx.new_rustfunc(SocketRef::fileno),
|
||||
});
|
||||
|
||||
py_module!(vm, "socket", {
|
||||
let module = py_module!(vm, "socket", {
|
||||
"AF_INET" => ctx.new_int(AddressFamily::Inet as i32),
|
||||
"SOCK_STREAM" => ctx.new_int(SocketKind::Stream as i32),
|
||||
"SOCK_DGRAM" => ctx.new_int(SocketKind::Dgram as i32),
|
||||
"socket" => socket,
|
||||
})
|
||||
"inet_aton" => ctx.new_rustfunc(socket_inet_aton),
|
||||
"inet_ntoa" => ctx.new_rustfunc(socket_inet_ntoa),
|
||||
"gethostname" => ctx.new_rustfunc(socket_gethostname),
|
||||
});
|
||||
|
||||
extend_module_platform_specific(vm, module)
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn extend_module_platform_specific(_vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef {
|
||||
module
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
extend_module!(vm, module, {
|
||||
"sethostname" => ctx.new_rustfunc(socket_sethostname),
|
||||
});
|
||||
|
||||
module
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user