@@ -61,23 +61,10 @@ fn dispatch_name<T>(
6161 NameInner :: UdSocketPseudoNs ( name) => {
6262 let name = name. as_bytes ( ) ;
6363 write_run_user ( & mut addr, name) ?;
64- let addrt = addr. write_terminator ( ) ;
65- match create ( addrt) {
66- Err ( e) if listen_fail_is_benign ( & e) => {
67- if is_listener {
68- let path = Path :: new ( OsStr :: from_bytes ( addrt. inner ( ) . path ( ) ) ) ;
69- if let Some ( p) = path. parent ( ) {
70- if !p. as_os_str ( ) . is_empty ( ) {
71- if let Ok ( ok) =
72- std:: fs:: create_dir_all ( p) . and_then ( |( ) | create ( addrt) )
73- {
74- return Ok ( ok) ;
75- }
76- }
77- }
78- }
64+ match with_missing_dir_creation ( is_listener, addr. write_terminator ( ) , & mut create) {
65+ Err ( e) if fail_is_benign ( & e) => {
7966 write_prefixed ( & mut addr, TMPDIR , name) ?;
80- create ( addr. write_terminator ( ) )
67+ with_missing_dir_creation ( is_listener , addr. write_terminator ( ) , & mut create )
8168 }
8269 otherwise => otherwise,
8370 }
@@ -91,6 +78,29 @@ fn dispatch_name<T>(
9178 }
9279}
9380
81+ fn with_missing_dir_creation < T > (
82+ create : bool ,
83+ addr : TerminatedUdAddr < ' _ > ,
84+ mut f : impl FnMut ( TerminatedUdAddr < ' _ > ) -> io:: Result < T > ,
85+ ) -> io:: Result < T > {
86+ match f ( addr) {
87+ Err ( e) if create && fail_is_benign ( & e) && create_missing_dirs ( addr) => f ( addr) ,
88+ otherwise => otherwise,
89+ }
90+ }
91+
92+ fn create_missing_dirs ( addr : TerminatedUdAddr < ' _ > ) -> bool {
93+ let path = Path :: new ( OsStr :: from_bytes ( addr. inner ( ) . path ( ) ) ) ;
94+ if let Some ( p) = path. parent ( ) {
95+ if !p. as_os_str ( ) . is_empty ( ) {
96+ if let Ok ( ( ) ) = std:: fs:: create_dir_all ( p) {
97+ return true ;
98+ }
99+ }
100+ }
101+ false
102+ }
103+
94104#[ allow( clippy:: as_conversions) ]
95105const MAX_RUN_USER : usize = "/run/user//" . len ( ) + uid_t:: MAX . ilog10 ( ) as usize + 1 ;
96106const RUN_USER_BUF : usize = MAX_RUN_USER + 1 ;
@@ -156,7 +166,7 @@ fn escape_nuls(b: &mut [u8]) {
156166 b. iter_mut ( ) . filter ( |c| * * c == 0 ) . for_each ( |c| * c = b'_' ) ;
157167}
158168
159- fn listen_fail_is_benign ( e : & io:: Error ) -> bool {
169+ fn fail_is_benign ( e : & io:: Error ) -> bool {
160170 use io:: ErrorKind :: * ;
161171 matches ! ( e. kind( ) , NotFound | Unsupported ) || e. raw_os_error ( ) == Some ( libc:: ENOTDIR )
162172}
0 commit comments