Skip to content

Commit 9f64434

Browse files
committed
simplify path checking and reword comments
1 parent fb00155 commit 9f64434

File tree

1 file changed

+18
-35
lines changed

1 file changed

+18
-35
lines changed

src/shims/fs.rs

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
288288

289289
// Under normal circumstances, we would use `deref_operand(statxbuf_op)` to produce a
290290
// proper `MemPlace` and then write the results of this function to it. However, the
291-
// syscall API in Rust is untyped. This means that all the `statx` parameters are provided
291+
// `syscall` function is untyped. This means that all the `statx` parameters are provided
292292
// as `isize`s instead of having the proper types. Thus, we have to recover the layout of
293293
// `statxbuf_op` by using the `libc::statx` struct type.
294294
let statxbuf_place = {
@@ -303,39 +303,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
303303
this.ref_to_mplace(statxbuf_imm)?
304304
};
305305

306-
let pathname: PathBuf = this.read_os_str_from_c_str(pathname_scalar)?.into();
307-
// This argument should be a `c_int` but the syscall API just returns a pointer sized
308-
// integer.
306+
let path: PathBuf = this.read_os_str_from_c_str(pathname_scalar)?.into();
307+
// `flags` should be a `c_int` but the `syscall` function provides an `isize`.
309308
let flags: i32 = this.try_from_ptr_sized_operand(flags_op)?;
310309

311-
let at_fdcwd = this.eval_libc_i32("AT_FDCWD")?;
312-
// Now we need to resolve the path of the target file. This was done following the manual
313-
// entry for `statx`
314-
315-
// If `pathname` is absolute we can ignore `dirfd`.
316-
let path = if pathname.is_absolute() {
317-
pathname
318-
} else {
319-
// This argument should be a `c_int` but the syscall API just returns a pointer sized
320-
// integer.
321-
let dirfd: i32 = this.try_from_ptr_sized_operand(dirfd_op)?;
322-
// If `dirfd` is `AT_FDCWD`, `pathname` is relative to the current directory.
323-
if dirfd == at_fdcwd {
324-
match std::env::current_dir() {
325-
Ok(cwd) => cwd.join(pathname),
326-
Err(e) => {
327-
this.set_last_error_from_io_error(e)?;
328-
return Ok(-1);
329-
}
330-
}
331-
} else {
332-
// This behavior is specified but cannot be tested from `libstd`. If you found this
333-
// error please open an issue reporting it.
334-
throw_unsup_format!(
335-
"Using statx with a fildes different from `AT_FDCWD` is not supported"
336-
)
337-
}
338-
};
310+
// we only support interpreting `path` as an absolute directory or as a directory relative
311+
// to `dirfd` when the latter is `AT_FDCWD`. Other behavior is specified but it cannot be
312+
// tested from `libstd`. If you found this error, please open an issue reporting it.
313+
314+
// `dirfd` should be a `c_int` but the `syscall` function provides an `isize`.
315+
if !(path.is_absolute()
316+
|| this.try_from_ptr_sized_operand::<i32>(dirfd_op)?
317+
== this.eval_libc_i32("AT_FDCWD")?)
318+
{
319+
throw_unsup_format!(
320+
"Using statx with a file descriptor different from `AT_FDCWD` is not supported"
321+
)
322+
}
339323

340324
// the `_mask_op` paramter specifies the file information that the caller requested.
341325
// However `statx` is allowed to return information that was not requested or to not
@@ -366,8 +350,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
366350
// The `mode` field specifies the type of the file and the permissions over the file for
367351
// the owner, its group and other users. Given that we can only provide the file type
368352
// without using platform specific methods, we only set the bits corresponding to the file
369-
// type. This argument should be an `__u16` but the syscall API just returns a pointer sized
370-
// integer.
353+
// type. This should be an `__u16` but `libc` provides its values as `u32`.
371354
let mode = if file_type.is_file() {
372355
this.eval_libc("S_IFREG")?
373356
} else if file_type.is_dir() {
@@ -377,7 +360,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
377360
}.to_u32()?;
378361

379362
let mode: u16 = mode.try_into().map_err(|e|
380-
err_unsup_format!("Failed to convert 32-bit operand to u16: {}",
363+
err_unsup_format!("Failed to convert 32-bit value to u16: {}",
381364
e
382365
))?;
383366

0 commit comments

Comments
 (0)