11use std:: ffi:: { OsString , OsStr } ;
22use std:: env;
3+ use std:: io:: { Error , ErrorKind } ;
34use std:: convert:: TryFrom ;
45
56use rustc_target:: abi:: { Size , LayoutOf } ;
@@ -293,20 +294,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
293294 let target_os = & this. tcx . sess . target . os ;
294295 assert ! ( target_os == "linux" || target_os == "macos" , "`getcwd` is only available for the UNIX target family" ) ;
295296
296- this. check_no_isolation ( "`getcwd`" ) ?;
297-
298- let buf = this. read_scalar ( & buf_op) ?. check_init ( ) ?;
299- let size = this. read_scalar ( & size_op) ?. to_machine_usize ( & * this. tcx ) ?;
300- // If we cannot get the current directory, we return null
301- match env:: current_dir ( ) {
302- Ok ( cwd) => {
303- if this. write_path_to_c_str ( & cwd, buf, size) ?. 0 {
304- return Ok ( buf) ;
297+ if this. machine . communicate {
298+ let buf = this. read_scalar ( & buf_op) ?. check_init ( ) ?;
299+ let size = this. read_scalar ( & size_op) ?. to_machine_usize ( & * this. tcx ) ?;
300+ // If we cannot get the current directory, we return null
301+ match env:: current_dir ( ) {
302+ Ok ( cwd) => {
303+ if this. write_path_to_c_str ( & cwd, buf, size) ?. 0 {
304+ return Ok ( buf) ;
305+ }
306+ let erange = this. eval_libc ( "ERANGE" ) ?;
307+ this. set_last_error ( erange) ?;
305308 }
306- let erange = this. eval_libc ( "ERANGE" ) ?;
307- this. set_last_error ( erange) ?;
309+ Err ( e) => this. set_last_error_from_io_error ( e) ?,
308310 }
309- Err ( e) => this. set_last_error_from_io_error ( e) ?,
311+ } else {
312+ // Emulate an error in isolation mode
313+ let err = Error :: new ( ErrorKind :: NotFound , "`getcwd` not available in isolation mode" ) ;
314+ this. set_last_error_from_io_error ( err) ?;
310315 }
311316 Ok ( Scalar :: null_ptr ( & * this. tcx ) )
312317 }
@@ -320,16 +325,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
320325 let this = self . eval_context_mut ( ) ;
321326 this. assert_target_os ( "windows" , "GetCurrentDirectoryW" ) ;
322327
323- this. check_no_isolation ( "`GetCurrentDirectoryW`" ) ?;
328+ if this. machine . communicate {
329+ let size = u64:: from ( this. read_scalar ( size_op) ?. to_u32 ( ) ?) ;
330+ let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
324331
325- let size = u64:: from ( this. read_scalar ( size_op) ?. to_u32 ( ) ?) ;
326- let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
327-
328- // If we cannot get the current directory, we return 0
329- match env:: current_dir ( ) {
330- Ok ( cwd) =>
331- return Ok ( windows_check_buffer_size ( this. write_path_to_wide_str ( & cwd, buf, size) ?) ) ,
332- Err ( e) => this. set_last_error_from_io_error ( e) ?,
332+ // If we cannot get the current directory, we return 0
333+ match env:: current_dir ( ) {
334+ Ok ( cwd) =>
335+ return Ok ( windows_check_buffer_size ( this. write_path_to_wide_str ( & cwd, buf, size) ?) ) ,
336+ Err ( e) => this. set_last_error_from_io_error ( e) ?,
337+ }
338+ } else {
339+ // Emulate an error in isolation mode
340+ let err = Error :: new ( ErrorKind :: NotFound , "`GetCurrentDirectoryW` not available in isolation mode" ) ;
341+ this. set_last_error_from_io_error ( err) ?;
333342 }
334343 Ok ( 0 )
335344 }
@@ -339,16 +348,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
339348 let target_os = & this. tcx . sess . target . os ;
340349 assert ! ( target_os == "linux" || target_os == "macos" , "`getcwd` is only available for the UNIX target family" ) ;
341350
342- this. check_no_isolation ( "`chdir`" ) ?;
343-
344- let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
351+ if this. machine . communicate {
352+ let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
345353
346- match env:: set_current_dir ( path) {
347- Ok ( ( ) ) => Ok ( 0 ) ,
348- Err ( e) => {
349- this. set_last_error_from_io_error ( e) ?;
350- Ok ( -1 )
354+ match env:: set_current_dir ( path) {
355+ Ok ( ( ) ) => Ok ( 0 ) ,
356+ Err ( e) => {
357+ this. set_last_error_from_io_error ( e) ?;
358+ Ok ( -1 )
359+ }
351360 }
361+ } else {
362+ // Emulate an error in isolation mode
363+ let err = Error :: new ( ErrorKind :: NotFound , "`chdir` not available in isolation mode" ) ;
364+ this. set_last_error_from_io_error ( err) ?;
365+ Ok ( -1 )
352366 }
353367 }
354368
@@ -360,16 +374,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
360374 let this = self . eval_context_mut ( ) ;
361375 this. assert_target_os ( "windows" , "SetCurrentDirectoryW" ) ;
362376
363- this. check_no_isolation ( "`SetCurrentDirectoryW`" ) ?;
364-
365- let path = this. read_path_from_wide_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
377+ if this. machine . communicate {
378+ let path = this. read_path_from_wide_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
366379
367- match env:: set_current_dir ( path) {
368- Ok ( ( ) ) => Ok ( 1 ) ,
369- Err ( e) => {
370- this. set_last_error_from_io_error ( e) ?;
371- Ok ( 0 )
380+ match env:: set_current_dir ( path) {
381+ Ok ( ( ) ) => Ok ( 1 ) ,
382+ Err ( e) => {
383+ this. set_last_error_from_io_error ( e) ?;
384+ Ok ( 0 )
385+ }
372386 }
387+ } else {
388+ // Emulate an error in isolation mode
389+ let err = Error :: new ( ErrorKind :: NotFound , "`SetCurrentDirectoryW` not available in isolation mode" ) ;
390+ this. set_last_error_from_io_error ( err) ?;
391+ Ok ( 0 )
373392 }
374393 }
375394
0 commit comments