66use clap:: { Arg , ArgAction , Command , value_parser} ;
77use nix:: sys:: stat:: Mode ;
88use nix:: unistd:: mkfifo;
9- use std:: fs;
10- use std:: os:: unix:: fs:: PermissionsExt ;
119use uucore:: display:: Quotable ;
1210use uucore:: error:: { UResult , USimpleError } ;
1311use uucore:: translate;
@@ -39,21 +37,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
3937 } ;
4038
4139 for f in fifos {
42- if mkfifo ( f. as_str ( ) , Mode :: from_bits_truncate ( 0o666 ) ) . is_err ( ) {
40+ // Create FIFO with exact mode by temporarily setting umask to 0.
41+ // This avoids a race condition where the FIFO briefly exists with
42+ // umask-based permissions before chmod is called.
43+ let result = {
44+ let _guard = uucore:: mode:: UmaskGuard :: set ( 0 ) ;
45+ mkfifo ( f. as_str ( ) , Mode :: from_bits_truncate ( mode) )
46+ } ;
47+
48+ if result. is_err ( ) {
4349 show ! ( USimpleError :: new(
4450 1 ,
4551 translate!( "mkfifo-error-cannot-create-fifo" , "path" => f. quote( ) ) ,
4652 ) ) ;
4753 }
4854
49- // Explicitly set the permissions to ignore umask
50- if let Err ( e) = fs:: set_permissions ( & f, fs:: Permissions :: from_mode ( mode) ) {
51- return Err ( USimpleError :: new (
52- 1 ,
53- translate ! ( "mkfifo-error-cannot-set-permissions" , "path" => f. quote( ) , "error" => e) ,
54- ) ) ;
55- }
56-
5755 // Apply SELinux context if requested
5856 #[ cfg( all( feature = "selinux" , target_os = "linux" ) ) ]
5957 {
@@ -66,7 +64,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
6664 if let Err ( e) =
6765 uucore:: selinux:: set_selinux_security_context ( Path :: new ( & f) , context)
6866 {
69- let _ = fs:: remove_file ( f) ;
67+ let _ = std :: fs:: remove_file ( f) ;
7068 return Err ( USimpleError :: new ( 1 , e. to_string ( ) ) ) ;
7169 }
7270 }
0 commit comments