Skip to content

Commit 61e1b65

Browse files
committed
Use clib instead
1 parent 45b1d3a commit 61e1b65

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

src/api/processor.rs

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
use crate::api::processor::Response::{Error, FetchFileChunk, GetInfo, ListFiles, Reboot};
22
use crate::api::websocket::{ConnectionState, SessionEvent, WebSocketSession};
3-
use anyhow::anyhow;
3+
use anyhow::{anyhow, bail};
44
use embedded_svc::ws::FrameType;
55
use esp_idf_svc::hal::gpio::Pull;
66
use esp_idf_svc::ping::Info;
7+
use esp_idf_svc::sys::{ctime, fstat, stat, strerror, S_IFDIR, S_IFMT};
78
use serde::{Deserialize, Serialize};
9+
use std::ffi::CString;
810
use std::fs::{read_dir, FileType};
911
use std::io::{Read, Seek};
1012
use std::mem::MaybeUninit;
13+
use std::os::fd::AsFd;
14+
use std::os::unix::fs::MetadataExt;
1115
use std::path::Path;
1216
use std::time::SystemTime;
1317
use time::serde::timestamp::milliseconds;
@@ -94,7 +98,10 @@ impl Processor {
9498

9599
fn list_files(&self, path: &str) -> anyhow::Result<Response> {
96100
let dir_path = Path::new(&self.root_dir).join(path);
97-
log::info!("Listing files at {}", dir_path.to_str().unwrap_or("<Unknown>"));
101+
log::info!(
102+
"Listing files at {}",
103+
dir_path.to_str().unwrap_or("<Unknown>")
104+
);
98105
// Ideally we should find a way to learn the size of all files, but we need to
99106
// iterate over all files anyway... so.. maybe not? :/
100107
let mut files: Vec<File> = vec![];
@@ -110,13 +117,25 @@ impl Processor {
110117
continue;
111118
}
112119
let path = path.unwrap();
113-
let metadata = entry.metadata()?;
120+
121+
// Notice: there's entry.metadata(), but somehow the implementation of rust's std
122+
// is broken and cannot return correct stat. So we call C lib directly to get
123+
// stat for the file instead.
124+
let path_c_str = CString::new(path.as_bytes());
125+
let mut file_stat = stat::default();
126+
let ret = unsafe { stat(path_c_str?.as_ptr(), &mut file_stat) };
127+
if ret != 0 {
128+
bail!("Failed to get file {} stat with error: {}", path, unsafe {
129+
CString::from_raw(strerror(ret)).to_str()?
130+
});
131+
}
132+
114133
files.push(File {
115134
path,
116-
size: metadata.len(),
117-
modified_at: metadata.modified()?.into(),
118-
created_at: metadata.created()?.into(),
119-
is_dir: metadata.is_dir(),
135+
size: file_stat.st_size as u64,
136+
modified_at: OffsetDateTime::from_unix_timestamp(file_stat.st_mtim.tv_sec)?,
137+
created_at: OffsetDateTime::from_unix_timestamp(file_stat.st_ctim.tv_sec)?,
138+
is_dir: file_stat.st_mode & S_IFMT == S_IFDIR,
120139
})
121140
}
122141
Ok(ListFiles {

0 commit comments

Comments
 (0)