@@ -63,7 +63,7 @@ fn dispatch_name<T>(
6363 write_run_user ( & mut addr, name) ?;
6464 match with_missing_dir_creation ( is_listener, addr. write_terminator ( ) , & mut create) {
6565 Err ( e) if fail_is_benign ( & e) => {
66- write_prefixed ( & mut addr, TMPDIR , name) ?;
66+ write_prefixed ( & mut addr, tmpdir ( ) , name) ?;
6767 with_missing_dir_creation ( is_listener, addr. write_terminator ( ) , & mut create)
6868 }
6969 otherwise => otherwise,
@@ -171,12 +171,27 @@ fn fail_is_benign(e: &io::Error) -> bool {
171171 matches ! ( e. kind( ) , NotFound | Unsupported ) || e. raw_os_error ( ) == Some ( libc:: ENOTDIR )
172172}
173173
174- const TMPDIR : & [ NonZeroU8 ] = {
175- unsafe {
176- assume_nonzero_slice ( if cfg ! ( target_os = "android" ) {
177- b"/data/local/tmp/"
178- } else {
179- b"/tmp/"
180- } )
174+ // Don't check this in right away.
175+ fn tmpdir < ' p > ( ) -> & ' p [ NonZeroU8 ] {
176+ if cfg ! ( target_os = "android" ) {
177+ // SAFETY: there is a nul terminator
178+ let mut ptr = unsafe { libc:: getenv ( b"TMPDIR\0 " . as_ptr ( ) . cast ( ) ) } ;
179+ if ptr. is_null ( ) {
180+ // SAFETY: there is a nul terminator
181+ ptr = unsafe { libc:: getenv ( b"TEMPDIR\0 " . as_ptr ( ) . cast ( ) ) } ;
182+ }
183+ if ptr. is_null ( ) {
184+ // SAFETY: proof by look at it
185+ return unsafe { assume_nonzero_slice ( b"/data/local/tmp/" ) } ;
186+ }
187+ // SAFETY: we got it from getenv and it's not null
188+ let len = unsafe { libc:: strlen ( ptr) } ;
189+ // SAFETY: there are no interior nuls as per strlen, and the pointer
190+ // is from getenv (meaning it would only be invalidated by setenv,
191+ // which would be a race)
192+ unsafe { std:: slice:: from_raw_parts ( ptr. cast ( ) , len) }
193+ } else {
194+ // SAFETY: proof by look at it
195+ unsafe { assume_nonzero_slice ( b"/tmp/" ) }
181196 }
182- } ;
197+ }
0 commit comments