@@ -94,6 +94,24 @@ pub fn with_mutable_config<F, R>(file: &mut File, f: F) -> std::io::Result<R>
9494where
9595 F : FnOnce ( & mut File ) -> io:: Result < R > ,
9696{
97+ let mut val = unlock_immutable ( file) ?;
98+ let res = f ( file) ;
99+ val |= FS_IMMUTABLE_FL ;
100+ lock_immutable ( file, val) ?;
101+ res
102+ }
103+
104+ pub fn lock_immutable ( file : & mut File , mut val : u32 ) -> Result < ( ) , io:: Error > {
105+ immutable_required_privileges ( file, || {
106+ if unsafe { nix:: libc:: ioctl ( file. as_raw_fd ( ) , FS_IOC_SETFLAGS , & mut val) } < 0 {
107+ return Err ( std:: io:: Error :: last_os_error ( ) ) ;
108+ }
109+ Ok ( ( ) )
110+ } ) ?;
111+ Ok ( ( ) )
112+ }
113+
114+ pub fn unlock_immutable ( file : & mut File ) -> Result < u32 , io:: Error > {
97115 let mut val = 0 ;
98116 if unsafe { nix:: libc:: ioctl ( file. as_raw_fd ( ) , FS_IOC_GETFLAGS , & mut val) } < 0 {
99117 return Err ( std:: io:: Error :: last_os_error ( ) ) ;
@@ -109,15 +127,7 @@ where
109127 } else {
110128 warn ! ( "Config file was not immutable." ) ;
111129 }
112- let res = f ( file) ;
113- val |= FS_IMMUTABLE_FL ;
114- immutable_required_privileges ( file, || {
115- if unsafe { nix:: libc:: ioctl ( file. as_raw_fd ( ) , FS_IOC_SETFLAGS , & mut val) } < 0 {
116- return Err ( std:: io:: Error :: last_os_error ( ) ) ;
117- }
118- Ok ( ( ) )
119- } ) ?;
120- res
130+ Ok ( val)
121131}
122132
123133pub fn warn_if_mutable ( file : & File , return_err : bool ) -> std:: io:: Result < ( ) > {
@@ -336,7 +346,10 @@ pub fn open_lock_with_privileges<P: AsRef<Path>>(
336346 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
337347 return Err ( e) ;
338348 }
339- debug ! ( "Permission denied while opening file, retrying with privileges" , ) ;
349+ debug ! (
350+ "Permission denied while opening {} file, retrying with privileges" ,
351+ p. as_ref( ) . display( )
352+ ) ;
340353 with_privileges ( & [ Cap :: DAC_READ_SEARCH ] , || options. open ( & p) ) . or_else ( |e| {
341354 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
342355 return Err ( e) ;
@@ -353,7 +366,10 @@ pub fn read_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<File> {
353366 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
354367 return Err ( e) ;
355368 }
356- debug ! ( "Permission denied while opening file, retrying with privileges" , ) ;
369+ debug ! (
370+ "Permission denied while opening {} file, retrying with privileges" ,
371+ p. as_ref( ) . display( )
372+ ) ;
357373 with_privileges ( & [ Cap :: DAC_READ_SEARCH ] , || std:: fs:: File :: open ( & p) ) . or_else ( |e| {
358374 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
359375 return Err ( e) ;
@@ -368,7 +384,10 @@ pub fn remove_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<()> {
368384 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
369385 return Err ( e) ;
370386 }
371- debug ! ( "Permission denied while removing file, retrying with privileges" , ) ;
387+ debug ! (
388+ "Permission denied while removing {} file, retrying with privileges" ,
389+ p. as_ref( ) . display( )
390+ ) ;
372391 with_privileges ( & [ Cap :: DAC_OVERRIDE ] , || std:: fs:: remove_file ( & p) )
373392 } )
374393}
@@ -378,7 +397,10 @@ pub fn create_dir_all_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<(
378397 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
379398 return Err ( e) ;
380399 }
381- debug ! ( "Permission denied while creating directory, retrying with privileges" , ) ;
400+ debug ! (
401+ "Permission denied while creating {} directory, retrying with privileges" ,
402+ p. as_ref( ) . display( )
403+ ) ;
382404 with_privileges ( & [ Cap :: DAC_OVERRIDE ] , || std:: fs:: create_dir_all ( p) )
383405 } )
384406}
0 commit comments