blob: da9daf745864924ccc714195dce32cb005f43b51 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
use std::ffi::CString;
use std::io;
use std::os::raw::{c_char, c_int};
enum TeaclaveContextFilePermission {
Read,
Write,
}
/// This struct is a wrapped version of the `teaclave_*` C interfaces
/// and meant to provide a set of more convenient methods for Rust
/// `std::io::Read` and `std::io::Write` traits are implemented
/// for TeaclaveContextFile to support related traits
/// The protected file handlers need NOT to be closed manually
pub struct TeaclaveContextFile {
handle: i32,
permission: TeaclaveContextFilePermission,
}
pub struct TeaclaveContextFileError;
type Result<T> = std::result::Result<T, io::Error>;
impl io::Read for TeaclaveContextFile {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
match self.permission {
TeaclaveContextFilePermission::Write => Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"Can't read opened input",
)),
_ => {
let rv =
unsafe { teaclave_read_file(self.handle, buf.as_ptr() as _, buf.len() as _) };
if rv == -1 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"teaclave_read_file failed",
));
}
Ok(rv as _)
}
}
}
}
impl io::Write for TeaclaveContextFile {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
match self.permission {
TeaclaveContextFilePermission::Read => Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"Can't read opened input",
)),
_ => {
let rv =
unsafe { teaclave_write_file(self.handle, buf.as_ptr() as _, buf.len() as _) };
if rv == -1 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"teaclave_write_file failed",
));
}
Ok(rv as _)
}
}
}
fn flush(&mut self) -> Result<()> {
return Ok(());
}
}
impl TeaclaveContextFile {
/// A wrapped version of `teaclave_open_input`
pub fn open_input(fid: &str) -> Result<Self> {
let fid_owned = CString::new(fid).unwrap();
let fd = unsafe { teaclave_open_input(fid_owned.as_c_str().as_ptr() as _) };
if fd == -1 {
return Err(io::Error::new(
io::ErrorKind::Other,
"teaclave_open_input failed",
));
}
Ok(TeaclaveContextFile {
handle: fd,
permission: TeaclaveContextFilePermission::Read,
})
}
/// A wrapped version of `teaclave_create_output`
pub fn create_output(fid: &str) -> Result<Self> {
let fid_owned = CString::new(fid).unwrap();
let fd = unsafe { teaclave_create_output(fid_owned.as_c_str().as_ptr() as _) };
if fd == -1 {
return Err(io::Error::new(
io::ErrorKind::Other,
"teaclave_create_output failed",
));
}
Ok(TeaclaveContextFile {
handle: fd,
permission: TeaclaveContextFilePermission::Write,
})
}
}
impl std::ops::Drop for TeaclaveContextFile {
fn drop(&mut self) {
unsafe { teaclave_close_file(self.handle) };
}
}
extern "C" {
/// Close a file handler
///
/// # Arguments
///
/// * `fd` - file handler returned by `teaclave_open_input`
///
/// # Return
///
/// 0 if succeed, -1 otherwise
pub fn teaclave_close_file(fd: c_int) -> c_int;
/// Write content from a buffer to a file
///
/// # Arguments
///
/// * `fd` - file handler returned by `teaclave_open_input`
/// * `in_buf` - the pointer to the buffer holding content to write
/// * `buf_size` - the total size in bytes to read from the buffer and write to the file
///
/// # Return
///
/// bytes written to the file, -1 if error occurs
pub fn teaclave_write_file(fd: c_int, in_buf: *mut c_char, buf_size: c_int) -> c_int;
/// Read content from a file to a buffer
///
/// # Arguments
///
/// * `fd` - file handler returned by `teaclave_open_input`
/// * `out_buf` - the pointer to output buffer
/// * `buf_size` - the total size in bytes of the output buffer
///
/// # Return
///
/// bytes read from the file, -1 if error occurs
pub fn teaclave_read_file(fd: c_int, out_buf: *mut c_char, buf_size: c_int) -> c_int;
/// Create or open a protected file as output
///
/// # Arguments
///
/// * `fid` - the uid of the file, c string pointer
///
/// # Return
///
/// file handler, -1 if error occurs
pub fn teaclave_create_output(fid: *mut c_char) -> c_int;
/// Open a protected file as input
///
/// # Arguments
///
/// * `fid` - the uid of the file, c string pointer
///
/// # Return
///
/// file handler, -1 if error occurs
pub fn teaclave_open_input(fid: *mut c_char) -> c_int;
}