@@ -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,7 @@ 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 ! ( "Permission denied while opening {} file, retrying with privileges" , p . as_ref ( ) . display ( ) ) ;
340350 with_privileges ( & [ Cap :: DAC_READ_SEARCH ] , || options. open ( & p) ) . or_else ( |e| {
341351 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
342352 return Err ( e) ;
@@ -353,7 +363,7 @@ pub fn read_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<File> {
353363 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
354364 return Err ( e) ;
355365 }
356- debug ! ( "Permission denied while opening file, retrying with privileges" , ) ;
366+ debug ! ( "Permission denied while opening {} file, retrying with privileges" , p . as_ref ( ) . display ( ) ) ;
357367 with_privileges ( & [ Cap :: DAC_READ_SEARCH ] , || std:: fs:: File :: open ( & p) ) . or_else ( |e| {
358368 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
359369 return Err ( e) ;
@@ -368,7 +378,7 @@ pub fn remove_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<()> {
368378 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
369379 return Err ( e) ;
370380 }
371- debug ! ( "Permission denied while removing file, retrying with privileges" , ) ;
381+ debug ! ( "Permission denied while removing {} file, retrying with privileges" , p . as_ref ( ) . display ( ) ) ;
372382 with_privileges ( & [ Cap :: DAC_OVERRIDE ] , || std:: fs:: remove_file ( & p) )
373383 } )
374384}
@@ -378,7 +388,7 @@ pub fn create_dir_all_with_privileges<P: AsRef<Path>>(p: P) -> std::io::Result<(
378388 if e. kind ( ) != std:: io:: ErrorKind :: PermissionDenied {
379389 return Err ( e) ;
380390 }
381- debug ! ( "Permission denied while creating directory, retrying with privileges" , ) ;
391+ debug ! ( "Permission denied while creating {} directory, retrying with privileges" , p . as_ref ( ) . display ( ) ) ;
382392 with_privileges ( & [ Cap :: DAC_OVERRIDE ] , || std:: fs:: create_dir_all ( p) )
383393 } )
384394}
0 commit comments