Skip to content

Commit 0f58289

Browse files
committed
fetch ERANGE value from libc
1 parent c0a6b5f commit 0f58289

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

src/shims/env.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::collections::HashMap;
22
use std::env;
33

4-
use rustc::ty::layout::{Size};
5-
use rustc_mir::interpret::{Pointer, Memory};
64
use crate::stacked_borrows::Tag;
75
use crate::*;
6+
use rustc::ty::layout::Size;
7+
use rustc_mir::interpret::{Memory, Pointer};
88

99
#[derive(Default)]
1010
pub struct EnvVars {
@@ -24,7 +24,8 @@ impl EnvVars {
2424
if ecx.machine.communicate {
2525
for (name, value) in env::vars() {
2626
if !excluded_env_vars.contains(&name) {
27-
let var_ptr = alloc_env_var(name.as_bytes(), value.as_bytes(), ecx.memory_mut());
27+
let var_ptr =
28+
alloc_env_var(name.as_bytes(), value.as_bytes(), ecx.memory_mut());
2829
ecx.machine.env_vars.map.insert(name.into_bytes(), var_ptr);
2930
}
3031
}
@@ -46,17 +47,16 @@ fn alloc_env_var<'mir, 'tcx>(
4647

4748
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
4849
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
49-
fn getenv(
50-
&mut self,
51-
name_op: OpTy<'tcx, Tag>,
52-
) -> InterpResult<'tcx, Scalar<Tag>> {
50+
fn getenv(&mut self, name_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, Scalar<Tag>> {
5351
let this = self.eval_context_mut();
5452

5553
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
5654
let name = this.memory().read_c_str(name_ptr)?;
5755
Ok(match this.machine.env_vars.map.get(name) {
5856
// The offset is used to strip the "{name}=" part of the string.
59-
Some(var_ptr) => Scalar::Ptr(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?),
57+
Some(var_ptr) => {
58+
Scalar::Ptr(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
59+
}
6060
None => Scalar::ptr_null(&*this.tcx),
6161
})
6262
}
@@ -81,18 +81,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8181
if let Some((name, value)) = new {
8282
let var_ptr = alloc_env_var(&name, &value, this.memory_mut());
8383
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), var_ptr) {
84-
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
84+
this.memory_mut()
85+
.deallocate(var, None, MiriMemoryKind::Env.into())?;
8586
}
8687
Ok(0)
8788
} else {
8889
Ok(-1)
8990
}
9091
}
9192

92-
fn unsetenv(
93-
&mut self,
94-
name_op: OpTy<'tcx, Tag>,
95-
) -> InterpResult<'tcx, i32> {
93+
fn unsetenv(&mut self, name_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
9694
let this = self.eval_context_mut();
9795

9896
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
@@ -105,7 +103,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
105103
}
106104
if let Some(old) = success {
107105
if let Some(var) = old {
108-
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
106+
this.memory_mut()
107+
.deallocate(var, None, MiriMemoryKind::Env.into())?;
109108
}
110109
Ok(0)
111110
} else {
@@ -124,25 +123,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
124123
throw_unsup_format!("Function not available when isolation is enabled")
125124
}
126125

127-
let tcx = &{this.tcx.tcx};
126+
let tcx = &{ this.tcx.tcx };
128127

129128
let buf = this.force_ptr(this.read_scalar(buf_op)?.not_undef()?)?;
130129
let size = this.read_scalar(size_op)?.to_usize(&*this.tcx)?;
131130
// If we cannot get the current directory, we return null
132131
// FIXME: Technically we have to set the `errno` global too
133132
match env::current_dir() {
134-
Ok(cwd) =>{
133+
Ok(cwd) => {
135134
// It is not clear what happens with non-utf8 paths here
136135
let mut bytes = cwd.display().to_string().into_bytes();
137136
// If the buffer is smaller or equal than the path, we return null.
138137
if (bytes.len() as u64) < size {
139138
// We add a `/0` terminator
140139
bytes.push(0);
141140
// This is ok because the buffer is larger than the path with the null terminator.
142-
this.memory_mut().get_mut(buf.alloc_id)?.write_bytes(tcx, buf, &bytes)?;
143-
return Ok(Scalar::Ptr(buf))
141+
this.memory_mut()
142+
.get_mut(buf.alloc_id)?
143+
.write_bytes(tcx, buf, &bytes)?;
144+
return Ok(Scalar::Ptr(buf));
144145
}
145-
this.machine.last_error = 34; // ERANGE
146+
this.machine.last_error = this
147+
.eval_path_scalar(&["libc", "ERANGE"])?
148+
.unwrap()
149+
.to_u32()?;
146150
}
147151
Err(e) => this.machine.last_error = e.raw_os_error().unwrap() as u32,
148152
}

0 commit comments

Comments
 (0)