@@ -276,6 +276,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
276276 this. try_unwrap_io_result ( result)
277277 }
278278
279+ fn symlink (
280+ & mut self ,
281+ target_op : OpTy < ' tcx , Tag > ,
282+ linkpath_op : OpTy < ' tcx , Tag >
283+ ) -> InterpResult < ' tcx , i32 > {
284+ #[ cfg( target_family = "unix" ) ]
285+ fn create_link ( src : PathBuf , dst : PathBuf ) -> std:: io:: Result < ( ) > {
286+ std:: os:: unix:: fs:: symlink ( src, dst)
287+ }
288+
289+ #[ cfg( target_family = "windows" ) ]
290+ fn create_link ( src : PathBuf , dst : PathBuf ) -> std:: io:: Result < ( ) > {
291+ use std:: os:: windows:: fs;
292+ if src. is_dir ( ) {
293+ fs:: symlink_dir ( src, dst)
294+ } else {
295+ fs:: symlink ( src, dst)
296+ }
297+ }
298+
299+ let this = self . eval_context_mut ( ) ;
300+
301+ this. check_no_isolation ( "symlink" ) ?;
302+
303+ let target = this. read_os_str_from_c_str ( this. read_scalar ( target_op) ?. not_undef ( ) ?) ?. into ( ) ;
304+ let linkpath = this. read_os_str_from_c_str ( this. read_scalar ( linkpath_op) ?. not_undef ( ) ?) ?. into ( ) ;
305+
306+ this. try_unwrap_io_result ( create_link ( target, linkpath) . map ( |_| 0 ) )
307+ }
308+
279309 fn stat (
280310 & mut self ,
281311 path_op : OpTy < ' tcx , Tag > ,
@@ -545,7 +575,6 @@ impl FileMetadata {
545575 let metadata = if follow_symlink {
546576 std:: fs:: metadata ( path)
547577 } else {
548- // FIXME: metadata for symlinks need testing.
549578 std:: fs:: symlink_metadata ( path)
550579 } ;
551580
0 commit comments