summaryrefslogtreecommitdiff
path: root/runtime/ops/fs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/fs.rs')
-rw-r--r--runtime/ops/fs.rs508
1 files changed, 265 insertions, 243 deletions
diff --git a/runtime/ops/fs.rs b/runtime/ops/fs.rs
index b63ddfd69..1fc453e2b 100644
--- a/runtime/ops/fs.rs
+++ b/runtime/ops/fs.rs
@@ -394,11 +394,14 @@ async fn op_fsync_async(
fn op_fstat_sync(
state: &mut OpState,
rid: ResourceId,
-) -> Result<FsStat, AnyError> {
+ out_buf: &mut [u32],
+) -> Result<(), AnyError> {
let metadata = StdFileResource::with_file(state, rid, |std_file| {
std_file.metadata().map_err(AnyError::from)
})?;
- Ok(get_stat(metadata))
+ let stat = get_stat(metadata);
+ stat.write(out_buf);
+ Ok(())
}
#[op]
@@ -579,42 +582,36 @@ async fn op_mkdir_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ChmodArgs {
+#[op]
+fn op_chmod_sync(
+ state: &mut OpState,
path: String,
mode: u32,
-}
-
-#[op]
-fn op_chmod_sync(state: &mut OpState, args: ChmodArgs) -> Result<(), AnyError> {
- let path = Path::new(&args.path);
- let mode = args.mode & 0o777;
+) -> Result<(), AnyError> {
+ let path = Path::new(&path);
+ let mode = mode & 0o777;
state.borrow_mut::<Permissions>().write.check(path)?;
- debug!("op_chmod_sync {} {:o}", path.display(), mode);
raw_chmod(path, mode)
}
#[op]
async fn op_chmod_async(
state: Rc<RefCell<OpState>>,
- args: ChmodArgs,
+ path: String,
+ mode: u32,
) -> Result<(), AnyError> {
- let path = Path::new(&args.path).to_path_buf();
- let mode = args.mode & 0o777;
+ let path = Path::new(&path).to_path_buf();
+ let mode = mode & 0o777;
{
let mut state = state.borrow_mut();
state.borrow_mut::<Permissions>().write.check(&path)?;
}
- tokio::task::spawn_blocking(move || {
- debug!("op_chmod_async {} {:o}", path.display(), mode);
- raw_chmod(&path, mode)
- })
- .await
- .unwrap()
+ tokio::task::spawn_blocking(move || raw_chmod(&path, mode))
+ .await
+ .unwrap()
}
fn raw_chmod(path: &Path, _raw_mode: u32) -> Result<(), AnyError> {
@@ -637,30 +634,21 @@ fn raw_chmod(path: &Path, _raw_mode: u32) -> Result<(), AnyError> {
}
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ChownArgs {
+#[op]
+fn op_chown_sync(
+ state: &mut OpState,
path: String,
uid: Option<u32>,
gid: Option<u32>,
-}
-
-#[op]
-fn op_chown_sync(state: &mut OpState, args: ChownArgs) -> Result<(), AnyError> {
- let path = Path::new(&args.path).to_path_buf();
+) -> Result<(), AnyError> {
+ let path = Path::new(&path).to_path_buf();
state.borrow_mut::<Permissions>().write.check(&path)?;
- debug!(
- "op_chown_sync {} {:?} {:?}",
- path.display(),
- args.uid,
- args.gid,
- );
#[cfg(unix)]
{
use crate::errors::get_nix_error_class;
use nix::unistd::{chown, Gid, Uid};
- let nix_uid = args.uid.map(Uid::from_raw);
- let nix_gid = args.gid.map(Gid::from_raw);
+ let nix_uid = uid.map(Uid::from_raw);
+ let nix_gid = gid.map(Gid::from_raw);
chown(&path, nix_uid, nix_gid).map_err(|err| {
custom_error(
get_nix_error_class(&err),
@@ -679,9 +667,11 @@ fn op_chown_sync(state: &mut OpState, args: ChownArgs) -> Result<(), AnyError> {
#[op]
async fn op_chown_async(
state: Rc<RefCell<OpState>>,
- args: ChownArgs,
+ path: String,
+ uid: Option<u32>,
+ gid: Option<u32>,
) -> Result<(), AnyError> {
- let path = Path::new(&args.path).to_path_buf();
+ let path = Path::new(&path).to_path_buf();
{
let mut state = state.borrow_mut();
@@ -689,18 +679,12 @@ async fn op_chown_async(
}
tokio::task::spawn_blocking(move || {
- debug!(
- "op_chown_async {} {:?} {:?}",
- path.display(),
- args.uid,
- args.gid,
- );
#[cfg(unix)]
{
use crate::errors::get_nix_error_class;
use nix::unistd::{chown, Gid, Uid};
- let nix_uid = args.uid.map(Uid::from_raw);
- let nix_gid = args.gid.map(Gid::from_raw);
+ let nix_uid = uid.map(Uid::from_raw);
+ let nix_gid = gid.map(Gid::from_raw);
chown(&path, nix_uid, nix_gid).map_err(|err| {
custom_error(
get_nix_error_class(&err),
@@ -717,20 +701,13 @@ async fn op_chown_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct RemoveArgs {
- path: String,
- recursive: bool,
-}
-
#[op]
fn op_remove_sync(
state: &mut OpState,
- args: RemoveArgs,
+ path: String,
+ recursive: bool,
) -> Result<(), AnyError> {
- let path = PathBuf::from(&args.path);
- let recursive = args.recursive;
+ let path = PathBuf::from(&path);
state.borrow_mut::<Permissions>().write.check(&path)?;
@@ -742,7 +719,6 @@ fn op_remove_sync(
};
let metadata = std::fs::symlink_metadata(&path).map_err(err_mapper)?;
- debug!("op_remove_sync {} {}", path.display(), recursive);
let file_type = metadata.file_type();
if file_type.is_file() {
std::fs::remove_file(&path).map_err(err_mapper)?;
@@ -772,10 +748,10 @@ fn op_remove_sync(
#[op]
async fn op_remove_async(
state: Rc<RefCell<OpState>>,
- args: RemoveArgs,
+ path: String,
+ recursive: bool,
) -> Result<(), AnyError> {
- let path = PathBuf::from(&args.path);
- let recursive = args.recursive;
+ let path = PathBuf::from(&path);
{
let mut state = state.borrow_mut();
@@ -820,36 +796,29 @@ async fn op_remove_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CopyFileArgs {
- from: String,
- to: String,
-}
-
#[op]
fn op_copy_file_sync(
state: &mut OpState,
- args: CopyFileArgs,
+ from: String,
+ to: String,
) -> Result<(), AnyError> {
- let from = PathBuf::from(&args.from);
- let to = PathBuf::from(&args.to);
+ let from_path = PathBuf::from(&from);
+ let to_path = PathBuf::from(&to);
let permissions = state.borrow_mut::<Permissions>();
- permissions.read.check(&from)?;
- permissions.write.check(&to)?;
+ permissions.read.check(&from_path)?;
+ permissions.write.check(&to_path)?;
- debug!("op_copy_file_sync {} {}", from.display(), to.display());
// On *nix, Rust reports non-existent `from` as ErrorKind::InvalidInput
// See https://github.com/rust-lang/rust/issues/54800
// Once the issue is resolved, we should remove this workaround.
- if cfg!(unix) && !from.is_file() {
+ if cfg!(unix) && !from_path.is_file() {
return Err(custom_error(
"NotFound",
format!(
"File not found, copy '{}' -> '{}'",
- from.display(),
- to.display()
+ from_path.display(),
+ to_path.display()
),
));
}
@@ -857,21 +826,80 @@ fn op_copy_file_sync(
let err_mapper = |err: Error| {
Error::new(
err.kind(),
- format!("{}, copy '{}' -> '{}'", err, from.display(), to.display()),
+ format!(
+ "{}, copy '{}' -> '{}'",
+ err,
+ from_path.display(),
+ to_path.display()
+ ),
)
};
+
+ #[cfg(target_os = "macos")]
+ {
+ use libc::chmod;
+ use libc::clonefile;
+ use libc::stat;
+ use libc::unlink;
+ use std::ffi::CString;
+ use std::io::Read;
+
+ let from = CString::new(from).unwrap();
+ let to = CString::new(to).unwrap();
+
+ // SAFETY: `from` and `to` are valid C strings.
+ // std::fs::copy does open() + fcopyfile() on macOS. We try to use
+ // clonefile() instead, which is more efficient.
+ unsafe {
+ let mut st = std::mem::zeroed();
+ let ret = stat(from.as_ptr(), &mut st);
+ if ret != 0 {
+ return Err(err_mapper(Error::last_os_error()).into());
+ }
+
+ if st.st_size > 128 * 1024 {
+ // Try unlink. If it fails, we are going to try clonefile() anyway.
+ let _ = unlink(to.as_ptr());
+ // Matches rust stdlib behavior for io::copy.
+ // https://github.com/rust-lang/rust/blob/3fdd578d72a24d4efc2fe2ad18eec3b6ba72271e/library/std/src/sys/unix/fs.rs#L1613-L1616
+ if clonefile(from.as_ptr(), to.as_ptr(), 0) == 0 {
+ return Ok(());
+ }
+ } else {
+ // Do a regular copy. fcopyfile() is an overkill for < 128KB
+ // files.
+ let mut buf = [0u8; 128 * 1024];
+ let mut from_file =
+ std::fs::File::open(&from_path).map_err(err_mapper)?;
+ let mut to_file =
+ std::fs::File::create(&to_path).map_err(err_mapper)?;
+ loop {
+ let nread = from_file.read(&mut buf).map_err(err_mapper)?;
+ if nread == 0 {
+ break;
+ }
+ to_file.write_all(&buf[..nread]).map_err(err_mapper)?;
+ }
+ return Ok(());
+ }
+ }
+
+ // clonefile() failed, fall back to std::fs::copy().
+ }
+
// returns size of from as u64 (we ignore)
- std::fs::copy(&from, &to).map_err(err_mapper)?;
+ std::fs::copy(&from_path, &to_path).map_err(err_mapper)?;
Ok(())
}
#[op]
async fn op_copy_file_async(
state: Rc<RefCell<OpState>>,
- args: CopyFileArgs,
+ from: String,
+ to: String,
) -> Result<(), AnyError> {
- let from = PathBuf::from(&args.from);
- let to = PathBuf::from(&args.to);
+ let from = PathBuf::from(&from);
+ let to = PathBuf::from(&to);
{
let mut state = state.borrow_mut();
@@ -880,7 +908,6 @@ async fn op_copy_file_async(
permissions.write.check(&to)?;
}
- debug!("op_copy_file_async {} {}", from.display(), to.display());
tokio::task::spawn_blocking(move || {
// On *nix, Rust reports non-existent `from` as ErrorKind::InvalidInput
// See https://github.com/rust-lang/rust/issues/54800
@@ -910,40 +937,68 @@ async fn op_copy_file_async(
.unwrap()
}
-fn to_msec(maybe_time: Result<SystemTime, io::Error>) -> Option<u64> {
+fn to_msec(maybe_time: Result<SystemTime, io::Error>) -> (u64, bool) {
match maybe_time {
- Ok(time) => {
- let msec = time
+ Ok(time) => (
+ time
.duration_since(UNIX_EPOCH)
.map(|t| t.as_millis() as u64)
- .unwrap_or_else(|err| err.duration().as_millis() as u64);
- Some(msec)
- }
- Err(_) => None,
+ .unwrap_or_else(|err| err.duration().as_millis() as u64),
+ true,
+ ),
+ Err(_) => (0, false),
}
}
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct FsStat {
- is_file: bool,
- is_directory: bool,
- is_symlink: bool,
- size: u64,
- // In milliseconds, like JavaScript. Available on both Unix or Windows.
- mtime: Option<u64>,
- atime: Option<u64>,
- birthtime: Option<u64>,
- // Following are only valid under Unix.
- dev: u64,
- ino: u64,
- mode: u32,
- nlink: u64,
- uid: u32,
- gid: u32,
- rdev: u64,
- blksize: u64,
- blocks: u64,
+macro_rules! create_struct_writer {
+ (pub struct $name:ident { $($field:ident: $type:ty),* $(,)? }) => {
+ impl $name {
+ fn write(self, buf: &mut [u32]) {
+ let mut offset = 0;
+ $(
+ let value = self.$field as u64;
+ buf[offset] = value as u32;
+ buf[offset + 1] = (value >> 32) as u32;
+ #[allow(unused_assignments)]
+ {
+ offset += 2;
+ }
+ )*
+ }
+ }
+
+ #[derive(Serialize)]
+ #[serde(rename_all = "camelCase")]
+ struct $name {
+ $($field: $type),*
+ }
+ };
+}
+
+create_struct_writer! {
+ pub struct FsStat {
+ is_file: bool,
+ is_directory: bool,
+ is_symlink: bool,
+ size: u64,
+ // In milliseconds, like JavaScript. Available on both Unix or Windows.
+ mtime_set: bool,
+ mtime: u64,
+ atime_set: bool,
+ atime: u64,
+ birthtime_set: bool,
+ birthtime: u64,
+ // Following are only valid under Unix.
+ dev: u64,
+ ino: u64,
+ mode: u32,
+ nlink: u64,
+ uid: u32,
+ gid: u32,
+ rdev: u64,
+ blksize: u64,
+ blocks: u64,
+ }
}
#[inline(always)]
@@ -964,15 +1019,22 @@ fn get_stat(metadata: std::fs::Metadata) -> FsStat {
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
+ let (mtime, mtime_set) = to_msec(metadata.modified());
+ let (atime, atime_set) = to_msec(metadata.accessed());
+ let (birthtime, birthtime_set) = to_msec(metadata.created());
+
FsStat {
is_file: metadata.is_file(),
is_directory: metadata.is_dir(),
is_symlink: metadata.file_type().is_symlink(),
size: metadata.len(),
// In milliseconds, like JavaScript. Available on both Unix or Windows.
- mtime: to_msec(metadata.modified()),
- atime: to_msec(metadata.accessed()),
- birthtime: to_msec(metadata.created()),
+ mtime_set,
+ mtime,
+ atime_set,
+ atime,
+ birthtime_set,
+ birthtime,
// Following are only valid under Unix.
dev: usm!(dev),
ino: usm!(ino),
@@ -996,12 +1058,12 @@ pub struct StatArgs {
#[op]
fn op_stat_sync(
state: &mut OpState,
- args: StatArgs,
-) -> Result<FsStat, AnyError> {
- let path = PathBuf::from(&args.path);
- let lstat = args.lstat;
+ path: String,
+ lstat: bool,
+ out_buf: &mut [u32],
+) -> Result<(), AnyError> {
+ let path = PathBuf::from(&path);
state.borrow_mut::<Permissions>().read.check(&path)?;
- debug!("op_stat_sync {} {}", path.display(), lstat);
let err_mapper = |err: Error| {
Error::new(err.kind(), format!("{}, stat '{}'", err, path.display()))
};
@@ -1010,7 +1072,11 @@ fn op_stat_sync(
} else {
std::fs::metadata(&path).map_err(err_mapper)?
};
- Ok(get_stat(metadata))
+
+ let stat = get_stat(metadata);
+ stat.write(out_buf);
+
+ Ok(())
}
#[op]
@@ -1185,26 +1251,20 @@ async fn op_read_dir_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct RenameArgs {
- oldpath: String,
- newpath: String,
-}
-
#[op]
fn op_rename_sync(
state: &mut OpState,
- args: RenameArgs,
+ oldpath: String,
+ newpath: String,
) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
let permissions = state.borrow_mut::<Permissions>();
permissions.read.check(&oldpath)?;
permissions.write.check(&oldpath)?;
permissions.write.check(&newpath)?;
- debug!("op_rename_sync {} {}", oldpath.display(), newpath.display());
+
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1223,10 +1283,11 @@ fn op_rename_sync(
#[op]
async fn op_rename_async(
state: Rc<RefCell<OpState>>,
- args: RenameArgs,
+ oldpath: String,
+ newpath: String,
) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<Permissions>();
@@ -1235,11 +1296,6 @@ async fn op_rename_async(
permissions.write.check(&newpath)?;
}
tokio::task::spawn_blocking(move || {
- debug!(
- "op_rename_async {} {}",
- oldpath.display(),
- newpath.display()
- );
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1258,17 +1314,14 @@ async fn op_rename_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LinkArgs {
+#[op]
+fn op_link_sync(
+ state: &mut OpState,
oldpath: String,
newpath: String,
-}
-
-#[op]
-fn op_link_sync(state: &mut OpState, args: LinkArgs) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+) -> Result<(), AnyError> {
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
let permissions = state.borrow_mut::<Permissions>();
permissions.read.check(&oldpath)?;
@@ -1276,7 +1329,6 @@ fn op_link_sync(state: &mut OpState, args: LinkArgs) -> Result<(), AnyError> {
permissions.read.check(&newpath)?;
permissions.write.check(&newpath)?;
- debug!("op_link_sync {} {}", oldpath.display(), newpath.display());
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1295,10 +1347,11 @@ fn op_link_sync(state: &mut OpState, args: LinkArgs) -> Result<(), AnyError> {
#[op]
async fn op_link_async(
state: Rc<RefCell<OpState>>,
- args: LinkArgs,
+ oldpath: String,
+ newpath: String,
) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
{
let mut state = state.borrow_mut();
@@ -1310,7 +1363,6 @@ async fn op_link_async(
}
tokio::task::spawn_blocking(move || {
- debug!("op_link_async {} {}", oldpath.display(), newpath.display());
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1329,38 +1381,19 @@ async fn op_link_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SymlinkArgs {
- oldpath: String,
- newpath: String,
- #[cfg(not(unix))]
- options: Option<SymlinkOptions>,
-}
-
-#[cfg(not(unix))]
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SymlinkOptions {
- _type: String,
-}
-
#[op]
fn op_symlink_sync(
state: &mut OpState,
- args: SymlinkArgs,
+ oldpath: String,
+ newpath: String,
+ _type: Option<String>,
) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
state.borrow_mut::<Permissions>().write.check_all()?;
state.borrow_mut::<Permissions>().read.check_all()?;
- debug!(
- "op_symlink_sync {} {}",
- oldpath.display(),
- newpath.display()
- );
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1382,8 +1415,8 @@ fn op_symlink_sync(
{
use std::os::windows::fs::{symlink_dir, symlink_file};
- match args.options {
- Some(options) => match options._type.as_ref() {
+ match _type {
+ Some(ty) => match ty.as_ref() {
"file" => symlink_file(&oldpath, &newpath).map_err(err_mapper)?,
"dir" => symlink_dir(&oldpath, &newpath).map_err(err_mapper)?,
_ => return Err(type_error("unsupported type")),
@@ -1409,10 +1442,12 @@ fn op_symlink_sync(
#[op]
async fn op_symlink_async(
state: Rc<RefCell<OpState>>,
- args: SymlinkArgs,
+ oldpath: String,
+ newpath: String,
+ _type: Option<String>,
) -> Result<(), AnyError> {
- let oldpath = PathBuf::from(&args.oldpath);
- let newpath = PathBuf::from(&args.newpath);
+ let oldpath = PathBuf::from(&oldpath);
+ let newpath = PathBuf::from(&newpath);
{
let mut state = state.borrow_mut();
@@ -1421,7 +1456,6 @@ async fn op_symlink_async(
}
tokio::task::spawn_blocking(move || {
- debug!("op_symlink_async {} {}", oldpath.display(), newpath.display());
let err_mapper = |err: Error| {
Error::new(
err.kind(),
@@ -1443,8 +1477,8 @@ async fn op_symlink_async(
{
use std::os::windows::fs::{symlink_dir, symlink_file};
- match args.options {
- Some(options) => match options._type.as_ref() {
+ match _type {
+ Some(ty) => match ty.as_ref() {
"file" => symlink_file(&oldpath, &newpath).map_err(err_mapper)?,
"dir" => symlink_dir(&oldpath, &newpath).map_err(err_mapper)?,
_ => return Err(type_error("unsupported type")),
@@ -1521,20 +1555,13 @@ async fn op_read_link_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct FtruncateArgs {
- rid: ResourceId,
- len: i32,
-}
-
#[op]
fn op_ftruncate_sync(
state: &mut OpState,
- args: FtruncateArgs,
+ rid: u32,
+ len: i32,
) -> Result<(), AnyError> {
- let rid = args.rid;
- let len = args.len as u64;
+ let len = len as u64;
StdFileResource::with_file(state, rid, |std_file| {
std_file.set_len(len).map_err(AnyError::from)
})?;
@@ -1544,10 +1571,10 @@ fn op_ftruncate_sync(
#[op]
async fn op_ftruncate_async(
state: Rc<RefCell<OpState>>,
- args: FtruncateArgs,
+ rid: ResourceId,
+ len: i32,
) -> Result<(), AnyError> {
- let rid = args.rid;
- let len = args.len as u64;
+ let len = len as u64;
StdFileResource::with_file_blocking_task(state, rid, move |std_file| {
std_file.set_len(len)?;
@@ -1556,20 +1583,13 @@ async fn op_ftruncate_async(
.await
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct TruncateArgs {
- path: String,
- len: u64,
-}
-
#[op]
fn op_truncate_sync(
state: &mut OpState,
- args: TruncateArgs,
+ path: String,
+ len: u64,
) -> Result<(), AnyError> {
- let path = PathBuf::from(&args.path);
- let len = args.len;
+ let path = PathBuf::from(&path);
state.borrow_mut::<Permissions>().write.check(&path)?;
@@ -1591,10 +1611,11 @@ fn op_truncate_sync(
#[op]
async fn op_truncate_async(
state: Rc<RefCell<OpState>>,
- args: TruncateArgs,
+ path: String,
+ len: u64,
) -> Result<(), AnyError> {
- let path = PathBuf::from(&args.path);
- let len = args.len;
+ let path = PathBuf::from(&path);
+
{
let mut state = state.borrow_mut();
state.borrow_mut::<Permissions>().write.check(&path)?;
@@ -1797,23 +1818,18 @@ async fn op_make_temp_file_async(
.unwrap()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct FutimeArgs {
- rid: ResourceId,
- atime: (i64, u32),
- mtime: (i64, u32),
-}
-
#[op]
fn op_futime_sync(
state: &mut OpState,
- args: FutimeArgs,
+ rid: ResourceId,
+ atime_secs: i64,
+ atime_nanos: u32,
+ mtime_secs: i64,
+ mtime_nanos: u32,
) -> Result<(), AnyError> {
super::check_unstable(state, "Deno.futimeSync");
- let rid = args.rid;
- let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
- let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
+ let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos);
+ let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos);
StdFileResource::with_file(state, rid, |std_file| {
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
@@ -1826,12 +1842,15 @@ fn op_futime_sync(
#[op]
async fn op_futime_async(
state: Rc<RefCell<OpState>>,
- args: FutimeArgs,
+ rid: ResourceId,
+ atime_secs: i64,
+ atime_nanos: u32,
+ mtime_secs: i64,
+ mtime_nanos: u32,
) -> Result<(), AnyError> {
super::check_unstable2(&state, "Deno.futime");
- let rid = args.rid;
- let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
- let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
+ let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos);
+ let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos);
StdFileResource::with_file_blocking_task(state, rid, move |std_file| {
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))?;
@@ -1840,21 +1859,20 @@ async fn op_futime_async(
.await
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct UtimeArgs {
- path: String,
- atime: (i64, u32),
- mtime: (i64, u32),
-}
-
#[op]
-fn op_utime_sync(state: &mut OpState, args: UtimeArgs) -> Result<(), AnyError> {
+fn op_utime_sync(
+ state: &mut OpState,
+ path: String,
+ atime_secs: i64,
+ atime_nanos: u32,
+ mtime_secs: i64,
+ mtime_nanos: u32,
+) -> Result<(), AnyError> {
super::check_unstable(state, "Deno.utime");
- let path = PathBuf::from(&args.path);
- let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
- let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
+ let path = PathBuf::from(&path);
+ let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos);
+ let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos);
state.borrow_mut::<Permissions>().write.check(&path)?;
filetime::set_file_times(&path, atime, mtime).map_err(|err| {
@@ -1866,13 +1884,17 @@ fn op_utime_sync(state: &mut OpState, args: UtimeArgs) -> Result<(), AnyError> {
#[op]
async fn op_utime_async(
state: Rc<RefCell<OpState>>,
- args: UtimeArgs,
+ path: String,
+ atime_secs: i64,
+ atime_nanos: u32,
+ mtime_secs: i64,
+ mtime_nanos: u32,
) -> Result<(), AnyError> {
super::check_unstable(&state.borrow(), "Deno.utime");
- let path = PathBuf::from(&args.path);
- let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
- let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
+ let path = PathBuf::from(&path);
+ let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos);
+ let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos);
state
.borrow_mut()