mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #3716 from youknowone/to-pyexc
PyResult<T, E> instead of PyResult<T>
This commit is contained in:
@@ -318,15 +318,10 @@ mod decl {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn modify(
|
||||
&self,
|
||||
Fildes(fd): Fildes,
|
||||
eventmask: u16,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
fn modify(&self, Fildes(fd): Fildes, eventmask: u16) -> io::Result<()> {
|
||||
let mut fds = self.fds.lock();
|
||||
let pfd = get_fd_mut(&mut fds, fd)
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT).to_pyexception(vm))?;
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT))?;
|
||||
pfd.events = eventmask as i16;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -260,16 +260,16 @@ mod _socket {
|
||||
|
||||
impl Read for &PySocket {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
(&mut &*self.sock_io()?).read(buf)
|
||||
(&mut &*self.sock()?).read(buf)
|
||||
}
|
||||
}
|
||||
impl Write for &PySocket {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
(&mut &*self.sock_io()?).write(buf)
|
||||
(&mut &*self.sock()?).write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
(&mut &*self.sock_io()?).flush()
|
||||
(&mut &*self.sock()?).flush()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,23 +278,18 @@ mod _socket {
|
||||
PyRwLockReadGuard::try_map(self.sock.read(), |sock| sock.get()).ok()
|
||||
}
|
||||
|
||||
fn sock_io(&self) -> io::Result<PyMappedRwLockReadGuard<'_, Socket>> {
|
||||
pub fn sock(&self) -> io::Result<PyMappedRwLockReadGuard<'_, Socket>> {
|
||||
self.sock_opt()
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(CLOSED_ERR))
|
||||
}
|
||||
|
||||
pub fn sock(&self, vm: &VirtualMachine) -> PyResult<PyMappedRwLockReadGuard<'_, Socket>> {
|
||||
self.sock_io().map_err(|e| e.to_pyexception(vm))
|
||||
}
|
||||
|
||||
fn init_inner(
|
||||
&self,
|
||||
family: i32,
|
||||
socket_kind: i32,
|
||||
proto: i32,
|
||||
sock: Socket,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
) -> io::Result<()> {
|
||||
self.family.store(family);
|
||||
self.kind.store(socket_kind);
|
||||
self.proto.store(proto);
|
||||
@@ -303,21 +298,11 @@ mod _socket {
|
||||
let timeout = DEFAULT_TIMEOUT.load();
|
||||
self.timeout.store(timeout);
|
||||
if timeout >= 0.0 {
|
||||
sock.set_nonblocking(true)
|
||||
.map_err(|e| e.to_pyexception(vm))?;
|
||||
sock.set_nonblocking(true)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sock_op<F, R>(&self, vm: &VirtualMachine, select: SelectKind, f: F) -> PyResult<R>
|
||||
where
|
||||
F: FnMut() -> io::Result<R>,
|
||||
{
|
||||
self.sock_op_err(vm, select, f)
|
||||
.map_err(|e| e.to_pyexception(vm))
|
||||
}
|
||||
|
||||
/// returns Err(blocking)
|
||||
pub fn get_timeout(&self) -> Result<Duration, bool> {
|
||||
let timeout = self.timeout.load();
|
||||
@@ -328,7 +313,7 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
|
||||
fn sock_op_err<F, R>(
|
||||
fn sock_op<F, R>(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
select: SelectKind,
|
||||
@@ -355,7 +340,7 @@ mod _socket {
|
||||
loop {
|
||||
if deadline.is_some() || matches!(select, SelectKind::Connect) {
|
||||
let interval = deadline.as_ref().map(|d| d.time_until()).transpose()?;
|
||||
let res = sock_select(&*self.sock(vm)?, select, interval);
|
||||
let res = sock_select(&*self.sock()?, select, interval);
|
||||
match res {
|
||||
Ok(true) => return Err(IoOrPyException::Timeout),
|
||||
Err(e) if e.kind() == io::ErrorKind::Interrupted => {
|
||||
@@ -387,7 +372,7 @@ mod _socket {
|
||||
addr: PyObjectRef,
|
||||
caller: &str,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<socket2::SockAddr> {
|
||||
) -> PyResult<socket2::SockAddr, IoOrPyException> {
|
||||
let family = self.family.load();
|
||||
match family {
|
||||
#[cfg(unix)]
|
||||
@@ -441,7 +426,7 @@ mod _socket {
|
||||
} else {
|
||||
socket2::SockAddr::unix(ffi::OsStr::from_bytes(path))
|
||||
}
|
||||
.map_err(|_| vm.new_os_error("AF_UNIX path too long".to_owned()))
|
||||
.map_err(|_| vm.new_os_error("AF_UNIX path too long".to_owned()).into())
|
||||
}
|
||||
c::AF_INET => {
|
||||
let tuple: PyTupleRef = addr.downcast().map_err(|obj| {
|
||||
@@ -452,9 +437,11 @@ mod _socket {
|
||||
))
|
||||
})?;
|
||||
if tuple.len() != 2 {
|
||||
return Err(vm.new_type_error(
|
||||
"AF_INET address must be a pair (host, post)".to_owned(),
|
||||
));
|
||||
return Err(vm
|
||||
.new_type_error(
|
||||
"AF_INET address must be a pair (host, post)".to_owned(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let addr = Address::from_tuple(&tuple, vm)?;
|
||||
let mut addr4 = get_addr(vm, addr.host, c::AF_INET)?;
|
||||
@@ -479,7 +466,7 @@ mod _socket {
|
||||
_ => return Err(vm.new_type_error(
|
||||
"AF_INET6 address must be a tuple (host, port[, flowinfo[, scopeid]])"
|
||||
.to_owned(),
|
||||
)),
|
||||
).into()),
|
||||
}
|
||||
let (addr, flowinfo, scopeid) = Address::from_tuple_ipv6(&tuple, vm)?;
|
||||
let mut addr6 = get_addr(vm, addr.host, c::AF_INET6)?;
|
||||
@@ -493,7 +480,7 @@ mod _socket {
|
||||
}
|
||||
Ok(addr6.into())
|
||||
}
|
||||
_ => Err(vm.new_os_error(format!("{}(): bad family", caller))),
|
||||
_ => Err(vm.new_os_error(format!("{}(): bad family", caller)).into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +492,7 @@ mod _socket {
|
||||
) -> Result<(), IoOrPyException> {
|
||||
let sock_addr = self.extract_address(address, caller, vm)?;
|
||||
|
||||
let err = match self.sock(vm)?.connect(&sock_addr) {
|
||||
let err = match self.sock()?.connect(&sock_addr) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(e) => e,
|
||||
};
|
||||
@@ -526,8 +513,8 @@ mod _socket {
|
||||
// basically, connect() is async, and it registers an "error" on the socket when it's
|
||||
// done connecting. SelectKind::Connect fills the errorfds fd_set, so if we wake up
|
||||
// from poll and the error is EISCONN then we know that the connect is done
|
||||
self.sock_op_err(vm, SelectKind::Connect, || {
|
||||
let sock = self.sock_io()?;
|
||||
self.sock_op(vm, SelectKind::Connect, || {
|
||||
let sock = self.sock()?;
|
||||
let err = sock.take_error()?;
|
||||
match err {
|
||||
Some(e) if e.raw_os_error() == Some(libc::EISCONN) => Ok(()),
|
||||
@@ -552,11 +539,18 @@ mod _socket {
|
||||
OptionalOption<PyObjectRef>,
|
||||
);
|
||||
|
||||
fn init(
|
||||
fn init(zelf: PyRef<Self>, args: Self::Args, vm: &VirtualMachine) -> PyResult<()> {
|
||||
Self::_init(zelf, args, vm).map_err(|e| e.to_pyexception(vm))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(DefaultConstructor, Initializer), flags(BASETYPE))]
|
||||
impl PySocket {
|
||||
fn _init(
|
||||
zelf: PyRef<Self>,
|
||||
(family, socket_kind, proto, fileno): Self::Args,
|
||||
(family, socket_kind, proto, fileno): <Self as Initializer>::Args,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
) -> PyResult<(), IoOrPyException> {
|
||||
let mut family = family.unwrap_or(-1);
|
||||
let mut socket_kind = socket_kind.unwrap_or(-1);
|
||||
let mut proto = proto.unwrap_or(-1);
|
||||
@@ -577,7 +571,7 @@ mod _socket {
|
||||
) =>
|
||||
{
|
||||
std::mem::forget(sock);
|
||||
return Err(e.to_pyexception(vm));
|
||||
return Err(e.into());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -594,7 +588,7 @@ mod _socket {
|
||||
)
|
||||
};
|
||||
if res < 0 {
|
||||
return Err(crate::vm::stdlib::os::errno_err(vm));
|
||||
return Err(crate::common::os::errno().into());
|
||||
}
|
||||
}
|
||||
cfg_if::cfg_if! {
|
||||
@@ -605,7 +599,7 @@ mod _socket {
|
||||
target_os = "linux",
|
||||
))] {
|
||||
if proto == -1 {
|
||||
proto = sock.protocol().map_err(|e| e.to_pyexception(vm))?.map_or(0, Into::into);
|
||||
proto = sock.protocol()?.map_or(0, Into::into);
|
||||
}
|
||||
} else {
|
||||
proto = 0;
|
||||
@@ -625,19 +619,18 @@ mod _socket {
|
||||
Domain::from(family),
|
||||
SocketType::from(socket_kind),
|
||||
Some(Protocol::from(proto)),
|
||||
)
|
||||
.map_err(|err| err.to_pyexception(vm))?;
|
||||
)?;
|
||||
};
|
||||
zelf.init_inner(family, socket_kind, proto, sock, vm)
|
||||
Ok(zelf.init_inner(family, socket_kind, proto, sock)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(DefaultConstructor, Initializer), flags(BASETYPE))]
|
||||
impl PySocket {
|
||||
#[pymethod]
|
||||
fn connect(&self, address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn connect(
|
||||
&self,
|
||||
address: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(), IoOrPyException> {
|
||||
self.connect_inner(address, "connect", vm)
|
||||
.map_err(|e| e.to_pyexception(vm))
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -649,25 +642,24 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn bind(&self, address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn bind(&self, address: PyObjectRef, vm: &VirtualMachine) -> PyResult<(), IoOrPyException> {
|
||||
let sock_addr = self.extract_address(address, "bind", vm)?;
|
||||
self.sock(vm)?
|
||||
.bind(&sock_addr)
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
Ok(self.sock()?.bind(&sock_addr)?)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn listen(&self, backlog: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn listen(&self, backlog: OptionalArg<i32>) -> PyResult<(), io::Error> {
|
||||
let backlog = backlog.unwrap_or(128);
|
||||
let backlog = if backlog < 0 { 0 } else { backlog };
|
||||
self.sock(vm)?
|
||||
.listen(backlog)
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
self.sock()?.listen(backlog)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn _accept(&self, vm: &VirtualMachine) -> PyResult<(RawSocket, PyObjectRef)> {
|
||||
let (sock, addr) = self.sock_op(vm, SelectKind::Read, || self.sock_io()?.accept())?;
|
||||
fn _accept(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(RawSocket, PyObjectRef), IoOrPyException> {
|
||||
let (sock, addr) = self.sock_op(vm, SelectKind::Read, || self.sock()?.accept())?;
|
||||
let fd = into_sock_fileno(sock);
|
||||
Ok((fd, get_addr_tuple(&addr, vm)))
|
||||
}
|
||||
@@ -678,10 +670,10 @@ mod _socket {
|
||||
bufsize: usize,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Vec<u8>> {
|
||||
) -> PyResult<Vec<u8>, IoOrPyException> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let mut buffer = Vec::with_capacity(bufsize);
|
||||
let sock = self.sock(vm)?;
|
||||
let sock = self.sock()?;
|
||||
let n = self.sock_op(vm, SelectKind::Read, || {
|
||||
sock.recv_with_flags(buffer.spare_capacity_mut(), flags)
|
||||
})?;
|
||||
@@ -695,9 +687,9 @@ mod _socket {
|
||||
buf: ArgMemoryBuffer,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
) -> PyResult<usize, IoOrPyException> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let sock = self.sock(vm)?;
|
||||
let sock = self.sock()?;
|
||||
let mut buf = buf.borrow_buf_mut();
|
||||
let buf = &mut *buf;
|
||||
self.sock_op(vm, SelectKind::Read, || {
|
||||
@@ -711,14 +703,14 @@ mod _socket {
|
||||
bufsize: isize,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(Vec<u8>, PyObjectRef)> {
|
||||
) -> PyResult<(Vec<u8>, PyObjectRef), IoOrPyException> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let bufsize = bufsize
|
||||
.to_usize()
|
||||
.ok_or_else(|| vm.new_value_error("negative buffersize in recvfrom".to_owned()))?;
|
||||
let mut buffer = Vec::with_capacity(bufsize);
|
||||
let (n, addr) = self.sock_op(vm, SelectKind::Read, || {
|
||||
self.sock_io()?
|
||||
self.sock()?
|
||||
.recv_from_with_flags(buffer.spare_capacity_mut(), flags)
|
||||
})?;
|
||||
unsafe { buffer.set_len(n) };
|
||||
@@ -732,7 +724,7 @@ mod _socket {
|
||||
nbytes: OptionalArg<isize>,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(usize, PyObjectRef)> {
|
||||
) -> PyResult<(usize, PyObjectRef), IoOrPyException> {
|
||||
let mut buf = buf.borrow_buf_mut();
|
||||
let buf = &mut *buf;
|
||||
let buf = match nbytes {
|
||||
@@ -749,7 +741,7 @@ mod _socket {
|
||||
OptionalArg::Missing => buf,
|
||||
};
|
||||
let flags = flags.unwrap_or(0);
|
||||
let sock = self.sock(vm)?;
|
||||
let sock = self.sock()?;
|
||||
let (n, addr) = self.sock_op(vm, SelectKind::Read, || {
|
||||
sock.recv_from_with_flags(slice_as_uninit(buf), flags)
|
||||
})?;
|
||||
@@ -762,12 +754,12 @@ mod _socket {
|
||||
bytes: ArgBytesLike,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
) -> PyResult<usize, IoOrPyException> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let buf = bytes.borrow_buf();
|
||||
let buf = &*buf;
|
||||
self.sock_op(vm, SelectKind::Write, || {
|
||||
self.sock_io()?.send_with_flags(buf, flags)
|
||||
self.sock()?.send_with_flags(buf, flags)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -777,7 +769,7 @@ mod _socket {
|
||||
bytes: ArgBytesLike,
|
||||
flags: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
) -> PyResult<(), IoOrPyException> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
|
||||
let timeout = self.get_timeout().ok();
|
||||
@@ -789,16 +781,12 @@ mod _socket {
|
||||
let mut buf_offset = 0;
|
||||
// now we have like 3 layers of interrupt loop :)
|
||||
while buf_offset < buf.len() {
|
||||
let interval = deadline
|
||||
.as_ref()
|
||||
.map(|d| d.time_until().map_err(|e| e.to_pyexception(vm)))
|
||||
.transpose()?;
|
||||
let interval = deadline.as_ref().map(|d| d.time_until()).transpose()?;
|
||||
self.sock_op_timeout_err(vm, SelectKind::Write, interval, || {
|
||||
let subbuf = &buf[buf_offset..];
|
||||
buf_offset += self.sock_io()?.send_with_flags(subbuf, flags)?;
|
||||
buf_offset += self.sock()?.send_with_flags(subbuf, flags)?;
|
||||
Ok(())
|
||||
})
|
||||
.map_err(|e| e.to_pyexception(vm))?;
|
||||
})?;
|
||||
vm.check_signals()?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -811,7 +799,7 @@ mod _socket {
|
||||
arg2: PyObjectRef,
|
||||
arg3: OptionalArg<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
) -> PyResult<usize, IoOrPyException> {
|
||||
// signature is bytes[, flags], address
|
||||
let (flags, address) = match arg3 {
|
||||
OptionalArg::Present(arg3) => {
|
||||
@@ -828,15 +816,15 @@ mod _socket {
|
||||
let buf = bytes.borrow_buf();
|
||||
let buf = &*buf;
|
||||
self.sock_op(vm, SelectKind::Write, || {
|
||||
self.sock_io()?.send_to_with_flags(buf, &addr, flags)
|
||||
self.sock()?.send_to_with_flags(buf, &addr, flags)
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn close(&self, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn close(&self) -> io::Result<()> {
|
||||
let sock = self.detach();
|
||||
if sock != INVALID_SOCKET {
|
||||
close_inner(sock, vm)?;
|
||||
close_inner(sock)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -853,20 +841,14 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn getsockname(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
|
||||
let addr = self
|
||||
.sock(vm)?
|
||||
.local_addr()
|
||||
.map_err(|err| err.to_pyexception(vm))?;
|
||||
fn getsockname(&self, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
|
||||
let addr = self.sock()?.local_addr()?;
|
||||
|
||||
Ok(get_addr_tuple(&addr, vm))
|
||||
}
|
||||
#[pymethod]
|
||||
fn getpeername(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
|
||||
let addr = self
|
||||
.sock(vm)?
|
||||
.peer_addr()
|
||||
.map_err(|err| err.to_pyexception(vm))?;
|
||||
fn getpeername(&self, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
|
||||
let addr = self.sock()?.peer_addr()?;
|
||||
|
||||
Ok(get_addr_tuple(&addr, vm))
|
||||
}
|
||||
@@ -882,11 +864,9 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn setblocking(&self, block: bool, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn setblocking(&self, block: bool) -> io::Result<()> {
|
||||
self.timeout.store(if block { -1.0 } else { 0.0 });
|
||||
self.sock(vm)?
|
||||
.set_nonblocking(!block)
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
self.sock()?.set_nonblocking(!block)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -895,14 +875,12 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn settimeout(&self, timeout: Option<Duration>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn settimeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
self.timeout
|
||||
.store(timeout.map_or(-1.0, |d| d.as_secs_f64()));
|
||||
// even if timeout is > 0 the socket needs to be nonblocking in order for us to select() on
|
||||
// it
|
||||
self.sock(vm)?
|
||||
.set_nonblocking(timeout.is_some())
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
self.sock()?.set_nonblocking(timeout.is_some())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -988,20 +966,18 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn shutdown(&self, how: i32, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn shutdown(&self, how: i32, vm: &VirtualMachine) -> PyResult<(), IoOrPyException> {
|
||||
let how = match how {
|
||||
c::SHUT_RD => Shutdown::Read,
|
||||
c::SHUT_WR => Shutdown::Write,
|
||||
c::SHUT_RDWR => Shutdown::Both,
|
||||
_ => {
|
||||
return Err(vm.new_value_error(
|
||||
"`how` must be SHUT_RD, SHUT_WR, or SHUT_RDWR".to_owned(),
|
||||
))
|
||||
return Err(vm
|
||||
.new_value_error("`how` must be SHUT_RD, SHUT_WR, or SHUT_RDWR".to_owned())
|
||||
.into())
|
||||
}
|
||||
};
|
||||
self.sock(vm)?
|
||||
.shutdown(how)
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
Ok(self.sock()?.shutdown(how)?)
|
||||
}
|
||||
|
||||
#[pyproperty(name = "type")]
|
||||
@@ -1137,8 +1113,8 @@ mod _socket {
|
||||
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn sethostname(hostname: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
nix::unistd::sethostname(hostname.as_str()).map_err(|err| err.to_pyexception(vm))
|
||||
fn sethostname(hostname: PyStrRef) -> PyResult<(), nix::errno::Errno> {
|
||||
nix::unistd::sethostname(hostname.as_str())
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
@@ -1238,6 +1214,7 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
impl ToPyException for IoOrPyException {
|
||||
#[inline]
|
||||
fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
match self {
|
||||
Self::Timeout => timeout_error(vm),
|
||||
@@ -1335,7 +1312,10 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn getaddrinfo(opts: GAIOptions, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
|
||||
fn getaddrinfo(
|
||||
opts: GAIOptions,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Vec<PyObjectRef>, IoOrPyException> {
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
socktype: opts.ty,
|
||||
protocol: opts.proto,
|
||||
@@ -1368,8 +1348,7 @@ mod _socket {
|
||||
.into()
|
||||
})
|
||||
})
|
||||
.collect::<io::Result<Vec<_>>>()
|
||||
.map_err(|e| e.to_pyexception(vm))?;
|
||||
.collect::<io::Result<Vec<_>>>()?;
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
@@ -1377,7 +1356,7 @@ mod _socket {
|
||||
fn gethostbyaddr(
|
||||
addr: PyStrRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(String, PyListRef, PyListRef)> {
|
||||
) -> PyResult<(String, PyListRef, PyListRef), IoOrPyException> {
|
||||
let addr = get_addr(vm, addr, c::AF_UNSPEC)?;
|
||||
let (hostname, _) = dns_lookup::getnameinfo(&addr, 0)
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::HError))?;
|
||||
@@ -1390,7 +1369,7 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn gethostbyname(name: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
|
||||
fn gethostbyname(name: PyStrRef, vm: &VirtualMachine) -> PyResult<String, IoOrPyException> {
|
||||
let addr = get_addr(vm, name, c::AF_INET)?;
|
||||
match addr {
|
||||
SocketAddr::V4(ip) => Ok(ip.ip().to_string()),
|
||||
@@ -1402,7 +1381,7 @@ mod _socket {
|
||||
fn gethostbyname_ex(
|
||||
name: PyStrRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(String, PyListRef, PyListRef)> {
|
||||
) -> PyResult<(String, PyListRef, PyListRef), IoOrPyException> {
|
||||
let addr = get_addr(vm, name, c::AF_UNSPEC)?;
|
||||
let (hostname, _) = dns_lookup::getnameinfo(&addr, 0)
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::HError))?;
|
||||
@@ -1471,10 +1450,14 @@ mod _socket {
|
||||
address: PyTupleRef,
|
||||
flags: i32,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(String, String)> {
|
||||
) -> PyResult<(String, String), IoOrPyException> {
|
||||
match address.len() {
|
||||
2 | 3 | 4 => {}
|
||||
_ => return Err(vm.new_type_error("illegal sockaddr argument".to_owned())),
|
||||
_ => {
|
||||
return Err(vm
|
||||
.new_type_error("illegal sockaddr argument".to_owned())
|
||||
.into())
|
||||
}
|
||||
}
|
||||
let (addr, flowinfo, scopeid) = Address::from_tuple_ipv6(&address, vm)?;
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
@@ -1490,12 +1473,16 @@ mod _socket {
|
||||
.filter_map(Result::ok);
|
||||
let mut ainfo = res.next().unwrap();
|
||||
if res.next().is_some() {
|
||||
return Err(vm.new_os_error("sockaddr resolved to multiple addresses".to_owned()));
|
||||
return Err(vm
|
||||
.new_os_error("sockaddr resolved to multiple addresses".to_owned())
|
||||
.into());
|
||||
}
|
||||
match &mut ainfo.sockaddr {
|
||||
SocketAddr::V4(_) => {
|
||||
if address.len() != 2 {
|
||||
return Err(vm.new_os_error("IPv4 sockaddr must be 2 tuple".to_owned()));
|
||||
return Err(vm
|
||||
.new_os_error("IPv4 sockaddr must be 2 tuple".to_owned())
|
||||
.into());
|
||||
}
|
||||
}
|
||||
SocketAddr::V6(addr) => {
|
||||
@@ -1513,17 +1500,15 @@ mod _socket {
|
||||
family: OptionalArg<i32>,
|
||||
socket_kind: OptionalArg<i32>,
|
||||
proto: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(PySocket, PySocket)> {
|
||||
) -> PyResult<(PySocket, PySocket), IoOrPyException> {
|
||||
let family = family.unwrap_or(libc::AF_UNIX);
|
||||
let socket_kind = socket_kind.unwrap_or(libc::SOCK_STREAM);
|
||||
let proto = proto.unwrap_or(0);
|
||||
let (a, b) = Socket::pair(family.into(), socket_kind.into(), Some(proto.into()))
|
||||
.map_err(|e| e.to_pyexception(vm))?;
|
||||
let (a, b) = Socket::pair(family.into(), socket_kind.into(), Some(proto.into()))?;
|
||||
let py_a = PySocket::default();
|
||||
py_a.init_inner(family, socket_kind, proto, a, vm)?;
|
||||
py_a.init_inner(family, socket_kind, proto, a)?;
|
||||
let py_b = PySocket::default();
|
||||
py_b.init_inner(family, socket_kind, proto, b, vm)?;
|
||||
py_b.init_inner(family, socket_kind, proto, b)?;
|
||||
Ok((py_a, py_b))
|
||||
}
|
||||
|
||||
@@ -1696,7 +1681,11 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_addr(vm: &VirtualMachine, pyname: PyStrRef, af: i32) -> PyResult<SocketAddr> {
|
||||
fn get_addr(
|
||||
vm: &VirtualMachine,
|
||||
pyname: PyStrRef,
|
||||
af: i32,
|
||||
) -> PyResult<SocketAddr, IoOrPyException> {
|
||||
let name = pyname.as_str();
|
||||
if name.is_empty() {
|
||||
let hints = dns_lookup::AddrInfoHints {
|
||||
@@ -1707,16 +1696,22 @@ mod _socket {
|
||||
};
|
||||
let mut res = dns_lookup::getaddrinfo(None, Some("0"), Some(hints))
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))?;
|
||||
let ainfo = res.next().unwrap().map_err(|e| e.to_pyexception(vm))?;
|
||||
let ainfo = res.next().unwrap()?;
|
||||
if res.next().is_some() {
|
||||
return Err(vm.new_os_error("wildcard resolved to multiple address".to_owned()));
|
||||
return Err(vm
|
||||
.new_os_error("wildcard resolved to multiple address".to_owned())
|
||||
.into());
|
||||
}
|
||||
return Ok(ainfo.sockaddr);
|
||||
}
|
||||
if name == "255.255.255.255" || name == "<broadcast>" {
|
||||
match af {
|
||||
c::AF_INET | c::AF_UNSPEC => {}
|
||||
_ => return Err(vm.new_os_error("address family mismatched".to_owned())),
|
||||
_ => {
|
||||
return Err(vm
|
||||
.new_os_error("address family mismatched".to_owned())
|
||||
.into())
|
||||
}
|
||||
}
|
||||
return Ok(SocketAddr::V4(net::SocketAddrV4::new(
|
||||
c::INADDR_BROADCAST.into(),
|
||||
@@ -1745,10 +1740,7 @@ mod _socket {
|
||||
.map_err(|_| vm.new_runtime_error("idna output is not utf8".to_owned()))?;
|
||||
let mut res = dns_lookup::getaddrinfo(Some(name), None, Some(hints))
|
||||
.map_err(|e| convert_socket_error(vm, e, SocketError::GaiError))?;
|
||||
res.next()
|
||||
.unwrap()
|
||||
.map(|ainfo| ainfo.sockaddr)
|
||||
.map_err(|e| e.to_pyexception(vm))
|
||||
Ok(res.next().unwrap().map(|ainfo| ainfo.sockaddr)?)
|
||||
}
|
||||
|
||||
fn sock_from_raw(fileno: RawSocket, vm: &VirtualMachine) -> PyResult<Socket> {
|
||||
@@ -1819,9 +1811,9 @@ mod _socket {
|
||||
vm: &VirtualMachine,
|
||||
err: dns_lookup::LookupError,
|
||||
err_kind: SocketError,
|
||||
) -> PyBaseExceptionRef {
|
||||
) -> IoOrPyException {
|
||||
if let dns_lookup::LookupErrorKind::System = err.kind() {
|
||||
return io::Error::from(err).to_pyexception(vm);
|
||||
return io::Error::from(err).into();
|
||||
}
|
||||
let strerr = {
|
||||
#[cfg(unix)]
|
||||
@@ -1849,6 +1841,7 @@ mod _socket {
|
||||
exception_cls,
|
||||
vec![vm.new_pyobj(err.error_num()), vm.ctx.new_str(strerr).into()],
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn timeout_error(vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
@@ -1904,23 +1897,22 @@ mod _socket {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn dup(x: PyObjectRef, vm: &VirtualMachine) -> PyResult<RawSocket> {
|
||||
fn dup(x: PyObjectRef, vm: &VirtualMachine) -> PyResult<RawSocket, IoOrPyException> {
|
||||
let sock = get_raw_sock(x, vm)?;
|
||||
let sock = std::mem::ManuallyDrop::new(sock_from_raw(sock, vm)?);
|
||||
let newsock = sock.try_clone().map_err(|e| e.to_pyexception(vm))?;
|
||||
let newsock = sock.try_clone()?;
|
||||
let fd = into_sock_fileno(newsock);
|
||||
#[cfg(windows)]
|
||||
crate::vm::stdlib::nt::raw_set_handle_inheritable(fd as _, false)
|
||||
.map_err(|e| e.to_pyexception(vm))?;
|
||||
crate::vm::stdlib::nt::raw_set_handle_inheritable(fd as _, false)?;
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn close(x: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
close_inner(get_raw_sock(x, vm)?, vm)
|
||||
fn close(x: PyObjectRef, vm: &VirtualMachine) -> PyResult<(), IoOrPyException> {
|
||||
Ok(close_inner(get_raw_sock(x, vm)?)?)
|
||||
}
|
||||
|
||||
fn close_inner(x: RawSocket, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn close_inner(x: RawSocket) -> io::Result<()> {
|
||||
#[cfg(unix)]
|
||||
use libc::close;
|
||||
#[cfg(windows)]
|
||||
@@ -1929,7 +1921,7 @@ mod _socket {
|
||||
if ret < 0 {
|
||||
let err = crate::common::os::errno();
|
||||
if err.raw_os_error() != Some(errcode!(ECONNRESET)) {
|
||||
return Err(err.to_pyexception(vm));
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -5,7 +5,7 @@ use super::{
|
||||
use crate::common::lock::PyRwLockReadGuard;
|
||||
use crate::{
|
||||
builtins::{PyBaseExceptionRef, PyType},
|
||||
convert::{ToPyObject, ToPyResult, TryFromObject},
|
||||
convert::{ToPyException, ToPyObject, ToPyResult, TryFromObject},
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::{borrow::Borrow, fmt, ops::Deref};
|
||||
@@ -27,7 +27,7 @@ Basically reference counting, but then done by rust.
|
||||
/// Use this type for functions which return a python object or an exception.
|
||||
/// Both the python object and the python exception are `PyObjectRef` types
|
||||
/// since exceptions are also python objects.
|
||||
pub type PyResult<T = PyObjectRef> = Result<T, PyBaseExceptionRef>; // A valid value, or an exception
|
||||
pub type PyResult<T = PyObjectRef, E = PyBaseExceptionRef> = Result<T, E>; // A valid value, or an exception
|
||||
|
||||
// TODO: remove these 2 impls
|
||||
impl fmt::Display for PyObjectRef {
|
||||
@@ -272,12 +272,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToPyResult for PyResult<T>
|
||||
impl<T, E> ToPyResult for PyResult<T, E>
|
||||
where
|
||||
T: ToPyObject,
|
||||
E: ToPyException,
|
||||
{
|
||||
#[inline(always)]
|
||||
fn to_pyresult(self, vm: &VirtualMachine) -> PyResult {
|
||||
self.map(|res| T::to_pyobject(res, vm))
|
||||
.map_err(|e| E::to_pyexception(e, vm))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPyException for PyBaseExceptionRef {
|
||||
#[inline(always)]
|
||||
fn to_pyexception(self, _vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,12 @@ use crate::{
|
||||
};
|
||||
pub use _io::io_open as open;
|
||||
|
||||
impl ToPyException for std::io::Error {
|
||||
fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
(&self).to_pyexception(vm)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPyException for &'_ std::io::Error {
|
||||
fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
use std::io::ErrorKind;
|
||||
|
||||
Reference in New Issue
Block a user