@@ -15,18 +15,19 @@ pub use self::noop::{Args, Config, Process};
1515mod unix {
1616 use std:: io;
1717 use std:: env:: set_current_dir;
18+ use std:: fs:: { File , OpenOptions } ;
19+ use std:: io:: Write ;
1820 use std:: os:: fd:: { AsFd , AsRawFd } ;
19- use std:: os:: unix:: io :: RawFd ;
21+ use std:: os:: unix:: fs :: OpenOptionsExt ;
2022 use std:: path:: { Path , PathBuf , StripPrefixError } ;
2123 use std:: str:: FromStr ;
2224 use log:: error;
23- use nix:: fcntl:: { flock , open , FlockArg , OFlag } ;
25+ use nix:: fcntl:: { Flock , FlockArg , OFlag , open } ;
2426 use nix:: sys:: stat:: Mode ;
2527 use nix:: sys:: stat:: umask;
2628 use nix:: unistd:: { Gid , Group , Uid , User } ;
2729 use nix:: unistd:: {
28- close, chown, chroot, dup2, fork, getpid, setgid, setsid, setuid,
29- write,
30+ close, chroot, dup2, fork, getpid, setgid, setsid, setuid,
3031 } ;
3132 use serde:: { Deserialize , Serialize } ;
3233 use crate :: config:: { ConfigFile , ConfigPath } ;
@@ -39,8 +40,8 @@ mod unix {
3940 /// All the configuration.
4041 config : Config ,
4142
42- /// The file descriptor of the pid file if requested.
43- pid_file : Option < RawFd > ,
43+ /// The pid file if requested.
44+ pid_file : Option < Flock < File > > ,
4445 }
4546
4647 impl Process {
@@ -97,7 +98,7 @@ mod unix {
9798
9899 // Create a new session.
99100 if let Err ( err) = setsid ( ) {
100- error ! ( "Fatal: failed to crates new session: {}" , err ) ;
101+ error ! ( "Fatal: failed to crates new session: {err}" ) ;
101102 return Err ( Failed )
102103 }
103104
@@ -169,67 +170,49 @@ mod unix {
169170
170171 /// Creates the pid file if requested.
171172 fn create_pid_file ( & mut self ) -> Result < ( ) , Failed > {
172- let path = match self . config . working_dir . as_ref ( ) {
173+ let path = match self . config . pid_file . as_ref ( ) {
173174 Some ( path) => path,
174175 None => return Ok ( ( ) )
175176 } ;
176177
177- let fd = match open (
178- path. as_path ( ) ,
179- OFlag :: O_WRONLY | OFlag :: O_CREAT | OFlag :: O_TRUNC ,
180- Mode :: from_bits_truncate ( 0o666 )
181- ) {
182- Ok ( fd) => fd,
178+ let file = OpenOptions :: new ( )
179+ . read ( false ) . write ( true )
180+ . create ( true ) . truncate ( true )
181+ . mode ( 0o666 )
182+ . open ( path) ;
183+ let file = match file {
184+ Ok ( file) => file,
183185 Err ( err) => {
184186 error ! ( "Fatal: failed to create PID file {}: {}" ,
185187 path. display( ) , err
186188 ) ;
187189 return Err ( Failed )
188190 }
189191 } ;
190-
191- if self . config . user . is_some ( ) || self . config . group . is_some ( ) {
192- if let Err ( err) = chown (
193- path. as_path ( ) ,
194- self . config . user . as_ref ( ) . map ( |user| user. uid ) ,
195- self . config . group . as_ref ( ) . map ( |group| group. gid ) ,
196- ) {
197- error ! (
198- "Fatal: failed to change owner of pid file: {}" , err
192+ let file = match Flock :: lock (
193+ file, FlockArg :: LockExclusiveNonblock
194+ ) {
195+ Ok ( file) => file,
196+ Err ( ( _, err) ) => {
197+ error ! ( "Fatal: cannot lock PID file {}: {}" ,
198+ path. display( ) , err
199199 ) ;
200200 return Err ( Failed )
201201 }
202- }
203-
204- if let Err ( err) = flock ( fd, FlockArg :: LockExclusiveNonblock ) {
205- error ! ( "Fatal: cannot lock PID file {}: {}" ,
206- path. display( ) , err
207- ) ;
208- return Err ( Failed )
209- }
210- self . pid_file = Some ( fd) ;
202+ } ;
203+ self . pid_file = Some ( file) ;
211204 Ok ( ( ) )
212205 }
213206
214207 /// Updates the pid in the pid file after forking.
215- fn write_pid_file ( & self ) -> Result < ( ) , Failed > {
216- if let Some ( pid_file) = self . pid_file {
208+ fn write_pid_file ( & mut self ) -> Result < ( ) , Failed > {
209+ if let Some ( pid_file) = self . pid_file . as_mut ( ) {
217210 let pid = format ! ( "{}" , getpid( ) ) ;
218- match write ( pid_file, pid. as_bytes ( ) ) {
219- Ok ( len) if len == pid. len ( ) => { }
220- Ok ( _) => {
221- error ! (
222- "Fatal: failed to write PID to PID file: \
223- short write"
224- ) ;
225- return Err ( Failed )
226- }
227- Err ( err) => {
228- error ! (
229- "Fatal: failed to write PID to PID file: {}" , err
230- ) ;
231- return Err ( Failed )
232- }
211+ if let Err ( err) = pid_file. write_all ( pid. as_bytes ( ) ) {
212+ error ! (
213+ "Fatal: failed to write PID to PID file: {err}"
214+ ) ;
215+ return Err ( Failed )
233216 }
234217 }
235218 Ok ( ( ) )
@@ -245,7 +228,7 @@ mod unix {
245228 Ok ( ( ) )
246229 }
247230 Err ( err) => {
248- error ! ( "Fatal: failed to detach: {}" , err ) ;
231+ error ! ( "Fatal: failed to detach: {err}" ) ;
249232 Err ( Failed )
250233 }
251234 }
@@ -279,33 +262,33 @@ mod unix {
279262 ) {
280263 Ok ( fd) => fd,
281264 Err ( err) => {
282- error ! ( "Fatal: failed to open /dev/null: {}" , err ) ;
265+ error ! ( "Fatal: failed to open /dev/null: {err}" ) ;
283266 return Err ( Failed )
284267 }
285268 } ;
286269
287270 if let Err ( err) = dup2 ( dev_null, io:: stdin ( ) . as_fd ( ) . as_raw_fd ( ) ) {
288271 error ! (
289- "Fatal: failed to redirect stdio to /dev/null: {}" , err
272+ "Fatal: failed to redirect stdio to /dev/null: {err}"
290273 ) ;
291274 return Err ( Failed )
292275 }
293276 if let Err ( err) = dup2 ( dev_null, io:: stdout ( ) . as_fd ( ) . as_raw_fd ( ) ) {
294277 error ! (
295- "Fatal: failed to redirect stdout to /dev/null: {}" , err
278+ "Fatal: failed to redirect stdout to /dev/null: {err}"
296279 ) ;
297280 return Err ( Failed )
298281 }
299282 if let Err ( err) = dup2 ( dev_null, io:: stderr ( ) . as_fd ( ) . as_raw_fd ( ) ) {
300283 error ! (
301- "Fatal: failed to redirect stderr to /dev/null: {}" , err
284+ "Fatal: failed to redirect stderr to /dev/null: {err}"
302285 ) ;
303286 return Err ( Failed )
304287 }
305288
306289 if let Err ( err) = close ( dev_null) {
307290 error ! (
308- "Fatal: failed to close /dev/null: {}" , err
291+ "Fatal: failed to close /dev/null: {err}"
309292 ) ;
310293 return Err ( Failed )
311294 }
@@ -439,10 +422,10 @@ mod unix {
439422 Ok ( UserId { uid : user. uid , name } )
440423 }
441424 Ok ( None ) => {
442- Err ( format ! ( "unknown user '{}'" , name ) )
425+ Err ( format ! ( "unknown user '{name }'" ) )
443426 }
444427 Err ( err) => {
445- Err ( format ! ( "failed to resolve user '{}': {}" , name , err ) )
428+ Err ( format ! ( "failed to resolve user '{name }': {err}" ) )
446429 }
447430 }
448431 }
@@ -487,10 +470,10 @@ mod unix {
487470 Ok ( GroupId { gid : group. gid , name } )
488471 }
489472 Ok ( None ) => {
490- Err ( format ! ( "unknown user '{}'" , name ) )
473+ Err ( format ! ( "unknown user '{name }'" ) )
491474 }
492475 Err ( err) => {
493- Err ( format ! ( "failed to resolve user '{}': {}" , name , err ) )
476+ Err ( format ! ( "failed to resolve user '{name }': {err}" ) )
494477 }
495478 }
496479 }
0 commit comments