Add gettimeofday

This commit is contained in:
Tate, Hongliang Tian 2019-01-07 22:57:14 +08:00
parent 1644159832
commit d3009db10b
10 changed files with 158 additions and 78 deletions

@ -14,5 +14,6 @@ enclave {
untrusted { untrusted {
void ocall_print_string([in, string] const char* msg); void ocall_print_string([in, string] const char* msg);
int ocall_run_new_task(void); int ocall_run_new_task(void);
void ocall_gettimeofday([out] long* seconds, [out] long* microseconds);
}; };
}; };

@ -5,6 +5,7 @@
#include "syscall_nr.h" #include "syscall_nr.h"
struct iovec; struct iovec;
struct timeval;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -38,6 +39,8 @@ extern int occlum_munmap(void *addr, size_t length);
extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address); extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address);
extern void* occlum_brk(void* addr); extern void* occlum_brk(void* addr);
extern int occlum_gettimeofday(struct timeval* tv/*, struct timezone* tz*/);
extern int occlum_unknown(int num); extern int occlum_unknown(int num);
#ifdef __cplusplus #ifdef __cplusplus

@ -32,6 +32,7 @@ mod process;
mod syscall; mod syscall;
mod vm; mod vm;
mod util; mod util;
mod time;
use prelude::*; use prelude::*;

@ -1,11 +1,12 @@
use super::*; use super::*;
use prelude::*; use prelude::*;
use std::{ptr};
use {std, fs, process, vm}; use {std, fs, process, vm};
use std::{ptr};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use fs::{off_t, FileDesc}; use fs::{off_t, FileDesc};
use vm::{VMAreaFlags, VMResizeOptions}; use vm::{VMAreaFlags, VMResizeOptions};
use process::{pid_t, ChildProcessFilter, FileAction}; use process::{pid_t, ChildProcessFilter, FileAction};
use time::{timeval_t};
// Use the internal syscall wrappers from sgx_tstd // Use the internal syscall wrappers from sgx_tstd
//use std::libc_fs as fs; //use std::libc_fs as fs;
//use std::libc_io as io; //use std::libc_io as io;
@ -50,6 +51,81 @@ fn clone_cstrings_from_user_safely(user_ptr: *const *const c_char)
} }
/*
* This Rust-version of fdop correspond to the C-version one in Occlum.
* See <path_to_musl_libc>/src/process/fdop.h.
*/
const FDOP_CLOSE : u32 = 1;
const FDOP_DUP2 : u32 = 2;
const FDOP_OPEN : u32 = 3;
#[repr(C)]
#[derive(Debug)]
pub struct FdOp {
// We actually switch the prev and next fields in the libc definition.
prev: *const FdOp,
next: *const FdOp,
cmd: u32,
fd: u32,
srcfd: u32,
oflag: u32,
mode: u32,
path: *const u8,
}
fn clone_file_actions_from_user_safely(fdop_ptr: *const FdOp)
-> Result<Vec<FileAction>, Error>
{
let mut file_actions = Vec::new();
let mut fdop_ptr = fdop_ptr;
while fdop_ptr != ptr::null() {
check_ptr_from_user(fdop_ptr)?;
let fdop = unsafe { &*fdop_ptr };
let file_action = match fdop.cmd {
FDOP_CLOSE => {
FileAction::Close(fdop.fd)
},
FDOP_DUP2 => {
FileAction::Dup2(fdop.srcfd, fdop.fd)
},
FDOP_OPEN => {
return errno!(EINVAL, "Not implemented");
},
_ => {
return errno!(EINVAL, "Unknown file action command");
},
};
file_actions.push(file_action);
fdop_ptr = fdop.next;
}
Ok(file_actions)
}
fn do_spawn(child_pid_ptr: *mut c_uint,
path: *const c_char,
argv: *const *const c_char,
envp: *const *const c_char,
fdop_list: *const FdOp,
)
-> Result<(), Error>
{
check_mut_ptr_from_user(child_pid_ptr)?;
let path = clone_cstring_from_user_safely(path)?;
let argv = clone_cstrings_from_user_safely(argv)?;
let envp = clone_cstrings_from_user_safely(envp)?;
let file_actions = clone_file_actions_from_user_safely(fdop_list)?;
let parent = process::get_current();
let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?;
unsafe { *child_pid_ptr = child_pid };
Ok(())
}
fn do_read(fd: c_int, buf: *mut c_void, size: size_t) fn do_read(fd: c_int, buf: *mut c_void, size: size_t)
-> Result<size_t, Error> -> Result<size_t, Error>
{ {
@ -244,6 +320,13 @@ fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<(), Error> {
check_mut_ptr_from_user(tv_u)?;
let tv = time::do_gettimeofday();
unsafe { *tv_u = tv; }
Ok(())
}
const MAP_FAILED : *const c_void = ((-1) as i64) as *const c_void; const MAP_FAILED : *const c_void = ((-1) as i64) as *const c_void;
@ -414,82 +497,6 @@ pub extern "C" fn occlum_unknown(num: u32)
println!("[WARNING] Unknown syscall (num = {})", num); println!("[WARNING] Unknown syscall (num = {})", num);
} }
/*
* This Rust-version of fdop correspond to the C-version one in Occlum.
* See <path_to_musl_libc>/src/process/fdop.h.
*/
const FDOP_CLOSE : u32 = 1;
const FDOP_DUP2 : u32 = 2;
const FDOP_OPEN : u32 = 3;
#[repr(C)]
#[derive(Debug)]
pub struct FdOp {
// We actually switch the prev and next fields in the libc definition.
prev: *const FdOp,
next: *const FdOp,
cmd: u32,
fd: u32,
srcfd: u32,
oflag: u32,
mode: u32,
path: *const u8,
}
fn clone_file_actions_from_user_safely(fdop_ptr: *const FdOp)
-> Result<Vec<FileAction>, Error>
{
let mut file_actions = Vec::new();
let mut fdop_ptr = fdop_ptr;
while fdop_ptr != ptr::null() {
check_ptr_from_user(fdop_ptr)?;
let fdop = unsafe { &*fdop_ptr };
let file_action = match fdop.cmd {
FDOP_CLOSE => {
FileAction::Close(fdop.fd)
},
FDOP_DUP2 => {
FileAction::Dup2(fdop.srcfd, fdop.fd)
},
FDOP_OPEN => {
return errno!(EINVAL, "Not implemented");
},
_ => {
return errno!(EINVAL, "Unknown file action command");
},
};
file_actions.push(file_action);
fdop_ptr = fdop.next;
}
Ok(file_actions)
}
fn do_spawn(child_pid_ptr: *mut c_uint,
path: *const c_char,
argv: *const *const c_char,
envp: *const *const c_char,
fdop_list: *const FdOp,
)
-> Result<(), Error>
{
check_mut_ptr_from_user(child_pid_ptr)?;
let path = clone_cstring_from_user_safely(path)?;
let argv = clone_cstrings_from_user_safely(argv)?;
let envp = clone_cstrings_from_user_safely(envp)?;
let file_actions = clone_file_actions_from_user_safely(fdop_list)?;
let parent = process::get_current();
let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?;
unsafe { *child_pid_ptr = child_pid };
Ok(())
}
#[no_mangle] #[no_mangle]
pub extern "C" fn occlum_spawn( pub extern "C" fn occlum_spawn(
child_pid: *mut c_uint, path: *const c_char, child_pid: *mut c_uint, path: *const c_char,
@ -562,3 +569,17 @@ pub extern "C" fn occlum_dup3(old_fd: c_int, new_fd: c_int, flags: c_int)
} }
} }
} }
// TODO: handle tz: timezone_t
#[no_mangle]
pub extern "C" fn occlum_gettimeofday(tv: *mut timeval_t) -> c_int
{
match do_gettimeofday(tv) {
Ok(()) => {
0
}
Err(e) => {
e.errno.as_retval()
}
}
}

