@@ -17,7 +17,58 @@ use crate::sys::time::SystemTime;
1717use crate :: sys:: unsupported;
1818use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
1919
20- pub use crate :: sys_common:: fs:: try_exists;
20+ pub ( crate ) mod fs_imp {
21+ pub ( crate ) use super :: {
22+ DirBuilder , DirEntry , File , FileAttr , FilePermissions , FileTimes , FileType , OpenOptions ,
23+ ReadDir ,
24+ } ;
25+ use crate :: io;
26+ use crate :: path:: AsPath ;
27+ use crate :: path:: PathBuf ;
28+
29+ pub ( crate ) fn remove_file < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
30+ path. with_native_path ( super :: unlink)
31+ }
32+ pub ( crate ) fn symlink_metadata < P : AsPath > ( path : P ) -> io:: Result < FileAttr > {
33+ path. with_native_path ( |path| super :: lstat ( path) )
34+ }
35+ pub ( crate ) fn metadata < P : AsPath > ( path : P ) -> io:: Result < FileAttr > {
36+ path. with_native_path ( |path| super :: stat ( path) )
37+ }
38+ pub ( crate ) fn rename < P : AsPath , Q : AsPath > ( from : P , to : Q ) -> io:: Result < ( ) > {
39+ to. with_path ( |to| from. with_native_path ( |from| super :: rename ( from, to) ) )
40+ }
41+ pub ( crate ) fn hard_link < P : AsPath , Q : AsPath > ( original : P , link : Q ) -> io:: Result < ( ) > {
42+ link. with_path ( |link| original. with_native_path ( |original| super :: link ( original, link) ) )
43+ }
44+ pub ( crate ) fn soft_link < P : AsPath , Q : AsPath > ( original : P , link : Q ) -> io:: Result < ( ) > {
45+ original. with_path ( |original| link. with_native_path ( |link| super :: symlink ( original, link) ) )
46+ }
47+ pub ( crate ) fn remove_dir < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
48+ path. with_native_path ( super :: rmdir)
49+ }
50+ pub ( crate ) fn read_dir < P : AsPath > ( path : P ) -> io:: Result < ReadDir > {
51+ path. with_path ( super :: readdir)
52+ }
53+ pub ( crate ) fn set_permissions < P : AsPath > ( path : P , perms : FilePermissions ) -> io:: Result < ( ) > {
54+ path. with_path ( |path| super :: set_perm ( path, perms) )
55+ }
56+ pub ( crate ) fn copy < P : AsPath , Q : AsPath > ( from : P , to : Q ) -> io:: Result < u64 > {
57+ from. with_path ( |from| to. with_path ( |to| super :: copy ( from, to) ) )
58+ }
59+ pub ( crate ) fn canonicalize < P : AsPath > ( path : P ) -> io:: Result < PathBuf > {
60+ path. with_path ( super :: canonicalize)
61+ }
62+ pub ( crate ) fn remove_dir_all < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
63+ path. with_path ( super :: remove_dir_all)
64+ }
65+ pub ( crate ) fn read_link < P : AsPath > ( path : P ) -> io:: Result < PathBuf > {
66+ path. with_native_path ( super :: readlink)
67+ }
68+ pub ( crate ) fn try_exists < P : AsPath > ( path : P ) -> io:: Result < bool > {
69+ path. with_path ( crate :: sys_common:: fs:: try_exists)
70+ }
71+ }
2172
2273pub struct File {
2374 fd : WasiFd ,
@@ -398,7 +449,7 @@ impl OpenOptions {
398449}
399450
400451impl File {
401- pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
452+ pub fn open_native ( path : & CStr , opts : & OpenOptions ) -> io:: Result < File > {
402453 let ( dir, file) = open_parent ( path) ?;
403454 open_at ( & dir, & file, opts)
404455 }
@@ -548,8 +599,10 @@ impl DirBuilder {
548599 }
549600
550601 pub fn mkdir ( & self , p : & Path ) -> io:: Result < ( ) > {
551- let ( dir, file) = open_parent ( p) ?;
552- dir. create_directory ( osstr2str ( file. as_ref ( ) ) ?)
602+ run_path_with_cstr ( p, & |p| {
603+ let ( dir, file) = open_parent ( p) ?;
604+ dir. create_directory ( osstr2str ( file. as_ref ( ) ) ?)
605+ } )
553606 }
554607}
555608
@@ -563,18 +616,18 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
563616 let mut opts = OpenOptions :: new ( ) ;
564617 opts. directory ( true ) ;
565618 opts. read ( true ) ;
566- let dir = File :: open ( p, & opts) ?;
619+ let dir = run_path_with_cstr ( p , & |p| File :: open_native ( p, & opts) ) ?;
567620 Ok ( ReadDir :: new ( dir, p. to_path_buf ( ) ) )
568621}
569622
570- pub fn unlink ( p : & Path ) -> io:: Result < ( ) > {
623+ pub fn unlink ( p : & CStr ) -> io:: Result < ( ) > {
571624 let ( dir, file) = open_parent ( p) ?;
572625 dir. unlink_file ( osstr2str ( file. as_ref ( ) ) ?)
573626}
574627
575- pub fn rename ( old : & Path , new : & Path ) -> io:: Result < ( ) > {
628+ pub fn rename ( old : & CStr , new : & Path ) -> io:: Result < ( ) > {
576629 let ( old, old_file) = open_parent ( old) ?;
577- let ( new, new_file) = open_parent ( new) ?;
630+ let ( new, new_file) = run_path_with_cstr ( new , & |new| open_parent ( new) ) ?;
578631 old. rename ( osstr2str ( old_file. as_ref ( ) ) ?, & new, osstr2str ( new_file. as_ref ( ) ) ?)
579632}
580633
@@ -584,12 +637,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
584637 unsupported ( )
585638}
586639
587- pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
640+ pub fn rmdir ( p : & CStr ) -> io:: Result < ( ) > {
588641 let ( dir, file) = open_parent ( p) ?;
589642 dir. remove_directory ( osstr2str ( file. as_ref ( ) ) ?)
590643}
591644
592- pub fn readlink ( p : & Path ) -> io:: Result < PathBuf > {
645+ pub fn readlink ( p : & CStr ) -> io:: Result < PathBuf > {
593646 let ( dir, file) = open_parent ( p) ?;
594647 read_link ( & dir, & file)
595648}
@@ -625,24 +678,24 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
625678 }
626679}
627680
628- pub fn symlink ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
681+ pub fn symlink ( original : & Path , link : & CStr ) -> io:: Result < ( ) > {
629682 let ( link, link_file) = open_parent ( link) ?;
630683 link. symlink ( osstr2str ( original. as_ref ( ) ) ?, osstr2str ( link_file. as_ref ( ) ) ?)
631684}
632685
633- pub fn link ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
686+ pub fn link ( original : & CStr , link : & Path ) -> io:: Result < ( ) > {
634687 let ( original, original_file) = open_parent ( original) ?;
635- let ( link, link_file) = open_parent ( link) ?;
688+ let ( link, link_file) = run_path_with_cstr ( link , & |link| open_parent ( link) ) ?;
636689 // Pass 0 as the flags argument, meaning don't follow symlinks.
637690 original. link ( 0 , osstr2str ( original_file. as_ref ( ) ) ?, & link, osstr2str ( link_file. as_ref ( ) ) ?)
638691}
639692
640- pub fn stat ( p : & Path ) -> io:: Result < FileAttr > {
693+ pub fn stat ( p : & CStr ) -> io:: Result < FileAttr > {
641694 let ( dir, file) = open_parent ( p) ?;
642695 metadata_at ( & dir, wasi:: LOOKUPFLAGS_SYMLINK_FOLLOW , & file)
643696}
644697
645- pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
698+ pub fn lstat ( p : & CStr ) -> io:: Result < FileAttr > {
646699 let ( dir, file) = open_parent ( p) ?;
647700 metadata_at ( & dir, 0 , & file)
648701}
@@ -697,53 +750,51 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
697750///
698751/// Note that this can fail if `p` doesn't look like it can be opened relative
699752/// to any pre-opened file descriptor.
700- fn open_parent ( p : & Path ) -> io:: Result < ( ManuallyDrop < WasiFd > , PathBuf ) > {
701- run_path_with_cstr ( p, & |p| {
702- let mut buf = Vec :: < u8 > :: with_capacity ( 512 ) ;
703- loop {
704- unsafe {
705- let mut relative_path = buf. as_ptr ( ) . cast ( ) ;
706- let mut abs_prefix = ptr:: null ( ) ;
707- let fd = __wasilibc_find_relpath (
708- p. as_ptr ( ) ,
709- & mut abs_prefix,
710- & mut relative_path,
711- buf. capacity ( ) ,
712- ) ;
713- if fd == -1 {
714- if io:: Error :: last_os_error ( ) . raw_os_error ( ) == Some ( libc:: ENOMEM ) {
715- // Trigger the internal buffer resizing logic of `Vec` by requiring
716- // more space than the current capacity.
717- let cap = buf. capacity ( ) ;
718- buf. set_len ( cap) ;
719- buf. reserve ( 1 ) ;
720- continue ;
721- }
722- let msg = format ! (
723- "failed to find a pre-opened file descriptor \
724- through which {:?} could be opened",
725- p
726- ) ;
727- return Err ( io:: Error :: new ( io:: ErrorKind :: Uncategorized , msg) ) ;
753+ fn open_parent ( p : & CStr ) -> io:: Result < ( ManuallyDrop < WasiFd > , PathBuf ) > {
754+ let mut buf = Vec :: < u8 > :: with_capacity ( 512 ) ;
755+ loop {
756+ unsafe {
757+ let mut relative_path = buf. as_ptr ( ) . cast ( ) ;
758+ let mut abs_prefix = ptr:: null ( ) ;
759+ let fd = __wasilibc_find_relpath (
760+ p. as_ptr ( ) ,
761+ & mut abs_prefix,
762+ & mut relative_path,
763+ buf. capacity ( ) ,
764+ ) ;
765+ if fd == -1 {
766+ if io:: Error :: last_os_error ( ) . raw_os_error ( ) == Some ( libc:: ENOMEM ) {
767+ // Trigger the internal buffer resizing logic of `Vec` by requiring
768+ // more space than the current capacity.
769+ let cap = buf. capacity ( ) ;
770+ buf. set_len ( cap) ;
771+ buf. reserve ( 1 ) ;
772+ continue ;
728773 }
729- let relative = CStr :: from_ptr ( relative_path ) . to_bytes ( ) . to_vec ( ) ;
730-
731- return Ok ( (
732- ManuallyDrop :: new ( WasiFd :: from_raw_fd ( fd as c_int ) ) ,
733- PathBuf :: from ( OsString :: from_vec ( relative ) ) ,
734- ) ) ;
774+ let msg = format ! (
775+ "failed to find a pre-opened file descriptor \
776+ through which {:?} could be opened" ,
777+ p
778+ ) ;
779+ return Err ( io :: Error :: new ( io :: ErrorKind :: Uncategorized , msg ) ) ;
735780 }
736- }
781+ let relative = CStr :: from_ptr ( relative_path ) . to_bytes ( ) . to_vec ( ) ;
737782
738- extern "C" {
739- pub fn __wasilibc_find_relpath (
740- path : * const libc:: c_char ,
741- abs_prefix : * mut * const libc:: c_char ,
742- relative_path : * mut * const libc:: c_char ,
743- relative_path_len : libc:: size_t ,
744- ) -> libc:: c_int ;
783+ return Ok ( (
784+ ManuallyDrop :: new ( WasiFd :: from_raw_fd ( fd as c_int ) ) ,
785+ PathBuf :: from ( OsString :: from_vec ( relative) ) ,
786+ ) ) ;
745787 }
746- } )
788+ }
789+
790+ extern "C" {
791+ pub fn __wasilibc_find_relpath (
792+ path : * const libc:: c_char ,
793+ abs_prefix : * mut * const libc:: c_char ,
794+ relative_path : * mut * const libc:: c_char ,
795+ relative_path_len : libc:: size_t ,
796+ ) -> libc:: c_int ;
797+ }
747798}
748799
749800pub fn osstr2str ( f : & OsStr ) -> io:: Result < & str > {
@@ -761,7 +812,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
761812}
762813
763814pub fn remove_dir_all ( path : & Path ) -> io:: Result < ( ) > {
764- let ( parent, path) = open_parent ( path) ?;
815+ let ( parent, path) = run_path_with_cstr ( path , & |path| open_parent ( path) ) ?;
765816 remove_dir_all_recursive ( & parent, & path)
766817}
767818
0 commit comments