11use std:: convert:: TryFrom ;
22use std:: env;
33use std:: ffi:: { OsStr , OsString } ;
4+ use std:: io:: { Error , ErrorKind } ;
45
56use rustc_data_structures:: fx:: FxHashMap ;
67use rustc_mir:: interpret:: Pointer ;
@@ -321,20 +322,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
321322 "`getcwd` is only available for the UNIX target family"
322323 ) ;
323324
324- this. check_no_isolation ( "`getcwd`" ) ?;
325-
326- let buf = this. read_scalar ( & buf_op) ?. check_init ( ) ?;
327- let size = this. read_scalar ( & size_op) ?. to_machine_usize ( & * this. tcx ) ?;
328- // If we cannot get the current directory, we return null
329- match env:: current_dir ( ) {
330- Ok ( cwd) => {
331- if this. write_path_to_c_str ( & cwd, buf, size) ?. 0 {
332- return Ok ( buf) ;
325+ if this. machine . communicate {
326+ let buf = this. read_scalar ( & buf_op) ?. check_init ( ) ?;
327+ let size = this. read_scalar ( & size_op) ?. to_machine_usize ( & * this. tcx ) ?;
328+ // If we cannot get the current directory, we return null
329+ match env:: current_dir ( ) {
330+ Ok ( cwd) => {
331+ if this. write_path_to_c_str ( & cwd, buf, size) ?. 0 {
332+ return Ok ( buf) ;
333+ }
334+ let erange = this. eval_libc ( "ERANGE" ) ?;
335+ this. set_last_error ( erange) ?;
333336 }
334- let erange = this. eval_libc ( "ERANGE" ) ?;
335- this. set_last_error ( erange) ?;
337+ Err ( e) => this. set_last_error_from_io_error ( e) ?,
336338 }
337- Err ( e) => this. set_last_error_from_io_error ( e) ?,
339+ } else {
340+ // Emulate an error in isolation mode
341+ let err = Error :: new ( ErrorKind :: NotFound , "`getcwd` not available in isolation mode" ) ;
342+ this. set_last_error_from_io_error ( err) ?;
338343 }
339344 Ok ( Scalar :: null_ptr ( & * this. tcx ) )
340345 }
@@ -348,16 +353,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
348353 let this = self . eval_context_mut ( ) ;
349354 this. assert_target_os ( "windows" , "GetCurrentDirectoryW" ) ;
350355
351- this. check_no_isolation ( "`GetCurrentDirectoryW`" ) ?;
356+ if this. machine . communicate {
357+ let size = u64:: from ( this. read_scalar ( size_op) ?. to_u32 ( ) ?) ;
358+ let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
352359
353- let size = u64:: from ( this. read_scalar ( size_op) ?. to_u32 ( ) ?) ;
354- let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
355-
356- // If we cannot get the current directory, we return 0
357- match env:: current_dir ( ) {
358- Ok ( cwd) =>
359- return Ok ( windows_check_buffer_size ( this. write_path_to_wide_str ( & cwd, buf, size) ?) ) ,
360- Err ( e) => this. set_last_error_from_io_error ( e) ?,
360+ // If we cannot get the current directory, we return 0
361+ match env:: current_dir ( ) {
362+ Ok ( cwd) =>
363+ return Ok ( windows_check_buffer_size ( this. write_path_to_wide_str ( & cwd, buf, size) ?) ) ,
364+ Err ( e) => this. set_last_error_from_io_error ( e) ?,
365+ }
366+ } else {
367+ // Emulate an error in isolation mode
368+ let err = Error :: new ( ErrorKind :: NotFound , "`GetCurrentDirectoryW` not available in isolation mode" ) ;
369+ this. set_last_error_from_io_error ( err) ?;
361370 }
362371 Ok ( 0 )
363372 }
@@ -370,16 +379,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
370379 "`getcwd` is only available for the UNIX target family"
371380 ) ;
372381
373- this. check_no_isolation ( "`chdir`" ) ?;
374-
375- let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
382+ if this. machine . communicate {
383+ let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
376384
377- match env:: set_current_dir ( path) {
378- Ok ( ( ) ) => Ok ( 0 ) ,
379- Err ( e) => {
380- this. set_last_error_from_io_error ( e) ?;
381- Ok ( -1 )
385+ match env:: set_current_dir ( path) {
386+ Ok ( ( ) ) => Ok ( 0 ) ,
387+ Err ( e) => {
388+ this. set_last_error_from_io_error ( e) ?;
389+ Ok ( -1 )
390+ }
382391 }
392+ } else {
393+ // Emulate an error in isolation mode
394+ let err = Error :: new ( ErrorKind :: NotFound , "`chdir` not available in isolation mode" ) ;
395+ this. set_last_error_from_io_error ( err) ?;
396+ Ok ( -1 )
383397 }
384398 }
385399
@@ -393,16 +407,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
393407 let this = self . eval_context_mut ( ) ;
394408 this. assert_target_os ( "windows" , "SetCurrentDirectoryW" ) ;
395409
396- this. check_no_isolation ( "`SetCurrentDirectoryW`" ) ?;
397-
398- let path = this. read_path_from_wide_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
410+ if this. machine . communicate {
411+ let path = this. read_path_from_wide_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
399412
400- match env:: set_current_dir ( path) {
401- Ok ( ( ) ) => Ok ( 1 ) ,
402- Err ( e) => {
403- this. set_last_error_from_io_error ( e) ?;
404- Ok ( 0 )
413+ match env:: set_current_dir ( path) {
414+ Ok ( ( ) ) => Ok ( 1 ) ,
415+ Err ( e) => {
416+ this. set_last_error_from_io_error ( e) ?;
417+ Ok ( 0 )
418+ }
405419 }
420+ } else {
421+ // Emulate an error in isolation mode
422+ let err = Error :: new ( ErrorKind :: NotFound , "`SetCurrentDirectoryW` not available in isolation mode" ) ;
423+ this. set_last_error_from_io_error ( err) ?;
424+ Ok ( 0 )
406425 }
407426 }
408427
0 commit comments