Implement a helper for converting &str to CString. (#154)
This commit implements a simple helper for converting `&str` to `CString` and mapping to the appropriate WASI error. It also adds a `path_cstring` helper method in `PathGet` where the conversion was used the most. Fixes #104.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use crate::{Error, Result};
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CString;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
|
||||
@@ -9,3 +10,7 @@ pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
|
||||
.try_into()
|
||||
.map_err(Into::into) // u128 doesn't fit into u64
|
||||
}
|
||||
|
||||
pub(crate) fn str_to_cstring(s: &str) -> Result<CString> {
|
||||
CString::new(s.as_bytes()).map_err(|_| Error::EILSEQ)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
use crate::helpers::str_to_cstring;
|
||||
use crate::sys::host_impl;
|
||||
use crate::sys::hostcalls_impl::fs_helpers::*;
|
||||
use crate::{host, Error, Result};
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::path::{Component, Path};
|
||||
|
||||
@@ -19,6 +21,10 @@ impl PathGet {
|
||||
pub(crate) fn path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub(crate) fn path_cstring(&self) -> Result<CString> {
|
||||
str_to_cstring(&self.path)
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizes a path to ensure that the target path is located under the directory provided.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::osfile::OsFile;
|
||||
use crate::helpers::str_to_cstring;
|
||||
use crate::hostcalls_impl::PathGet;
|
||||
use crate::sys::host_impl;
|
||||
use crate::{host, Error, Result};
|
||||
use nix::libc::{self, c_long, c_void};
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::os::unix::prelude::AsRawFd;
|
||||
|
||||
@@ -12,7 +12,7 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
use nix::errno;
|
||||
use nix::libc::unlinkat;
|
||||
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let path_cstr = resolved.path_cstring()?;
|
||||
|
||||
// nix doesn't expose unlinkat() yet
|
||||
match unsafe { unlinkat(resolved.dirfd().as_raw_fd(), path_cstr.as_ptr(), 0) } {
|
||||
@@ -52,8 +52,8 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
use nix::{errno::Errno, fcntl::AtFlags, libc::symlinkat, sys::stat::fstatat};
|
||||
|
||||
let old_path_cstr = CString::new(old_path.as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let old_path_cstr = str_to_cstring(old_path)?;
|
||||
let new_path_cstr = resolved.path_cstring()?;
|
||||
|
||||
log::debug!("path_symlink old_path = {:?}", old_path);
|
||||
log::debug!("path_symlink resolved = {:?}", resolved);
|
||||
@@ -93,8 +93,8 @@ pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
|
||||
pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
use nix::{errno::Errno, fcntl::AtFlags, libc::renameat, sys::stat::fstatat};
|
||||
let old_path_cstr = CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr = CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let old_path_cstr = resolved_old.path_cstring()?;
|
||||
let new_path_cstr = resolved_new.path_cstring()?;
|
||||
|
||||
let res = unsafe {
|
||||
renameat(
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::sys::host_impl;
|
||||
use crate::{host, Error, Result};
|
||||
use nix::libc;
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CString;
|
||||
use std::fs::{File, Metadata};
|
||||
use std::os::unix::fs::FileExt;
|
||||
use std::os::unix::prelude::{AsRawFd, FromRawFd};
|
||||
@@ -58,7 +57,7 @@ pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: host::__wasi_fdflags_t) ->
|
||||
|
||||
pub(crate) fn path_create_directory(resolved: PathGet) -> Result<()> {
|
||||
use nix::libc::mkdirat;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let path_cstr = resolved.path_cstring()?;
|
||||
// nix doesn't expose mkdirat() yet
|
||||
match unsafe { mkdirat(resolved.dirfd().as_raw_fd(), path_cstr.as_ptr(), 0o777) } {
|
||||
0 => Ok(()),
|
||||
@@ -68,8 +67,8 @@ pub(crate) fn path_create_directory(resolved: PathGet) -> Result<()> {
|
||||
|
||||
pub(crate) fn path_link(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
use nix::libc::linkat;
|
||||
let old_path_cstr = CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr = CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let old_path_cstr = resolved_old.path_cstring()?;
|
||||
let new_path_cstr = resolved_new.path_cstring()?;
|
||||
|
||||
// Not setting AT_SYMLINK_FOLLOW fails on most filesystems
|
||||
let atflags = libc::AT_SYMLINK_FOLLOW;
|
||||
@@ -184,7 +183,7 @@ pub(crate) fn path_open(
|
||||
|
||||
pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize> {
|
||||
use nix::errno::Errno;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let path_cstr = resolved.path_cstring()?;
|
||||
|
||||
// Linux requires that the buffer size is positive, whereas POSIX does not.
|
||||
// Use a fake buffer to store the results if the size is zero.
|
||||
@@ -341,7 +340,7 @@ pub(crate) fn path_remove_directory(resolved: PathGet) -> Result<()> {
|
||||
use nix::errno;
|
||||
use nix::libc::{unlinkat, AT_REMOVEDIR};
|
||||
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let path_cstr = resolved.path_cstring()?;
|
||||
|
||||
// nix doesn't expose unlinkat() yet
|
||||
match unsafe {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::osfile::OsFile;
|
||||
use crate::helpers::str_to_cstring;
|
||||
use crate::hostcalls_impl::PathGet;
|
||||
use crate::sys::host_impl;
|
||||
use crate::{host, Error, Result};
|
||||
@@ -13,7 +14,7 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
use nix::errno;
|
||||
use nix::libc::unlinkat;
|
||||
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let path_cstr = resolved.path_cstring()?;
|
||||
|
||||
// nix doesn't expose unlinkat() yet
|
||||
let res = unsafe { unlinkat(resolved.dirfd().as_raw_fd(), path_cstr.as_ptr(), 0) };
|
||||
@@ -27,8 +28,8 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
use nix::{errno::Errno, libc::symlinkat};
|
||||
|
||||
let old_path_cstr = CString::new(old_path.as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let old_path_cstr = str_to_cstring(old_path)?;
|
||||
let new_path_cstr = resolved.path_cstring()?;
|
||||
|
||||
log::debug!("path_symlink old_path = {:?}", old_path);
|
||||
log::debug!("path_symlink resolved = {:?}", resolved);
|
||||
@@ -49,8 +50,8 @@ pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
|
||||
pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
use nix::libc::renameat;
|
||||
let old_path_cstr = CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr = CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let old_path_cstr = resolved_old.path_cstring()?;
|
||||
let new_path_cstr = resolved_new.path_cstring()?;
|
||||
|
||||
let res = unsafe {
|
||||
renameat(
|
||||
|
||||
@@ -14,7 +14,6 @@ lazy_static! {
|
||||
static ref START_MONOTONIC: Instant = Instant::now();
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__wasi_timestamp_t> {
|
||||
unimplemented!("clock_res_get")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user