How can you call Linux' socketpair()
command in rust?
I was not able to find it in the documentation.
This is how it works:
use std::io;
use std::libc;
use std::libc::consts::os::bsd44;
use std::libc::funcs::bsd43;
extern {
fn socketpair(
domain: libc::c_int,
typ: libc::c_int,
protocol: libc::c_int,
sv: *libc::c_int
) -> libc::c_int;
}
struct PairedStream {
socket: i32
}
impl PairedStream {
fn new(fd: i32) -> PairedStream {
PairedStream {socket: fd}
}
fn send(&self, buf: &[u8]) -> Result<(), io::IoError> {
let res = unsafe {
let ptr = buf.as_ptr() as *mut libc::c_void;
let len = buf.len() as u64;
bsd43::send(self.socket, ptr, len, 0) as uint == buf.len()
};
if res {
return Ok(());
}
else {
return Err(io::IoError {
kind: io::OtherIoError,
desc: "TODO: determine error types ;)",
detail: None,
})
}
}
fn read(&self, buf: &mut [u8]) -> Result<uint, io::IoError> {
let len = unsafe {
let ptr = buf.as_ptr() as *mut libc::c_void;
let len = buf.len() as u64;
bsd43::recv(self.socket, ptr, len, 0)
};
if len == -1 {
return Err(io::IoError {
kind: io::OtherIoError,
desc: "TODO: determine error types ;)",
detail: None,
})
}
else {
return Ok(len as uint);
}
}
}
struct SocketPair;
impl SocketPair {
fn new() -> (Result<(PairedStream, PairedStream), io::IoError>) {
let AF_LOCAL = 1;
let sv: [i32, ..2] = [-1, -1];
let _type = bsd44::SOCK_DGRAM;
let res = unsafe {
socketpair(AF_LOCAL, _type, 0, sv.as_ptr()) == 0
};
if res {
let s1 = PairedStream::new(sv[0]);
let s2 = PairedStream::new(sv[1]);
return Ok((s1, s2));
}
else {
return Err(io::IoError {
kind: io::OtherIoError,
desc: "TODO: determine error types ;)",
detail: None,
})
}
}
}
fn main() {
let sockets = SocketPair::new();
match sockets {
Ok((s1, s2)) => {
let mut buf = [9,8,7,6,5,4,3,2,1];
s1.send([1,2,3,4,5,6,7,8,9]);
s2.read(buf);
println!("{} {}", buf[0], buf[8])
}
Err(ioerr) => {}
}
}