Add gettimeofday
This commit is contained in:
parent
1644159832
commit
d3009db10b
@ -14,5 +14,6 @@ enclave {
|
||||
untrusted {
|
||||
void ocall_print_string([in, string] const char* msg);
|
||||
int ocall_run_new_task(void);
|
||||
void ocall_gettimeofday([out] long* seconds, [out] long* microseconds);
|
||||
};
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "syscall_nr.h"
|
||||
|
||||
struct iovec;
|
||||
struct timeval;
|
||||
|
||||
#ifdef __cplusplus
|
||||
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_brk(void* addr);
|
||||
|
||||
extern int occlum_gettimeofday(struct timeval* tv/*, struct timezone* tz*/);
|
||||
|
||||
extern int occlum_unknown(int num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -32,6 +32,7 @@ mod process;
|
||||
mod syscall;
|
||||
mod vm;
|
||||
mod util;
|
||||
mod time;
|
||||
|
||||
use prelude::*;
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
use std::{ptr};
|
||||
use {std, fs, process, vm};
|
||||
use std::{ptr};
|
||||
use std::ffi::{CStr, CString};
|
||||
use fs::{off_t, FileDesc};
|
||||
use vm::{VMAreaFlags, VMResizeOptions};
|
||||
use process::{pid_t, ChildProcessFilter, FileAction};
|
||||
use time::{timeval_t};
|
||||
// Use the internal syscall wrappers from sgx_tstd
|
||||
//use std::libc_fs as fs;
|
||||
//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)
|
||||
-> Result<size_t, Error>
|
||||
{
|
||||
@ -244,6 +320,13 @@ fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> {
|
||||
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;
|
||||
|
||||
@ -414,82 +497,6 @@ pub extern "C" fn occlum_unknown(num: u32)
|
||||
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]
|
||||
pub extern "C" fn occlum_spawn(
|
||||
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);
|
||||
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:
|
||||
ret = occlum_unknown(num);
|
||||
break;
|
||||
|
27
src/libos/src/time/mod.rs
Normal file
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 <pwd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MAX_PATH FILENAME_MAX
|
||||
|
||||
@ -197,6 +198,13 @@ int ocall_run_new_task(void) {
|
||||
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 */
|
||||
int SGX_CDECL main(int argc, char *argv[])
|
||||
|
@ -1,7 +1,7 @@
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
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:%=%)
|
||||
RUN_TEST_SUITES := $(TEST_SUITES:%=test-%)
|
||||
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)
|
||||
|
4
test/time/Makefile
Normal file
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
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user