use std::{ env, ffi::CString, io::Write, panic, ptr, sync::atomic::{AtomicBool, Ordering}, }; static RELOAD: AtomicBool = AtomicBool::new(false); pub fn begin_reload() { RELOAD.store(true, Ordering::SeqCst); panic::resume_unwind(Box::new(42)); } /// ONLY TO BE CALLED FROM MAIN WHEN NOT A SINGLE RESOURCE IS HELD pub unsafe fn continue_reload() { if !RELOAD.load(Ordering::SeqCst) { return; } eprintln!("reloading..."); let _ = std::io::stdout().lock().flush(); unsafe { exec() } eprintln!("exec failed."); } unsafe fn exec() { // path to this executable let exe = env::current_exe() .unwrap() .to_string_lossy() .replace(" (deleted)", ""); let exe_c = CString::new(exe).unwrap(); // argv let args: Vec = env::args().map(|a| CString::new(a).unwrap()).collect(); let mut argv: Vec<*const libc::c_char> = args.iter().map(|a| a.as_ptr()).collect(); argv.push(ptr::null()); unsafe { libc::execv(exe_c.as_ptr(), argv.as_ptr()); } }