Add a few things necessary for openssl (not all)
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user