Add gettimeofday
This commit is contained in:
parent
1644159832
commit
d3009db10b
@ -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
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
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