@ -144,6 +144,12 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long
ret = (long) occlum_dup3(old_fd, new_fd, flags); ret = (long) occlum_dup3(old_fd, new_fd, flags);
break; break;
} }
case SYS_gettimeofday: {
DECL_SYSCALL_ARG(struct timeval*, tv, arg0);
//DECL_SYSCALL_ARG(struct timezone*, tz, arg1);
ret = (long) occlum_gettimeofday(tv/*, tz*/);
break;
}
default: default:
ret = occlum_unknown(num); ret = occlum_unknown(num);
break; break;

27
src/libos/src/time/mod.rs Normal file

@ -0,0 +1,27 @@
use super::*;
#[allow(non_camel_case_types)]
pub type time_t = i64;
#[allow(non_camel_case_types)]
pub type suseconds_t = i64;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct timeval_t {
sec: time_t,
usec: suseconds_t,
}
pub fn do_gettimeofday() -> timeval_t {
let mut tv : timeval_t = Default::default();
unsafe {
ocall_gettimeofday(&mut tv.sec as *mut time_t,
&mut tv.usec as *mut suseconds_t);
}
tv
}
extern {
fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t;
}

@ -4,6 +4,7 @@
#include <unistd.h> #include <unistd.h>
#include <pwd.h> #include <pwd.h>
#include <sys/time.h>
#define MAX_PATH FILENAME_MAX #define MAX_PATH FILENAME_MAX
@ -197,6 +198,13 @@ int ocall_run_new_task(void) {
return ret; return ret;
} }
void ocall_gettimeofday(long* seconds, long* microseconds) {
struct timeval tv;
gettimeofday(&tv, NULL);
*seconds = tv.tv_sec;
*microseconds = tv.tv_usec;
}
/* Application entry */ /* Application entry */
int SGX_CDECL main(int argc, char *argv[]) int SGX_CDECL main(int argc, char *argv[])

@ -1,7 +1,7 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PROJECT_DIR := $(realpath $(CUR_DIR)/../) PROJECT_DIR := $(realpath $(CUR_DIR)/../)
TEST_SUITES := empty hello_world malloc file getpid spawn pipe TEST_SUITES := empty hello_world malloc file getpid spawn pipe time
BUILD_TEST_SUITES := $(TEST_SUITES:%=%) BUILD_TEST_SUITES := $(TEST_SUITES:%=%)
RUN_TEST_SUITES := $(TEST_SUITES:%=test-%) RUN_TEST_SUITES := $(TEST_SUITES:%=test-%)
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)

4
test/time/Makefile Normal file

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

9
test/time/main.c Normal file

@ -0,0 +1,9 @@
#include <sys/time.h>
#include <stdio.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("sec = %lu, usec = %lu\n", tv.tv_sec, tv.tv_usec);
return 0;
}