platform/redox: Support AF_UNIX in bind / connect.
Previously, domain AF_INET was assumed while processing bind() / connect(), which end up calling bind_or_connect!. Instead, match on the domain type and process the path for AF_UNIX domains.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use core::{mem, ptr, slice};
|
||||
use core::{mem, ptr, slice, str};
|
||||
use syscall::{self, flag::*, Result};
|
||||
|
||||
use super::{
|
||||
@@ -9,6 +9,7 @@ use crate::header::{
|
||||
netinet_in::{in_port_t, sockaddr_in},
|
||||
sys_socket::{constants::*, sockaddr, socklen_t},
|
||||
sys_time::timeval,
|
||||
sys_un::sockaddr_un,
|
||||
};
|
||||
|
||||
macro_rules! bind_or_connect {
|
||||
@@ -29,28 +30,48 @@ macro_rules! bind_or_connect {
|
||||
0
|
||||
}};
|
||||
($mode:ident copy, $socket:expr, $address:expr, $address_len:expr) => {{
|
||||
if (*$address).sa_family as c_int != AF_INET {
|
||||
errno = syscall::EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if ($address_len as usize) < mem::size_of::<sockaddr>() {
|
||||
errno = syscall::EINVAL;
|
||||
return -1;
|
||||
}
|
||||
let data = &*($address as *const sockaddr_in);
|
||||
let addr = slice::from_raw_parts(
|
||||
&data.sin_addr.s_addr as *const _ as *const u8,
|
||||
mem::size_of_val(&data.sin_addr.s_addr),
|
||||
);
|
||||
let port = in_port_t::from_be(data.sin_port);
|
||||
let path = format!(
|
||||
bind_or_connect!($mode "{}.{}.{}.{}:{}"),
|
||||
addr[0],
|
||||
addr[1],
|
||||
addr[2],
|
||||
addr[3],
|
||||
port
|
||||
);
|
||||
|
||||
let path = match (*$address).sa_family as c_int {
|
||||
AF_INET => {
|
||||
let data = &*($address as *const sockaddr_in);
|
||||
let addr = slice::from_raw_parts(
|
||||
&data.sin_addr.s_addr as *const _ as *const u8,
|
||||
mem::size_of_val(&data.sin_addr.s_addr),
|
||||
);
|
||||
let port = in_port_t::from_be(data.sin_port);
|
||||
let path = format!(
|
||||
bind_or_connect!($mode "{}.{}.{}.{}:{}"),
|
||||
addr[0],
|
||||
addr[1],
|
||||
addr[2],
|
||||
addr[3],
|
||||
port
|
||||
);
|
||||
|
||||
path
|
||||
},
|
||||
AF_UNIX => {
|
||||
let data = &*($address as *const sockaddr_un);
|
||||
let addr = slice::from_raw_parts(
|
||||
&data.sun_path as *const _ as *const u8,
|
||||
mem::size_of_val(&data.sun_path),
|
||||
);
|
||||
let path = format!(
|
||||
"{}",
|
||||
str::from_utf8(addr).unwrap()
|
||||
);
|
||||
|
||||
path
|
||||
},
|
||||
_ => {
|
||||
errno = syscall::EAFNOSUPPORT;
|
||||
return -1;
|
||||
},
|
||||
};
|
||||
|
||||
// Duplicate the socket, and then duplicate the copy back to the original fd
|
||||
let fd = e(syscall::dup($socket as usize, path.as_bytes()));
|
||||
|
||||
Reference in New Issue
Block a user