Codex Handbook
windows-sandbox-rs/src/bin/command_runner/win/cwd_junction.rs 140 lines
use codex_windows_sandbox::log_note;use std::collections::hash_map::DefaultHasher;use std::hash::Hash;use std::hash::Hasher;use std::os::windows::fs::MetadataExt as _;use std::os::windows::process::CommandExt as _;use std::path::Path;use std::path::PathBuf;use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_REPARSE_POINT;fn junction_name_for_path(path: &Path) -> String {    let mut hasher = DefaultHasher::new();    path.to_string_lossy().hash(&mut hasher);    format!("{:x}", hasher.finish())}fn junction_root_for_userprofile(userprofile: &str) -> PathBuf {    PathBuf::from(userprofile)        .join(".codex")        .join(".sandbox")        .join("cwd")}pub fn create_cwd_junction(requested_cwd: &Path, log_dir: Option<&Path>) -> Option<PathBuf> {    let userprofile = std::env::var("USERPROFILE").ok()?;    let junction_root = junction_root_for_userprofile(&userprofile);    if let Err(err) = std::fs::create_dir_all(&junction_root) {        log_note(            &format!(                "junction: failed to create {}: {err}",                junction_root.display()            ),            log_dir,        );        return None;    }    let junction_path = junction_root.join(junction_name_for_path(requested_cwd));    if junction_path.exists() {        // Reuse an existing junction if it looks like a reparse point; this keeps the hot path        // cheap and avoids repeatedly shelling out to mklink.        match std::fs::symlink_metadata(&junction_path) {            Ok(md) if (md.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT) != 0 => {                log_note(                    &format!("junction: reusing existing {}", junction_path.display()),                    log_dir,                );                return Some(junction_path);            }            Ok(_) => {                // Unexpected: something else exists at this path (regular directory/file). We'll                // try to remove it if possible and recreate the junction.                log_note(                    &format!(                        "junction: existing path is not a reparse point, recreating {}",                        junction_path.display()                    ),                    log_dir,                );            }            Err(err) => {                log_note(                    &format!(                        "junction: failed to stat existing {}: {err}",                        junction_path.display()                    ),                    log_dir,                );                return None;            }        }        if let Err(err) = std::fs::remove_dir(&junction_path) {            log_note(                &format!(                    "junction: failed to remove existing {}: {err}",                    junction_path.display()                ),                log_dir,            );            return None;        }    }    let link = junction_path.to_string_lossy().to_string();    let target = requested_cwd.to_string_lossy().to_string();    // Use `cmd /c` so we can call `mklink` (a cmd builtin). We must quote paths so CWDs    // containing spaces work reliably.    //    // IMPORTANT: `std::process::Command::args()` will apply Windows quoting/escaping rules when    // constructing the command line. Passing a single argument that itself contains quotes can    // confuse `cmd.exe` and cause mklink to fail with "syntax is incorrect". We avoid that by    // using `raw_arg` to pass the tokens exactly as `cmd.exe` expects to parse them.    //    // Paths cannot contain quotes on Windows, so no extra escaping is needed here.    let link_quoted = format!("\"{link}\"");    let target_quoted = format!("\"{target}\"");    log_note(        &format!("junction: creating via cmd /c mklink /J {link_quoted} {target_quoted}"),        log_dir,    );    let output = match std::process::Command::new("cmd")        .raw_arg("/c")        .raw_arg("mklink")        .raw_arg("/J")        .raw_arg(&link_quoted)        .raw_arg(&target_quoted)        .output()    {        Ok(output) => output,        Err(err) => {            log_note(&format!("junction: mklink failed to run: {err}"), log_dir);            return None;        }    };    if output.status.success() && junction_path.exists() {        log_note(            &format!(                "junction: created {} -> {}",                junction_path.display(),                requested_cwd.display()            ),            log_dir,        );        return Some(junction_path);    }    let stdout = String::from_utf8_lossy(&output.stdout);    let stderr = String::from_utf8_lossy(&output.stderr);    log_note(        &format!(            "junction: mklink failed status={:?} stdout={} stderr={}",            output.status,            stdout.trim(),            stderr.trim()        ),        log_dir,    );    None}