filelock_rs/pid.rs
1//! # Pid
2//!
3//! `Pid` is a Rust crate that provides functionality for creating, reading, and managing PID (Process ID) files.
4//!
5//! A PID file typically contains the process ID of a running program. This crate
6//! offers an easy-to-use interface for working with PID files, allowing you to
7//! create new PID files, read process IDs from existing files, and handle the
8//! cleanup of PID files when they are no longer needed.
9//!
10//! ## Examples
11//!
12//! Creating a new PID file:
13//!
14//! ```no_run
15//! use filelock_rs::pid::Pid;
16//!
17//! match Pid::new("/var/run", "my_program") {
18//! Ok(pid) => {
19//! println!("PID file created. Process ID: {}", pid.process_id);
20//! }
21//! Err(error) => {
22//! eprintln!("Failed to create PID file: {}", error);
23//! }
24//! }
25//! ```
26//!
27//! Reading the process ID from an existing PID file:
28//!
29//! ```no_run
30//! use filelock_rs::pid::Pid;
31//!
32//! let pid_file = Pid::new("/var/run", "my_program").expect("Failed to create PID file");
33//! let process_id = pid_file.process_id;
34//! println!("Process ID: {}", process_id);
35//! ```
36//!
37//! ## Cleanup
38//!
39//! The `Pid` structure implements the `Drop` trait, ensuring that the PID file
40//! is automatically cleaned up when it goes out of scope. The file
41//! is unlocked and removed from the file system.
42//!
43//! ## Notes
44//!
45//! - The `Pid` crate uses the standard library's file I/O and process ID functionality.
46//! - Ensure that the target directory has proper write permissions for creating and manipulating PID files.
47//! - If the PID file cannot be opened, locked, or written, an `std::io::Error` will be returned.
48use std::fmt::Display;
49use std::fs::File;
50use std::io;
51use std::io::Write;
52
53use crate::FdLock;
54
55/// Represents a PID (Process ID) file.
56///
57/// The `Pid` structure provides functionality
58/// for creating, reading, and managing a PID file,
59/// which typically contains the process ID of
60/// a running program.
61pub struct Pid {
62 /// process_id stored inside the file.
63 pub process_id: u32,
64 /// path of the file.
65 pub file_path: String,
66 file: File,
67}
68
69impl Pid {
70 /// Creates a new `Pid` instance with the specified file path and name.
71 ///
72 /// # Arguments
73 ///
74 /// * `path` - The path where the PID file will be stored.
75 /// * `name` - The name of the PID file (without the extension).
76 ///
77 /// # Errors
78 ///
79 /// Returns an `std::io::Error` if the file cannot be opened, locked, or written.
80 ///
81 /// # Examples
82 ///
83 /// ```no_run
84 /// use filelock_rs::pid::Pid;
85 ///
86 /// let pid = Pid::new("/var/run", "my_program").unwrap();
87 /// ```
88 pub fn new<T: Display>(path: T, name: T) -> io::Result<Self> {
89 let pid = std::process::id();
90 let file_path = format!("{path}/{name}.pid");
91 let mut file = std::fs::File::create(file_path.clone())?;
92 file.try_lock_exclusive()?;
93 file.write_all(format!("{pid}").as_bytes())?;
94 Ok(Self {
95 process_id: pid,
96 file_path,
97 file,
98 })
99 }
100}
101
102impl Drop for Pid {
103 fn drop(&mut self) {
104 self.file.unlock().unwrap();
105 std::fs::remove_file(self.file_path.clone()).unwrap();
106 }
107}