Add a few things necessary for openssl (not all)

This commit is contained in:
jD91mZM2
2018-07-08 08:44:23 +02:00
parent 587ee32a30
commit d3f6985ee9
23 changed files with 427 additions and 30 deletions
+17
View File
@@ -4,6 +4,7 @@
#![feature(allocator_api)]
//TODO #![feature(thread_local)]
#[cfg_attr(target_os = "redox", macro_use)]
extern crate alloc;
#[cfg(all(not(feature = "no_std"), target_os = "linux"))]
@@ -43,6 +44,22 @@ use types::*;
#[global_allocator]
static ALLOCATOR: Allocator = Allocator;
pub const AF_INET: c_int = 2;
pub const SOCK_STREAM: c_int = 1;
pub const SOCK_DGRAM: c_int = 2;
pub const SOCK_NONBLOCK: c_int = 0o4000;
pub const SOCK_CLOEXEC: c_int = 0o2000000;
pub type in_addr_t = [u8; 4];
pub type in_port_t = u16;
pub type sa_family_t = u16;
pub type socklen_t = u32;
pub struct sockaddr {
pub sa_family: sa_family_t,
pub data: [c_char; 14]
}
//TODO #[thread_local]
#[allow(non_upper_case_globals)]
#[no_mangle]
+23 -1
View File
@@ -1,6 +1,6 @@
use core::ptr;
use errno;
use ::*;
use types::*;
const AT_FDCWD: c_int = -100;
@@ -19,6 +19,10 @@ pub fn e(sys: usize) -> usize {
}
}
pub unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
e(syscall!(BIND, socket, address, address_len)) as c_int
}
pub fn brk(addr: *mut c_void) -> *mut c_void {
unsafe { syscall!(BRK, addr) as *mut c_void }
}
@@ -39,6 +43,10 @@ pub fn close(fildes: c_int) -> c_int {
e(unsafe { syscall!(CLOSE, fildes) }) as c_int
}
pub unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
e(syscall!(CONNECT, socket, address, address_len)) as c_int
}
pub fn dup(fildes: c_int) -> c_int {
e(unsafe { syscall!(DUP, fildes) }) as c_int
}
@@ -171,6 +179,11 @@ pub fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
}
pub 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 {
e(syscall!(RECVFROM, socket, buf, len, flags, address, address_len)) as ssize_t
}
pub fn rename(old: *const c_char, new: *const c_char) -> c_int {
e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old, AT_FDCWD, new) }) as c_int
}
@@ -179,6 +192,11 @@ pub fn rmdir(path: *const c_char) -> c_int {
e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, AT_REMOVEDIR) }) as c_int
}
pub 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 {
e(syscall!(SENDTO, socket, buf, len, flags, dest_addr, dest_len)) as ssize_t
}
pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
e(unsafe { syscall!(SETPGID, pid, pgid) }) as c_int
}
@@ -195,6 +213,10 @@ pub fn stat(file: *const c_char, buf: *mut stat) -> c_int {
e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, 0) }) as c_int
}
pub fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
e(unsafe { syscall!(SOCKET, domain, kind, protocol) }) as c_int
}
pub fn uname(utsname: usize) -> c_int {
e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
}
+112 -2
View File
@@ -1,3 +1,4 @@
use alloc;
use core::mem;
use core::ptr;
use core::slice;
@@ -6,10 +7,16 @@ use syscall::data::Stat as redox_stat;
use syscall::data::TimeSpec as redox_timespec;
use syscall::flag::*;
use c_str;
use errno;
use ::*;
use types::*;
#[repr(C)]
struct SockData {
port: in_port_t,
addr: in_addr_t,
_pad: [c_char; 8]
}
pub fn e(sys: Result<usize, syscall::Error>) -> usize {
match sys {
Ok(ok) => ok,
@@ -22,6 +29,45 @@ pub fn e(sys: Result<usize, syscall::Error>) -> usize {
}
}
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: &SockData = mem::transmute(&(*$address).data);
let addr = &data.addr;
let port = in_port_t::from_be(data.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
}}
}
pub unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
bind_or_connect!(bind socket, address, address_len)
}
pub fn brk(addr: *mut c_void) -> *mut c_void {
unsafe { syscall::brk(addr as usize).unwrap_or(0) as *mut c_void }
}
@@ -59,6 +105,10 @@ pub fn close(fd: c_int) -> c_int {
e(syscall::close(fd as usize)) as c_int
}
pub unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
bind_or_connect!(connect socket, address, address_len)
}
pub fn dup(fd: c_int) -> c_int {
e(syscall::dup(fd as usize, &[])) as c_int
}
@@ -331,6 +381,24 @@ pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
e(syscall::read(fd as usize, buf)) as ssize_t
}
pub 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;
}
let data = slice::from_raw_parts_mut(
&mut (*address).data as *mut _ as *mut u8,
(*address).data.len()
);
let pathlen = e(syscall::fpath(socket as usize, data));
if pathlen < 0 {
return -1;
}
*address_len = pathlen as socklen_t;
read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
}
pub fn rename(oldpath: *const c_char, newpath: *const c_char) -> c_int {
let (oldpath, newpath) = unsafe { (c_str(oldpath), c_str(newpath)) };
match syscall::open(oldpath, O_WRONLY) {
@@ -348,6 +416,16 @@ pub fn rmdir(path: *const c_char) -> c_int {
e(syscall::rmdir(path)) as c_int
}
pub 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 {
// TODO: Use dest_addr and dest_len
if flags != 0 {
errno = syscall::EOPNOTSUPP;
return -1;
}
write(socket, slice::from_raw_parts(buf as *const u8, len))
}
pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
e(syscall::setpgid(pid as usize, pgid as usize)) as c_int
}
@@ -372,6 +450,38 @@ pub fn stat(path: *const c_char, buf: *mut stat) -> c_int {
}
}
pub 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
}
}
}
pub fn unlink(path: *const c_char) -> c_int {
let path = unsafe { c_str(path) };
e(syscall::unlink(path)) as c_int