char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
cd262f3
main
1use std:: io::{ self , Read }; 2use std:: path::{ Component , Path }; 3 4use crate :: authority:: SourceAuthority ; 5use crate :: caps:: PathTarget ; 6use cap_fs_ext::{ DirExt , FollowSymlinks , OpenOptionsFollowExt , OpenOptionsSyncExt }; 7 8pub fn open_directory ( path : & Path ) -> io:: Result < cap_std:: fs:: Dir > { 9let mut root = std:: path:: PathBuf :: new (); 10let mut names =Vec :: new (); 11for componentin path. components () { 12match component{ 13Component :: Prefix ( _) |Component :: RootDir => root. push ( component. as_os_str ()), 14Component :: Normal ( name) => names. push ( name), 15 _ =>return Err ( io:: Error :: other ( "Expected a canonical path" )), 16} 17} 18let mut directory = cap_std:: fs:: Dir :: open_ambient_dir ( root, cap_std:: ambient_authority ()) ?; 19// Canonicalization alone races with symlink replacement. Walk the resolved path 20// through directory handles without following any newly introduced symlinks. 21for namein names{ 22 directory = directory. open_dir_nofollow ( name) ?; 23} 24Ok ( directory) 25} 26 27pub fn read_text ( 28target : & PathTarget , 29authority : & SourceAuthority , 30) ->Result < String , Box < dyn std:: error:: Error >> { 31 authority. check_local ( target) ?; 32let path = target. as_path (); 33let directory =open_directory ( path. parent (). ok_or ( "Expected a module directory" ) ?) ?; 34let mut file =open_file ( & directory, target, authority) ?; 35let mut source =String :: new (); 36 file. read_to_string ( & mut source) ?; 37Ok ( source) 38} 39 40pub fn open_file ( 41directory : & cap_std:: fs:: Dir , 42target : & PathTarget , 43authority : & SourceAuthority , 44) ->Result < cap_std:: fs:: File , Box < dyn std:: error:: Error >> { 45 authority. check_local ( target) ?; 46let file_name = target 47. as_path () 48. file_name () 49. ok_or ( "Expected a module file" ) ?; 50let file =open_regular ( directory, file_name) ?; 51 authority. check_local ( target) ?; 52Ok ( file) 53} 54 55/// Opens a regular file without following symlinks or blocking on special files. 56pub fn open_regular ( 57directory : & cap_std:: fs:: Dir , 58file_name : impl AsRef < Path >, 59) ->Result < cap_std:: fs:: File , Box < dyn std:: error:: Error >> { 60let mut options = cap_std:: fs:: OpenOptions :: new (); 61 options. read ( true ). follow ( FollowSymlinks :: No ). nonblock ( true ); 62let file = directory. open_with ( file_name, & options) ?; 63if !file. metadata () ?. is_file () { 64return Err ( "Modules must be regular files" . into ()); 65} 66Ok ( file) 67}