Skip to content

Commit c84d351

Browse files
committed
Add socket.{bind,listen,accept}
1 parent 49837f5 commit c84d351

File tree

1 file changed

+74
-3
lines changed

1 file changed

+74
-3
lines changed

vm/src/stdlib/socket.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use num_traits::ToPrimitive;
1111
use std::io;
1212
use std::io::Read;
1313
use std::io::Write;
14-
use std::net::{TcpListener, TcpStream, UdpSocket};
14+
use std::net::{SocketAddr, TcpListener, TcpStream, UdpSocket};
1515

16-
#[derive(Debug)]
16+
#[derive(Copy, Clone)]
1717
enum AddressFamily {
1818
AfUnix = 1,
1919
AfInet = 2,
@@ -31,7 +31,7 @@ impl AddressFamily {
3131
}
3232
}
3333

34-
#[derive(Debug)]
34+
#[derive(Copy, Clone)]
3535
enum SocketKind {
3636
SockStream = 1,
3737
SockDgram = 2,
@@ -53,6 +53,15 @@ enum Connection {
5353
UdpSocket(UdpSocket),
5454
}
5555

56+
impl Connection {
57+
fn accept(&mut self) -> io::Result<(TcpStream, SocketAddr)> {
58+
match self {
59+
Connection::TcpListener(con) => con.accept(),
60+
_ => Err(io::Error::new(io::ErrorKind::Other, "oh no!")),
61+
}
62+
}
63+
}
64+
5665
impl Read for Connection {
5766
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
5867
match self {
@@ -135,6 +144,65 @@ fn socket_connect(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
135144
}
136145
}
137146

147+
fn socket_bind(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
148+
arg_check!(
149+
vm,
150+
args,
151+
required = [(zelf, None), (address, Some(vm.ctx.str_type()))]
152+
);
153+
154+
let mut mut_obj = zelf.borrow_mut();
155+
156+
match mut_obj.payload {
157+
PyObjectPayload::Socket { ref mut socket } => {
158+
if let Ok(stream) = TcpListener::bind(objstr::get_value(&address)) {
159+
socket.con = Some(Connection::TcpListener(stream));
160+
Ok(vm.get_none())
161+
} else {
162+
// TODO: Socket error
163+
Err(vm.new_type_error("socket failed".to_string()))
164+
}
165+
}
166+
_ => Err(vm.new_type_error("".to_string())),
167+
}
168+
}
169+
170+
fn socket_listen(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
171+
Ok(vm.get_none())
172+
}
173+
174+
fn socket_accept(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
175+
arg_check!(vm, args, required = [(zelf, None)]);
176+
177+
let mut mut_obj = zelf.borrow_mut();
178+
179+
match mut_obj.payload {
180+
PyObjectPayload::Socket { ref mut socket } => {
181+
let ret = match socket.con {
182+
Some(ref mut v) => v.accept(),
183+
None => return Err(vm.new_type_error("".to_string())),
184+
};
185+
186+
let tcp_stream = match ret {
187+
Ok((socket, _addr)) => socket,
188+
_ => return Err(vm.new_type_error("".to_string())),
189+
};
190+
191+
let socket = Socket {
192+
address_family: socket.address_family.clone(),
193+
sk: socket.sk.clone(),
194+
con: Some(Connection::TcpStream(tcp_stream)),
195+
};
196+
197+
Ok(PyObject::new(
198+
PyObjectPayload::Socket { socket },
199+
mut_obj.typ(),
200+
))
201+
}
202+
_ => Err(vm.new_type_error("".to_string())),
203+
}
204+
}
205+
138206
fn socket_recv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
139207
arg_check!(
140208
vm,
@@ -219,6 +287,9 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
219287
ctx.set_attr(&socket, "connect", ctx.new_rustfunc(socket_connect));
220288
ctx.set_attr(&socket, "recv", ctx.new_rustfunc(socket_recv));
221289
ctx.set_attr(&socket, "send", ctx.new_rustfunc(socket_send));
290+
ctx.set_attr(&socket, "bind", ctx.new_rustfunc(socket_bind));
291+
ctx.set_attr(&socket, "accept", ctx.new_rustfunc(socket_accept));
292+
ctx.set_attr(&socket, "listen", ctx.new_rustfunc(socket_listen));
222293
ctx.set_attr(&socket, "close", ctx.new_rustfunc(socket_close));
223294
socket
224295
};

0 commit comments

Comments
 (0)