1

How can you call Linux' socketpair() command in rust? I was not able to find it in the documentation.

4

1 回答 1

1

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) => {}
    }
}
于 2014-02-08T21:42:57.693 回答