Verified Commit d3f6985e authored by jD91mZM2's avatar jD91mZM2

Add a few things necessary for openssl (not all)

parent 587ee32a
Pipeline #559 failed with stages
in 40 seconds
......@@ -304,6 +304,7 @@ dependencies = [
"stdio 0.1.0",
"stdlib 0.1.0",
"string 0.1.0",
"strings 0.1.0",
"sys_mman 0.1.0",
"sys_resource 0.1.0",
"sys_socket 0.1.0",
......@@ -446,6 +447,14 @@ dependencies = [
"platform 0.1.0",
]
[[package]]
name = "strings"
version = "0.1.0"
dependencies = [
"cbindgen 0.5.2",
"platform 0.1.0",
]
[[package]]
name = "strsim"
version = "0.7.0"
......
......@@ -30,6 +30,7 @@ signal = { path = "src/signal" }
stdio = { path = "src/stdio" }
stdlib = { path = "src/stdlib" }
string = { path = "src/string" }
strings = { path = "src/strings" }
sys_mman = { path = "src/sys_mman" }
sys_resource = { path = "src/sys_resource" }
sys_socket = { path = "src/sys_socket" }
......
#ifndef _SYS_PARAM_H
#define _SYS_PARAM_H
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define __bitop(array, index, op) ((array)[(index) / 8] op (1 << (index) % 8))
#define setbit(array, index) __bitop(array, index, |=)
#define clrbit(array, index) __bitop(array, index, &= ~)
#define isset(array, index) __bitop(array, index, &)
#define isclr(array, index) !isset(array, index)
#define howmany(bits, size) (((bits) + (size) - 1) / (size))
#define roundup(bits, size) (howmany(bits, size) * (size))
#define powerof2(n) !(((n) - 1) & (n))
// Shamelessly copied from musl.
// Tweak as needed.
#define MAXSYMLINKS 20
#define MAXHOSTNAMELEN 64
#define MAXNAMLEN 255
#define MAXPATHLEN 4096
#define NBBY 8
#define NGROUPS 32
#define CANBSIZ 255
#define NOFILE 256
#define NCARGS 131072
#define DEV_BSIZE 512
#define NOGROUP (-1)
#include <sys/resource.h>
#include <limits.h>
#endif
......@@ -18,7 +18,7 @@ pub extern "C" fn isalpha(c: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn isascii(c: c_int) -> c_int {
(!(c & !0x7f)) as c_int
((c & !0x7f) == 0) as c_int
}
#[no_mangle]
......
......@@ -20,6 +20,7 @@ pub extern crate signal;
pub extern crate stdio;
pub extern crate stdlib;
pub extern crate string;
pub extern crate strings;
pub extern crate sys_mman;
pub extern crate sys_resource;
pub extern crate sys_socket;
......
......@@ -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]
......
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
}
......
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
......
......@@ -55,13 +55,11 @@ pub unsafe fn printf<W: Write>(mut w: W, format: *const c_char, mut ap: VaList)
w.write_fmt(format_args!("0x{:x}", a))
}
's' => {
let a = ap.get::<usize>();
let a = ap.get::<*const c_char>();
found_percent = false;
w.write_str(str::from_utf8_unchecked(platform::c_str(
a as *const c_char,
)))
w.write_str(str::from_utf8_unchecked(platform::c_str(a)))
}
'u' => {
let a = ap.get::<c_uint>();
......
......@@ -229,7 +229,7 @@ pub extern "C" fn erand(xsubi: [c_ushort; 3]) -> c_double {
}
#[no_mangle]
pub unsafe extern "C" fn exit(status: c_int) -> ! {
pub unsafe extern "C" fn exit(status: c_int) {
for i in (0..ATEXIT_FUNCS.len()).rev() {
if let Some(func) = ATEXIT_FUNCS[i] {
(func)();
......
......@@ -126,14 +126,13 @@ pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_ch
}
#[no_mangle]
pub unsafe extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char {
let c = c as i8;
let mut i = 0;
while *s.offset(i) != 0 {
if *s.offset(i) == c {
return s.offset(i) as *mut c_char;
pub unsafe extern "C" fn strchr(mut s: *const c_char, c: c_int) -> *mut c_char {
let c = c as c_char;
while *s != 0 {
if *s == c {
return s as *mut c_char;
}
i += 1;
s = s.offset(1);
}
ptr::null_mut()
}
......@@ -276,7 +275,7 @@ pub unsafe extern "C" fn strncpy(s1: *mut c_char, s2: *const c_char, n: usize) -
}
// if length of s2 < n, pad s1 with zeroes
for _ in cmp::min(n, s2_len)..n {
while idx < s2_len {
*s1.offset(idx as isize) = 0;
idx += 1;
}
......
[package]
name = "strings"
version = "0.1.0"
authors = ["jD91mZM2 <me@krake.one>"]
build = "build.rs"
[build-dependencies]
cbindgen = { path = "../../cbindgen" }
[dependencies]
platform = { path = "../platform" }
extern crate cbindgen;
use std::{env, fs};
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
fs::create_dir_all("../../target/include").expect("failed to create include directory");
cbindgen::generate(crate_dir)
.expect("failed to generate bindings")
.write_to_file("../../target/include/strings.h");
}
sys_includes = ["stddef.h", "stdint.h"]
include_guard = "_STRINGS_H"
language = "C"
style = "Tag"
[enum]
prefix_with_name = true
//! strings implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/strings.h.html
#![no_std]
#![feature(alloc)]
extern crate alloc;
extern crate platform;
use alloc::Vec;
use core::ptr;
use platform::types::*;
#[no_mangle]
pub unsafe extern "C" fn bcmp(mut first: *const c_void, mut second: *const c_void, n: size_t) -> c_int {
let first = first as *const c_char;
let second = second as *const c_char;
for i in 0..n as isize {
if *first.offset(i) != *second.offset(i) {
return -1;
}
}
0
}
#[no_mangle]
pub unsafe extern "C" fn bcopy(src: *const c_void, dst: *mut c_void, n: size_t) {
let src = src as *mut c_char;
let dst = dst as *mut c_char;
let mut tmp = Vec::with_capacity(n);
for i in 0..n as isize {
tmp.push(*src.offset(i));
}
for (i, val) in tmp.into_iter().enumerate() {
*dst.offset(i as isize) = val;
}
}
#[no_mangle]
pub unsafe extern "C" fn bzero(src: *mut c_void, n: size_t) {
let src = src as *mut c_char;
for i in 0..n as isize {
*src.offset(i) = 0;
}
}
#[no_mangle]
pub extern "C" fn ffs(mut i: c_int) -> c_int {
if i == 0 {
return 0;
}
let mut n = 1;
while i & 1 == 0 {
i >>= 1;
n += 1;
}
n
}
#[no_mangle]
pub unsafe extern "C" fn index(mut s: *const c_char, c: c_int) -> *mut c_char {
while *s != 0 {
if *s == c as c_char {
// Input is const but output is mutable. WHY C, WHY DO THIS?
return s as *mut c_char;
}
s = s.offset(1);
}
ptr::null_mut()
}
#[no_mangle]
pub unsafe extern "C" fn rindex(mut s: *const c_char, c: c_int) -> *mut c_char {
let original = s;
while *s != 0 {
s = s.offset(1);
}
while s != original {
s = s.offset(-1);
if *s == c as c_char {
// Input is const but output is mutable. WHY C, WHY DO THIS?
return s as *mut c_char;
}
}
ptr::null_mut()
}
#[no_mangle]
pub unsafe extern "C" fn strcasecmp(mut first: *const c_char, mut second: *const c_char) -> c_int {
while *first != 0 && *second != 0 {
let mut i = *first;
let mut j = *second;
if i >= b'A' as c_char && i <= b'Z' as c_char {
i += (b'a' - b'A') as c_char;
}
if j >= b'A' as c_char && j <= b'Z' as c_char {
j += (b'a' - b'A') as c_char;
}
if i != j {
return -1;
}
first = first.offset(1);
second = first.offset(1);
}
// Both strings ended at the same time too
(*first == *second) as c_int
}
#[no_mangle]
pub unsafe extern "C" fn strncasecmp(mut first: *const c_char, mut second: *const c_char, mut n: size_t) -> c_int {
while *first != 0 && *second != 0 && n > 0 {
let mut i = *first;
let mut j = *second;
if i >= b'A' as c_char && i <= b'Z' as c_char {
i += (b'a' - b'A') as c_char;
}
if j >= b'A' as c_char && j <= b'Z' as c_char {
j += (b'a' - b'A') as c_char;
}
if i != j {
return -1;
}
first = first.offset(1);
second = first.offset(1);
n -= 1;
}
// Both strings ended at the same time too
(n == 0 || *first == *second) as c_int
}
......@@ -5,17 +5,26 @@
extern crate platform;
use core::ptr;
use platform::types::*;
pub type in_addr_t = [u8; 4];
pub type in_port_t = u16;
pub type sa_family_t = u16;
pub type socklen_t = u32;
#[repr(C)]
pub struct sockaddr {
pub sa_family: sa_family_t,
pub sa_data: [c_char; 14],
data: [c_char; 14]
}
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;
#[no_mangle]
pub unsafe extern "C" fn accept(
socket: c_int,
......@@ -31,7 +40,7 @@ pub unsafe extern "C" fn bind(
address: *const sockaddr,
address_len: socklen_t,
) -> c_int {
unimplemented!();
platform::bind(socket, address as *const platform::sockaddr, address_len)
}
#[no_mangle]
......@@ -40,7 +49,7 @@ pub unsafe extern "C" fn connect(
address: *const sockaddr,
address_len: socklen_t,
) -> c_int {
unimplemented!();
platform::connect(socket, address as *const platform::sockaddr, address_len)
}
#[no_mangle]
......@@ -84,7 +93,7 @@ pub unsafe extern "C" fn recv(
length: size_t,
flags: c_int,
) -> ssize_t {
unimplemented!();
recvfrom(socket, buffer, length, flags, ptr::null_mut(), ptr::null_mut())
}
#[no_mangle]
......@@ -96,7 +105,7 @@ pub unsafe extern "C" fn recvfrom(
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> ssize_t {
unimplemented!();
platform::recvfrom(socket, buffer, length, flags, address as *mut platform::sockaddr, address_len)
}
#[no_mangle]
......@@ -106,11 +115,11 @@ pub unsafe extern "C" fn send(
length: size_t,
flags: c_int,
) -> ssize_t {
unimplemented!();
sendto(socket, message, length, flags, ptr::null(), 0)
}
#[no_mangle]
pub unsafe extern "C" fn sento(
pub unsafe extern "C" fn sendto(
socket: c_int,
message: *const c_void,
length: size_t,
......@@ -118,7 +127,7 @@ pub unsafe extern "C" fn sento(
dest_addr: *const sockaddr,
dest_len: socklen_t,
) -> ssize_t {
unimplemented!();
platform::sendto(socket, message, length, flags, dest_addr as *const platform::sockaddr, dest_len)
}
#[no_mangle]
......@@ -138,8 +147,8 @@ pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int {
}
#[no_mangle]
pub unsafe extern "C" fn socket(domain: c_int, _type: c_int, protocol: c_int) -> c_int {
unimplemented!();
pub unsafe extern "C" fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
platform::socket(domain, kind, protocol)
}
#[no_mangle]
......
......@@ -32,6 +32,7 @@
/setjmp
/sleep
/sprintf
/strings
/stdlib/a64l
/stdlib/bsearch
/stdlib/mktemp
......
......@@ -26,6 +26,7 @@ EXPECT_BINS=\
setjmp \
sleep \
sprintf \
strings \