@@ -17,7 +17,58 @@ use crate::sys::time::SystemTime;
17
17
use crate :: sys:: unsupported;
18
18
use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
19
19
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
+ }
21
72
22
73
pub struct File {
23
74
fd : WasiFd ,
@@ -398,7 +449,7 @@ impl OpenOptions {
398
449
}
399
450
400
451
impl File {
401
- pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
452
+ pub fn open_native ( path : & CStr , opts : & OpenOptions ) -> io:: Result < File > {
402
453
let ( dir, file) = open_parent ( path) ?;
403
454
open_at ( & dir, & file, opts)
404
455
}
@@ -548,8 +599,10 @@ impl DirBuilder {
548
599
}
549
600
550
601
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
+ } )
553
606
}
554
607
}
555
608
@@ -563,18 +616,18 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
563
616
let mut opts = OpenOptions :: new ( ) ;
564
617
opts. directory ( true ) ;
565
618
opts. read ( true ) ;
566
- let dir = File :: open ( p, & opts) ?;
619
+ let dir = run_path_with_cstr ( p , & |p| File :: open_native ( p, & opts) ) ?;
567
620
Ok ( ReadDir :: new ( dir, p. to_path_buf ( ) ) )
568
621
}
569
622
570
- pub fn unlink ( p : & Path ) -> io:: Result < ( ) > {
623
+ pub fn unlink ( p : & CStr ) -> io:: Result < ( ) > {
571
624
let ( dir, file) = open_parent ( p) ?;
572
625
dir. unlink_file ( osstr2str ( file. as_ref ( ) ) ?)
573
626
}
574
627
575
- pub fn rename ( old : & Path , new : & Path ) -> io:: Result < ( ) > {
628
+ pub fn rename ( old : & CStr , new : & Path ) -> io:: Result < ( ) > {
576
629
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) ) ?;
578
631
old. rename ( osstr2str ( old_file. as_ref ( ) ) ?, & new, osstr2str ( new_file. as_ref ( ) ) ?)
579
632
}
580
633
@@ -584,12 +637,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
584
637
unsupported ( )
585
638
}
586
639
587
- pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
640
+ pub fn rmdir ( p : & CStr ) -> io:: Result < ( ) > {
588
641
let ( dir, file) = open_parent ( p) ?;
589
642
dir. remove_directory ( osstr2str ( file. as_ref ( ) ) ?)
590
643
}
591
644
592
- pub fn readlink ( p : & Path ) -> io:: Result < PathBuf > {
645
+ pub fn readlink ( p : & CStr ) -> io:: Result < PathBuf > {
593
646
let ( dir, file) = open_parent ( p) ?;
594
647
read_link ( & dir, & file)
595
648
}
@@ -625,24 +678,24 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
625
678
}
626
679
}
627
680
628
- pub fn symlink ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
681
+ pub fn symlink ( original : & Path , link : & CStr ) -> io:: Result < ( ) > {
629
682
let ( link, link_file) = open_parent ( link) ?;
630
683
link. symlink ( osstr2str ( original. as_ref ( ) ) ?, osstr2str ( link_file. as_ref ( ) ) ?)
631
684
}
632
685
633
- pub fn link ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
686
+ pub fn link ( original : & CStr , link : & Path ) -> io:: Result < ( ) > {
634
687
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) ) ?;
636
689
// Pass 0 as the flags argument, meaning don't follow symlinks.
637
690
original. link ( 0 , osstr2str ( original_file. as_ref ( ) ) ?, & link, osstr2str ( link_file. as_ref ( ) ) ?)
638
691
}
639
692
640
- pub fn stat ( p : & Path ) -> io:: Result < FileAttr > {
693
+ pub fn stat ( p : & CStr ) -> io:: Result < FileAttr > {
641
694
let ( dir, file) = open_parent ( p) ?;
642
695
metadata_at ( & dir, wasi:: LOOKUPFLAGS_SYMLINK_FOLLOW , & file)
643
696
}
644
697
645
- pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
698
+ pub fn lstat ( p : & CStr ) -> io:: Result < FileAttr > {
646
699
let ( dir, file) = open_parent ( p) ?;
647
700
metadata_at ( & dir, 0 , & file)
648
701
}
@@ -697,53 +750,51 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
697
750
///
698
751
/// Note that this can fail if `p` doesn't look like it can be opened relative
699
752
/// 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 ;
728
773
}
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 ) ) ;
735
780
}
736
- }
781
+ let relative = CStr :: from_ptr ( relative_path ) . to_bytes ( ) . to_vec ( ) ;
737
782
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
+ ) ) ;
745
787
}
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
+ }
747
798
}
748
799
749
800
pub fn osstr2str ( f : & OsStr ) -> io:: Result < & str > {
@@ -761,7 +812,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
761
812
}
762
813
763
814
pub 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) ) ?;
765
816
remove_dir_all_recursive ( & parent, & path)
766
817
}
767
818
0 commit comments