66
77use std:: convert:: TryInto ;
88use std:: ffi:: CString ;
9- use std:: fs:: { canonicalize, remove_file, File } ;
9+ use std:: fs:: { canonicalize, remove_dir_all , remove_file, File } ;
1010use std:: io:: { Error , ErrorKind , Write } ;
1111use std:: os:: unix:: ffi:: OsStrExt ;
1212use std:: path:: PathBuf ;
@@ -18,6 +18,8 @@ fn main() {
1818 test_file_open_unix_allow_two_args ( ) ;
1919 test_file_open_unix_needs_three_args ( ) ;
2020 test_file_open_unix_extra_third_arg ( ) ;
21+ #[ cfg( target_os = "linux" ) ]
22+ test_o_tmpfile_flag ( ) ;
2123}
2224
2325fn tmp ( ) -> PathBuf {
@@ -45,6 +47,15 @@ fn prepare(filename: &str) -> PathBuf {
4547 path
4648}
4749
50+ /// Prepare directory: compute directory name and make sure it does not exist.
51+ #[ allow( unused) ]
52+ fn prepare_dir ( dirname : & str ) -> PathBuf {
53+ let path = tmp ( ) . join ( & dirname) ;
54+ // Clean the directory for robustness.
55+ remove_dir_all ( & path) . ok ( ) ;
56+ path
57+ }
58+
4859/// Prepare like above, and also write some initial content to the file.
4960fn prepare_with_content ( filename : & str , content : & [ u8 ] ) -> PathBuf {
5061 let path = prepare ( filename) ;
@@ -135,3 +146,22 @@ fn test_readlink() {
135146 assert_eq ! ( res, -1 ) ;
136147 assert_eq ! ( Error :: last_os_error( ) . kind( ) , ErrorKind :: NotFound ) ;
137148}
149+
150+ #[ cfg( target_os = "linux" ) ]
151+ fn test_o_tmpfile_flag ( ) {
152+ use std:: fs:: { create_dir, OpenOptions } ;
153+ use std:: os:: unix:: fs:: OpenOptionsExt ;
154+ let dir_path = prepare_dir ( "miri_test_fs_dir" ) ;
155+ create_dir ( & dir_path) . unwrap ( ) ;
156+ // test that the `O_TMPFILE` custom flag gracefully errors instead of stopping execution
157+ assert_eq ! (
158+ Some ( libc:: EOPNOTSUPP ) ,
159+ OpenOptions :: new( )
160+ . read( true )
161+ . write( true )
162+ . custom_flags( libc:: O_TMPFILE )
163+ . open( dir_path)
164+ . unwrap_err( )
165+ . raw_os_error( ) ,
166+ ) ;
167+ }
0 commit comments