//! Temporary directories for tests. Do not edit. //! //! Included with `#[path = "support/tmp.rs"] mod tmp;`. No crate is used: the name is made from //! the process id and a counter, and the directory is removed when the value is dropped. #![allow(dead_code)] // each test file uses a different part of this module use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicU32, Ordering}; static NEXT: AtomicU32 = AtomicU32::new(0); pub struct TempDir(PathBuf); impl TempDir { pub fn new(tag: &str) -> TempDir { let n = NEXT.fetch_add(1, Ordering::SeqCst); let path = std::env::temp_dir().join(format!("bx-{tag}-{}-{n}", std::process::id())); let _ = std::fs::remove_dir_all(&path); std::fs::create_dir_all(&path).unwrap(); TempDir(path) } pub fn path(&self) -> &Path { &self.0 } /// Writes `text` to `name` inside the directory and returns the full path. pub fn write(&self, name: &str, text: &str) -> PathBuf { let path = self.0.join(name); std::fs::write(&path, text).unwrap(); path } } impl Drop for TempDir { fn drop(&mut self) { // Put back the permissions a test may have taken away, or the removal fails. use std::os::unix::fs::PermissionsExt; let _ = std::fs::set_permissions(&self.0, std::fs::Permissions::from_mode(0o700)); let _ = std::fs::remove_dir_all(&self.0); } } /// True when the tests run as root, for whom file permissions do not apply. Tests that depend on /// a permission error print why they are skipped and return. pub fn running_as_root(test: &str) -> bool { let probe = TempDir::new("rootprobe"); let file = probe.write("probe", "x"); use std::os::unix::fs::PermissionsExt; std::fs::set_permissions(&file, std::fs::Permissions::from_mode(0o000)).unwrap(); let root = std::fs::read(&file).is_ok(); if root { eprintln!("{test}: skipped, because this user can read a mode 000 file (root?)"); } root }