use std::ops::DerefMut; use std::path::Path; use std::process::Command; use std::{fs, sync, thread, time}; use crate::{DiskSparse, FileSystem}; fn with_redoxfs(callback: F) -> T where T: Send + Sync + 'static, F: FnMut(&Path) -> T + Send + Sync + 'static, { let disk_path = "image.bin"; let mount_path = "image"; let res = { let disk = DiskSparse::create(dbg!(disk_path)).unwrap(); if cfg!(not(target_os = "redox")) { if !Path::new(mount_path).exists() { dbg!(fs::create_dir(dbg!(mount_path))).unwrap(); } } let ctime = dbg!(time::SystemTime::now().duration_since(time::UNIX_EPOCH)).unwrap(); let fs = FileSystem::create_reserved(disk, &[], ctime.as_secs(), ctime.subsec_nanos()).unwrap(); let callback_mutex = sync::Arc::new(sync::Mutex::new(callback)); let join_handle = crate::mount(fs, dbg!(mount_path), move |real_path| { let callback_mutex = callback_mutex.clone(); let real_path = real_path.to_owned(); thread::spawn(move || { let res = { let mut callback_guard = callback_mutex.lock().unwrap(); let callback = callback_guard.deref_mut(); callback(&real_path) }; if cfg!(target_os = "redox") { dbg!(fs::remove_file(dbg!(format!(":{}", mount_path)))).unwrap(); } else { let status_res = if cfg!(target_os = "linux") { Command::new("fusermount") .arg("-u") .arg(mount_path) .status() } else { Command::new("umount").arg(mount_path).status() }; let status = dbg!(status_res).unwrap(); if !status.success() { panic!("umount failed"); } } res }) }) .unwrap(); join_handle.join().unwrap() }; dbg!(fs::remove_file(dbg!(disk_path))).unwrap(); if cfg!(not(target_os = "redox")) { dbg!(fs::remove_dir(dbg!(mount_path))).unwrap(); } res } #[test] fn simple() { with_redoxfs(|path| { dbg!(fs::create_dir(&path.join("test"))).unwrap(); }) } #[cfg(target_os = "redox")] #[test] fn mmap() { use std::os::unix::ffi::OsStrExt; use syscall; //TODO with_redoxfs(|path| { use std::slice; let path = dbg!(path.join("test")); let mmap_inner = |write: bool| { let fd = dbg!(syscall::open( path.as_os_str().as_bytes(), syscall::O_CREAT | syscall::O_RDWR | syscall::O_CLOEXEC )) .unwrap(); let map = unsafe { slice::from_raw_parts_mut( dbg!(syscall::fmap( fd, &syscall::Map { offset: 0, size: 128, flags: syscall::PROT_READ | syscall::PROT_WRITE } )) .unwrap() as *mut u8, 128, ) }; // Maps should be available after closing assert_eq!(dbg!(syscall::close(fd)), Ok(0)); for i in 0..128 { if write { map[i as usize] = i; } assert_eq!(map[i as usize], i); } //TODO: add msync unsafe { assert_eq!(dbg!(syscall::funmap(map.as_mut_ptr() as usize)), Ok(0)); } }; mmap_inner(true); mmap_inner(false); }) }