Crate pidlock

Crate pidlock 

Source
Expand description

§pidlock

A library for creating and managing PID-based file locks, providing a simple and reliable way to ensure only one instance of a program runs at a time.

§Features

  • Cross-platform: Works on Unix-like systems and Windows
  • Stale lock detection: Automatically detects and cleans up locks from dead processes
  • Path validation: Ensures lock file paths are valid across platforms
  • Safe cleanup: Automatically releases locks when the Pidlock is dropped
  • Comprehensive error handling: Detailed error types for different failure scenarios

§Quick Start

use pidlock::Pidlock;
use std::path::Path;

let temp_dir = std::env::temp_dir();
let lock_path = temp_dir.join("my_app.pid");
let mut lock = Pidlock::new_validated(&lock_path)?;

// Try to acquire the lock
match lock.acquire() {
    Ok(()) => {
        println!("Lock acquired successfully!");
         
        // Do your work here...
         
        // Explicitly release the lock (optional - it's auto-released on drop)
        lock.release()?;
        println!("Lock released successfully!");
    }
    Err(pidlock::PidlockError::LockExists) => {
        println!("Another instance is already running");
    }
    Err(e) => {
        eprintln!("Failed to acquire lock: {}", e);
    }
}

§Advanced Usage

§Checking Lock Status Without Acquiring

use pidlock::Pidlock;

let temp_dir = std::env::temp_dir();
let lock_path = temp_dir.join("example.pid");
let lock = Pidlock::new_validated(&lock_path)?;

// Check if a lock file exists
if lock.exists() {
    // Check if the lock is held by an active process
    match lock.is_active()? {
        true => println!("Lock is held by an active process"),
        false => println!("Lock file exists but process is dead (stale lock)"),
    }
} else {
    println!("No lock file exists");
}

§Error Handling

use pidlock::{Pidlock, PidlockError, InvalidPathError};

let result = Pidlock::new_validated("invalid<path>");
match result {
    Ok(_) => println!("Path is valid"),
    Err(PidlockError::InvalidPath(InvalidPathError::ProblematicCharacter { character, filename })) => {
        println!("Invalid character '{}' in filename: {}", character, filename);
    }
    Err(e) => println!("Other error: {}", e),
}

§Platform Considerations

  • Unix/Linux: Uses POSIX signals for process detection, respects umask for permissions
  • Windows: Uses Win32 APIs for process detection, handles reserved filenames
  • File permissions: Lock files are created with restrictive permissions (600 on Unix)
  • Path validation: Automatically validates paths for cross-platform compatibility
  • Lock file locations: Use /run/lock/ on Linux, /var/run/ on other Unix systems, or appropriate system directories. Avoid /tmp for production use.

§Safety

This library uses unsafe code for platform-specific process detection, but all unsafe operations are carefully validated and documented. The library ensures that:

  • PID values are validated before use in system calls
  • Windows handles are properly managed and cleaned up
  • Unix signals are used safely without affecting target processes

Structs§

Pidlock
A pid-centered lock. A lock is considered “acquired” when a file exists on disk at the path specified, containing the process id of the locking process.

Enums§

InvalidPathError
Specific types of path validation errors.
PidlockError
Errors that may occur during the Pidlock lifetime.