remem-ai 0.6.62

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
#[cfg(not(windows))]
use std::fs::{File, OpenOptions};
use std::path::{Component, Path, PathBuf};

use anyhow::{bail, Context, Result};

#[cfg(windows)]
use crate::retrieval::embedding::local_semantic::{
    windows_cleanup,
    windows_security::{self, AnchoredFile, DirectoryAnchor},
};

#[cfg(windows)]
pub(super) type CacheLock = AnchoredFile;
#[cfg(not(windows))]
pub(super) type CacheLock = File;

pub(super) fn exclusive_lock(parent: &Path, name: &str) -> Result<CacheLock> {
    let file = open_lock_file(parent, name)?;
    fs2::FileExt::lock_exclusive(&file)
        .with_context(|| format!("lock private runtime cache exclusively {}", name))?;
    Ok(file)
}

pub(super) fn shared_lock(parent: &Path, name: &str) -> Result<CacheLock> {
    let file = open_lock_file(parent, name)?;
    fs2::FileExt::lock_shared(&file)
        .with_context(|| format!("lock private runtime cache for use {}", name))?;
    Ok(file)
}

pub(super) fn try_exclusive_lock(parent: &Path, name: &str) -> Result<Option<CacheLock>> {
    let file = open_lock_file(parent, name)?;
    match fs2::FileExt::try_lock_exclusive(&file) {
        Ok(()) => Ok(Some(file)),
        Err(error)
            if error.kind() == std::io::ErrorKind::WouldBlock
                || error.raw_os_error() == fs2::lock_contended_error().raw_os_error() =>
        {
            Ok(None)
        }
        Err(error) => {
            Err(error).with_context(|| format!("try exclusive private runtime cache lock {}", name))
        }
    }
}

pub(super) fn usage_lock_name(cache_name: &str) -> String {
    format!(".{cache_name}.usage.lock")
}

fn lock_path(parent: &Path, name: &str) -> PathBuf {
    parent.join(name)
}

pub(super) fn release_and_remove_usage_lock(
    parent: &Path,
    cache_name: &str,
    lock: CacheLock,
) -> Result<()> {
    #[cfg(windows)]
    let expected = windows_security::lock_file_identity(&lock)
        .with_context(|| format!("identify private runtime cache lock {cache_name}"))?;
    fs2::FileExt::unlock(&lock)
        .with_context(|| format!("unlock stale private runtime cache {cache_name}"))?;
    let path = lock_path(parent, &usage_lock_name(cache_name));
    drop(lock);
    #[cfg(windows)]
    return windows_cleanup::remove_owner_only_file(&path, expected);
    #[cfg(not(windows))]
    match std::fs::remove_file(&path) {
        Ok(()) => Ok(()),
        Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),
        Err(error) => Err(error)
            .with_context(|| format!("remove private runtime usage lock {}", path.display())),
    }
}

fn open_lock_file(parent: &Path, name: &str) -> Result<CacheLock> {
    validate_lock_name(name)?;
    let canonical_parent = std::fs::canonicalize(parent)
        .with_context(|| format!("canonicalize lock parent {}", parent.display()))?;
    if canonical_parent != parent {
        bail!(
            "private runtime lock parent is not canonical: expected {}, got {}",
            parent.display(),
            canonical_parent.display()
        );
    }
    #[cfg(windows)]
    let parent_anchor = DirectoryAnchor::open_owner_only(parent, false)
        .with_context(|| format!("anchor private runtime lock parent {}", parent.display()))?;
    let path = parent.join(name);
    #[cfg(not(windows))]
    let file = {
        let mut options = OpenOptions::new();
        options.create(true).read(true).write(true);
        #[cfg(unix)]
        {
            use std::os::unix::fs::OpenOptionsExt;
            options.mode(0o600).custom_flags(libc::O_NOFOLLOW);
        }
        options
            .open(&path)
            .with_context(|| format!("open private runtime lock {}", path.display()))?
    };
    #[cfg(windows)]
    let file = windows_security::open_or_create_owner_only_lock_file(&path)
        .with_context(|| format!("open secure private runtime lock {}", path.display()))?;
    let path_metadata = std::fs::symlink_metadata(&path)
        .with_context(|| format!("stat private runtime lock {}", path.display()))?;
    if !path_metadata.file_type().is_file() {
        bail!(
            "private runtime lock is not a regular file: {}",
            path.display()
        );
    }
    let canonical_path = std::fs::canonicalize(&path)
        .with_context(|| format!("canonicalize private runtime lock {}", path.display()))?;
    if canonical_path != path || !canonical_path.starts_with(parent) {
        bail!(
            "private runtime lock escapes cache parent: {}",
            canonical_path.display()
        );
    }
    #[cfg(unix)]
    {
        use std::os::unix::fs::{MetadataExt, PermissionsExt};

        let handle_metadata = file
            .metadata()
            .with_context(|| format!("stat private runtime lock handle {}", path.display()))?;
        if handle_metadata.dev() != path_metadata.dev()
            || handle_metadata.ino() != path_metadata.ino()
        {
            bail!(
                "private runtime lock changed while opening: {}",
                path.display()
            );
        }
        std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600))
            .with_context(|| format!("secure private runtime lock {}", path.display()))?;
    }
    #[cfg(windows)]
    windows_security::validate_lock_file(&path, &file)
        .with_context(|| format!("verify Windows private runtime lock {}", path.display()))?;
    #[cfg(windows)]
    let file = AnchoredFile::new(file, parent_anchor);
    Ok(file)
}

fn validate_lock_name(name: &str) -> Result<()> {
    let mut components = Path::new(name).components();
    if !matches!(components.next(), Some(Component::Normal(_))) || components.next().is_some() {
        bail!("invalid private runtime lock name {name}");
    }
    Ok(())
}