Update Redox platform to pal
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
use core::{mem, ptr};
|
||||
use core::fmt::Write;
|
||||
|
||||
use FileWriter;
|
||||
use Pal;
|
||||
use errno;
|
||||
use {errno, FileWriter, Pal};
|
||||
use types::*;
|
||||
|
||||
mod signal;
|
||||
@@ -81,8 +79,8 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
|
||||
}
|
||||
|
||||
fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
|
||||
e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
|
||||
unsafe fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
|
||||
e(syscall!(EXECVE, path, argv, envp)) as c_int
|
||||
}
|
||||
|
||||
fn exit(status: c_int) -> ! {
|
||||
|
||||
@@ -45,7 +45,7 @@ pub trait Pal {
|
||||
Self::no_pal("dup2")
|
||||
}
|
||||
|
||||
fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
|
||||
unsafe fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
|
||||
Self::no_pal("execve")
|
||||
}
|
||||
|
||||
|
||||
+677
-1012
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
impl PalSignal for Sys {
|
||||
fn kill(pid: pid_t, sig: c_int) -> c_int {
|
||||
e(syscall::kill(pid as usize, sig as usize)) as c_int
|
||||
}
|
||||
|
||||
fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
|
||||
e(syscall::kill(-(pgrp as isize) as usize, sig as usize)) as c_int
|
||||
}
|
||||
|
||||
fn raise(sig: c_int) -> c_int {
|
||||
kill(getpid(), sig)
|
||||
}
|
||||
|
||||
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
|
||||
if !oact.is_null() {
|
||||
// Assumes the last sigaction() call was made by relibc and not a different one
|
||||
if SIG_HANDLER.is_some() {
|
||||
(*oact).sa_handler = SIG_HANDLER;
|
||||
}
|
||||
}
|
||||
let act = if act.is_null() {
|
||||
None
|
||||
} else {
|
||||
SIG_HANDLER = (*act).sa_handler;
|
||||
let m = (*act).sa_mask;
|
||||
Some(syscall::SigAction {
|
||||
sa_handler: sig_handler,
|
||||
sa_mask: [0, m as u64],
|
||||
sa_flags: (*act).sa_flags as usize,
|
||||
})
|
||||
};
|
||||
let mut old = syscall::SigAction::default();
|
||||
let ret = e(syscall::sigaction(
|
||||
sig as usize,
|
||||
act.as_ref(),
|
||||
if oact.is_null() { None } else { Some(&mut old) },
|
||||
)) as c_int;
|
||||
if !oact.is_null() {
|
||||
let m = old.sa_mask;
|
||||
(*oact).sa_mask = m[1] as c_ulong;
|
||||
(*oact).sa_flags = old.sa_flags as c_ulong;
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
//fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
macro_rules! bind_or_connect {
|
||||
(bind $path:expr) => {
|
||||
concat!("/", $path)
|
||||
};
|
||||
(connect $path:expr) => {
|
||||
$path
|
||||
};
|
||||
($mode:ident $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 = &data.sin_addr.s_addr;
|
||||
let port = in_port_t::from_be(data.sin_port); // This is transmuted from bytes in BigEndian order
|
||||
let path = format!(bind_or_connect!($mode "{}.{}.{}.{}:{}"), addr[0], addr[1], addr[2], addr[3], port);
|
||||
|
||||
// Duplicate the socket, and then duplicate the copy back to the original fd
|
||||
let fd = e(syscall::dup($socket as usize, path.as_bytes()));
|
||||
if (fd as c_int) < 0 {
|
||||
return -1;
|
||||
}
|
||||
let result = syscall::dup2(fd, $socket as usize, &[]);
|
||||
let _ = syscall::close(fd);
|
||||
if (e(result) as c_int) < 0 {
|
||||
return -1;
|
||||
}
|
||||
0
|
||||
}}
|
||||
}
|
||||
|
||||
unsafe fn inner_get_name(
|
||||
local: bool,
|
||||
socket: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> Result<usize> {
|
||||
// 32 should probably be large enough.
|
||||
// Format: tcp:remote/local
|
||||
// and since we only yet support IPv4 (I think)...
|
||||
let mut buf = [0; 32];
|
||||
let len = syscall::fpath(socket as usize, &mut buf)?;
|
||||
let buf = &buf[..len];
|
||||
assert!(&buf[..4] == b"tcp:" || &buf[..4] == b"udp:");
|
||||
let buf = &buf[4..];
|
||||
|
||||
let mut parts = buf.split(|c| *c == b'/');
|
||||
if local {
|
||||
// Skip the remote part
|
||||
parts.next();
|
||||
}
|
||||
let part = parts.next().expect("Invalid reply from netstack");
|
||||
|
||||
let data = slice::from_raw_parts_mut(
|
||||
&mut (*address).data as *mut _ as *mut u8,
|
||||
(*address).data.len(),
|
||||
);
|
||||
|
||||
let len = data.len().min(part.len());
|
||||
data[..len].copy_from_slice(&part[..len]);
|
||||
|
||||
*address_len = len as socklen_t;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
impl PalSocket for Sys {
|
||||
unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
|
||||
let stream = e(syscall::dup(socket as usize, b"listen")) as c_int;
|
||||
if stream < 0 {
|
||||
return -1;
|
||||
}
|
||||
if address != ptr::null_mut()
|
||||
&& address_len != ptr::null_mut()
|
||||
&& getpeername(stream, address, address_len) < 0
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
stream
|
||||
}
|
||||
|
||||
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
|
||||
bind_or_connect!(bind socket, address, address_len)
|
||||
}
|
||||
|
||||
unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
|
||||
bind_or_connect!(connect socket, address, address_len)
|
||||
}
|
||||
|
||||
unsafe fn getpeername(
|
||||
socket: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
e(inner_get_name(false, socket, address, address_len)) as c_int
|
||||
}
|
||||
|
||||
unsafe fn getsockname(
|
||||
socket: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
e(inner_get_name(true, socket, address, address_len)) as c_int
|
||||
}
|
||||
|
||||
unsafe fn recvfrom(
|
||||
socket: c_int,
|
||||
buf: *mut c_void,
|
||||
len: size_t,
|
||||
flags: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> ssize_t {
|
||||
if flags != 0 {
|
||||
errno = syscall::EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
if address != ptr::null_mut()
|
||||
&& address_len != ptr::null_mut()
|
||||
&& getpeername(socket, address, address_len) < 0
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
|
||||
}
|
||||
|
||||
unsafe fn sendto(
|
||||
socket: c_int,
|
||||
buf: *const c_void,
|
||||
len: size_t,
|
||||
flags: c_int,
|
||||
dest_addr: *const sockaddr,
|
||||
dest_len: socklen_t,
|
||||
) -> ssize_t {
|
||||
if dest_addr != ptr::null() || dest_len != 0 {
|
||||
errno = syscall::EISCONN;
|
||||
return -1;
|
||||
}
|
||||
if flags != 0 {
|
||||
errno = syscall::EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
write(socket, slice::from_raw_parts(buf as *const u8, len))
|
||||
}
|
||||
|
||||
unsafe fn socket(domain: c_int, mut kind: c_int, protocol: c_int) -> c_int {
|
||||
if domain != AF_INET {
|
||||
errno = syscall::EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if protocol != 0 {
|
||||
errno = syscall::EPROTONOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
let mut flags = O_RDWR;
|
||||
if kind & SOCK_NONBLOCK == SOCK_NONBLOCK {
|
||||
kind &= !SOCK_NONBLOCK;
|
||||
flags |= O_NONBLOCK;
|
||||
}
|
||||
if kind & SOCK_CLOEXEC == SOCK_CLOEXEC {
|
||||
kind &= !SOCK_CLOEXEC;
|
||||
flags |= O_CLOEXEC;
|
||||
}
|
||||
|
||||
// The tcp: and udp: schemes allow using no path,
|
||||
// and later specifying one using `dup`.
|
||||
match kind {
|
||||
SOCK_STREAM => e(syscall::open("tcp:", flags)) as c_int,
|
||||
SOCK_DGRAM => e(syscall::open("udp:", flags)) as c_int,
|
||||
_ => {
|
||||
errno = syscall::EPROTOTYPE;
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user