1use flex_fuchsia_io as fio;
8
9pub mod directory;
10pub mod file;
11pub mod node;
12
13pub use fio::{Flags, OpenFlags, PERM_EXECUTABLE, PERM_READABLE, PERM_WRITABLE};
16
17pub fn canonicalize_path(path: &str) -> &str {
20 if path == "/" {
21 return ".";
22 }
23 if path.starts_with('/') {
24 return &path[1..];
25 }
26 path
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32 use fuchsia_async as fasync;
33 use std::fs;
34 use std::path::Path;
35 use tempfile::TempDir;
36 use vfs::file::vmo::read_only;
37 use vfs::pseudo_directory;
38 use vfs::remote::remote_dir;
39 use zx_status;
40
41 #[fasync::run_singlethreaded(test)]
42 async fn open_and_read_file_test() {
43 let tempdir = TempDir::new().expect("failed to create tmp dir");
44 let data = "abc".repeat(10000);
45 fs::write(tempdir.path().join("myfile"), &data).expect("failed writing file");
46
47 let dir = crate::directory::open_in_namespace(
48 tempdir.path().to_str().unwrap(),
49 fio::PERM_READABLE,
50 )
51 .expect("could not open tmp dir");
52 let file = directory::open_file_async(&dir, "myfile", fio::PERM_READABLE)
53 .expect("could not open file");
54 let contents = file::read_to_string(&file).await.expect("could not read file");
55 assert_eq!(&contents, &data, "File contents did not match");
56 }
57
58 #[fasync::run_singlethreaded(test)]
59 async fn open_and_write_file_test() {
60 let tempdir = TempDir::new().expect("failed to create tmp dir");
62 let dir = crate::directory::open_in_namespace(
63 tempdir.path().to_str().unwrap(),
64 fio::PERM_READABLE | fio::PERM_WRITABLE,
65 )
66 .expect("could not open tmp dir");
67
68 let file_name = Path::new("myfile");
70 let data = "abc".repeat(10000);
71 let file = directory::open_file_async(
72 &dir,
73 file_name.to_str().unwrap(),
74 fio::Flags::FLAG_MAYBE_CREATE | fio::PERM_WRITABLE,
75 )
76 .expect("could not open file");
77 file::write(&file, &data).await.expect("could not write file");
78
79 let contents = std::fs::read_to_string(tempdir.path().join(file_name)).unwrap();
81 assert_eq!(&contents, &data, "File contents did not match");
82 }
83
84 #[test]
85 fn test_canonicalize_path() {
86 assert_eq!(canonicalize_path("/"), ".");
87 assert_eq!(canonicalize_path("/foo"), "foo");
88 assert_eq!(canonicalize_path("/foo/bar/"), "foo/bar/");
89
90 assert_eq!(canonicalize_path("."), ".");
91 assert_eq!(canonicalize_path("./"), "./");
92 assert_eq!(canonicalize_path("foo/bar/"), "foo/bar/");
93 }
94
95 #[fasync::run_singlethreaded(test)]
96 async fn flags_test() {
97 let tempdir = TempDir::new().expect("failed to create tmp dir");
98 std::fs::write(tempdir.path().join("read_write"), "rw/read_write")
99 .expect("failed to write file");
100 let dir = crate::directory::open_in_namespace(
101 tempdir.path().to_str().unwrap(),
102 fio::PERM_READABLE | fio::PERM_WRITABLE,
103 )
104 .expect("could not open tmp dir");
105 let example_dir = pseudo_directory! {
106 "ro" => pseudo_directory! {
107 "read_only" => read_only("ro/read_only"),
108 },
109 "rw" => remote_dir(dir)
110 };
111 let example_dir_proxy = vfs::directory::serve(
112 example_dir,
113 vfs::execution_scope::ExecutionScope::new(),
114 fio::PERM_READABLE | fio::PERM_WRITABLE,
115 );
116
117 for (file_name, flags, should_succeed) in vec![
118 ("ro/read_only", fio::PERM_READABLE, true),
119 ("ro/read_only", fio::PERM_READABLE | fio::PERM_WRITABLE, false),
120 ("ro/read_only", fio::PERM_WRITABLE, false),
121 ("rw/read_write", fio::PERM_READABLE, true),
122 ("rw/read_write", fio::PERM_READABLE | fio::PERM_WRITABLE, true),
123 ("rw/read_write", fio::PERM_WRITABLE, true),
124 ] {
125 let file_proxy =
126 directory::open_file_async(&example_dir_proxy, file_name, flags).unwrap();
127 match (should_succeed, file_proxy.query().await) {
128 (true, Ok(_)) => (),
129 (false, Err(_)) => continue,
130 (true, Err(e)) => {
131 panic!("failed to open when expected success, couldn't describe: {:?}", e)
132 }
133 (false, Ok(d)) => {
134 panic!("successfully opened when expected failure, could describe: {:?}", d)
135 }
136 }
137 if flags.intersects(fio::Flags::PERM_READ_BYTES) {
138 assert_eq!(
139 file_name,
140 file::read_to_string(&file_proxy).await.expect("failed to read file")
141 );
142 }
143 if flags.intersects(fio::Flags::PERM_WRITE_BYTES) {
144 let _: u64 = file_proxy
145 .write(b"write_only")
146 .await
147 .expect("write failed")
148 .map_err(zx_status::Status::from_raw)
149 .expect("write error");
150 }
151 assert_eq!(file_proxy.close().await.unwrap(), Ok(()));
152 }
153 }
154}