Skip to content

Commit 6b567f4

Browse files
committed
fix(library/std sys::fs): fix rename(), copy(), rmdir(), and remove_dir_all() for safaos
1 parent 871a681 commit 6b567f4

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

library/std/src/sys/fs/safaos.rs

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::ffi::{OsStr, OsString};
2-
use crate::fmt;
32
use crate::hash::Hash;
43
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
54
use crate::io::{Read, Seek, Write};
65
use crate::path::{Path, PathBuf};
76
use crate::sys::resources::{DirIterResource, FileDesc, FileResource};
87
use crate::sys::time::SystemTime;
98
use crate::sys::{unsupported, unsupported_err};
9+
use crate::sys_common::ignore_notfound;
10+
use crate::{fmt, fs};
1011
use safa_api::errors::ErrorStatus;
1112
use safa_api::raw;
1213
use safa_api::raw::io::FSObjectType;
@@ -365,6 +366,8 @@ pub fn unlink(p: &Path) -> io::Result<()> {
365366

366367
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
367368
let old_str = path_to_str!(old);
369+
let new_str = path_to_str!(new);
370+
368371
let old_attrs = syscalls::fs::getdirentry(old_str)?;
369372
// TODO: implement native rename syscall
370373
match old_attrs.attrs.kind {
@@ -374,13 +377,25 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
374377
Ok(())
375378
}
376379
FSObjectType::Directory => {
380+
// create the new directory if it doesn't exist
381+
if let Err(e) = syscalls::fs::createdir(new_str)
382+
&& e != ErrorStatus::AlreadyExists
383+
{
384+
return Err(e.into());
385+
}
386+
377387
for entry in crate::fs::read_dir(old)? {
378388
let entry = entry?;
379-
let old_path = entry.path();
389+
let entry_name = entry.file_name();
390+
// special cases for '.' and '..' to avoid infinite recursion
391+
if entry_name.as_encoded_bytes() == b"." || entry_name.as_encoded_bytes() == b".." {
392+
continue;
393+
}
394+
395+
let old_entry_path = entry.path();
380396

381-
let new_path = new.join(entry.file_name());
382-
rename(&old_path, &new_path)?;
383-
syscalls::fs::remove_path(path_to_str!(old_path))?;
397+
let new_entry_path = new.join(entry_name);
398+
rename(&old_entry_path, &new_entry_path)?;
384399
}
385400

386401
syscalls::fs::remove_path(old_str)?;
@@ -405,7 +420,31 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
405420
}
406421

407422
pub fn remove_dir_all(path: &Path) -> io::Result<()> {
408-
super::common::remove_dir_all(path)
423+
for child in crate::fs::read_dir(path)? {
424+
let result: io::Result<()> = try {
425+
let child = child?;
426+
let name = child.file_name();
427+
// special cases for '.' and '..' to avoid infinite recursion
428+
if name.as_encoded_bytes() == b"." || name.as_encoded_bytes() == b".." {
429+
continue;
430+
}
431+
432+
let path = child.path();
433+
434+
if child.file_type()?.is_dir() {
435+
remove_dir_all(&path)?;
436+
} else {
437+
fs::remove_file(&path)?;
438+
}
439+
};
440+
// ignore internal NotFound errors to prevent race conditions
441+
if let Err(err) = &result
442+
&& err.kind() != io::ErrorKind::NotFound
443+
{
444+
return result;
445+
}
446+
}
447+
ignore_notfound(fs::remove_dir(path))
409448
}
410449

411450
pub fn exists(path: &Path) -> io::Result<bool> {
@@ -446,5 +485,14 @@ pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
446485
}
447486

448487
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
449-
super::common::copy(from, to)
488+
let mut reader = fs::File::open(from)?;
489+
let metadata = reader.metadata()?;
490+
491+
if !metadata.is_file() {
492+
return Err(ErrorStatus::NotAFile.into());
493+
}
494+
495+
let mut writer = fs::File::create(to)?;
496+
let ret = io::copy(&mut reader, &mut writer)?;
497+
Ok(ret)
450498
}

0 commit comments

Comments
 (0)