Squashed (migration)
(initial) Align formatting and code style to project standards. Add live_test.sh: full automated integration suite against a real SSH server Show [name] for optional positionals, allow filtering import by name too Fix transfer rough edges: value-name hint, identity warnings, single-profile export Add transfer subcommand for bulk profile export/import Harden forced ssh flags: accept-new host keys, block multiplexing, tighten identity auth release build opts Standardize error messages, formatting, and code style. Refine --help text for consistency. Update comments for clarity and tone alignment. Normalize user-facing --help text for tone/format consistency Show real mapping grammar in --help, make --via repeatable, trim comments Match vmic's custom top-level --help renderer Implement porthole v0.1: profiles, supervised open/close, reconnect Fix --via/-J grammar and --force process-group kill added .gitignore
This commit is contained in:
25
src/atomic.rs
Normal file
25
src/atomic.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
//! Atomic file writes: write to a sibling temp file, then `rename` over the
|
||||
//! target. Matters here specifically for the instance JSON file, which the
|
||||
//! supervisor rewrites on every state change while it may be alive for
|
||||
//! months; a reader (`status`/`list`) must never observe a half-written
|
||||
//! file, and a crash mid-write must never corrupt the last-known-good state.
|
||||
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn write(path: &Path, contents: &[u8]) -> std::io::Result<()>
|
||||
{
|
||||
let tmp = path.with_extension(format!(
|
||||
"{}.tmp.{}",
|
||||
path.extension().and_then(|e| e.to_str()).unwrap_or(""),
|
||||
std::process::id()
|
||||
));
|
||||
|
||||
{
|
||||
let mut f = std::fs::File::create(&tmp)?;
|
||||
f.write_all(contents)?;
|
||||
f.sync_all()?;
|
||||
}
|
||||
|
||||
std::fs::rename(&tmp, path)
|
||||
}
|
||||
Reference in New Issue
Block a user