Skip to content

Commit e9a390a

Browse files
committed
Auto merge of #3770 - oli-obk:duplicator, r=oli-obk
Some FileDescriptor/FileDescription refactorings follow-up to #3763 (comment) I opted not to change the method names, as I think they are already pretty good (and the common one is the short name), and the docs should explain what they actually do, but if you feel like the names you proposed would be better, I'll just do that.
2 parents 3fbdc82 + 1ecd186 commit e9a390a

File tree

2 files changed

+37
-33
lines changed

2 files changed

+37
-33
lines changed

src/shims/unix/fd.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,13 @@ impl FileDescription for NullOutput {
197197
}
198198

199199
#[derive(Clone, Debug)]
200-
pub struct FileDescriptor(Rc<RefCell<Box<dyn FileDescription>>>);
200+
pub struct FileDescriptionRef(Rc<RefCell<Box<dyn FileDescription>>>);
201+
202+
impl FileDescriptionRef {
203+
fn new(fd: impl FileDescription) -> Self {
204+
FileDescriptionRef(Rc::new(RefCell::new(Box::new(fd))))
205+
}
201206

202-
impl FileDescriptor {
203207
pub fn borrow(&self) -> Ref<'_, dyn FileDescription> {
204208
Ref::map(self.0.borrow(), |fd| fd.as_ref())
205209
}
@@ -221,7 +225,7 @@ impl FileDescriptor {
221225
/// The file descriptor table
222226
#[derive(Debug)]
223227
pub struct FdTable {
224-
pub fds: BTreeMap<i32, FileDescriptor>,
228+
fds: BTreeMap<i32, FileDescriptionRef>,
225229
}
226230

227231
impl VisitProvenance for FdTable {
@@ -247,14 +251,14 @@ impl FdTable {
247251
fds
248252
}
249253

250-
/// Insert a file descriptor to the FdTable.
251-
pub fn insert_fd<T: FileDescription>(&mut self, fd: T) -> i32 {
252-
let file_handle = FileDescriptor(Rc::new(RefCell::new(Box::new(fd))));
254+
/// Insert a new file description to the FdTable.
255+
pub fn insert_fd(&mut self, fd: impl FileDescription) -> i32 {
256+
let file_handle = FileDescriptionRef::new(fd);
253257
self.insert_fd_with_min_fd(file_handle, 0)
254258
}
255259

256260
/// Insert a new FD that is at least `min_fd`.
257-
pub fn insert_fd_with_min_fd(&mut self, file_handle: FileDescriptor, min_fd: i32) -> i32 {
261+
fn insert_fd_with_min_fd(&mut self, file_handle: FileDescriptionRef, min_fd: i32) -> i32 {
258262
// Find the lowest unused FD, starting from min_fd. If the first such unused FD is in
259263
// between used FDs, the find_map combinator will return it. If the first such unused FD
260264
// is after all other used FDs, the find_map combinator will return None, and we will use
@@ -290,12 +294,12 @@ impl FdTable {
290294
Some(fd.borrow_mut())
291295
}
292296

293-
pub fn dup(&self, fd: i32) -> Option<FileDescriptor> {
297+
pub fn dup(&self, fd: i32) -> Option<FileDescriptionRef> {
294298
let fd = self.fds.get(&fd)?;
295299
Some(fd.clone())
296300
}
297301

298-
pub fn remove(&mut self, fd: i32) -> Option<FileDescriptor> {
302+
pub fn remove(&mut self, fd: i32) -> Option<FileDescriptionRef> {
299303
self.fds.remove(&fd)
300304
}
301305

@@ -324,9 +328,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
324328
if new_fd != old_fd {
325329
// Close new_fd if it is previously opened.
326330
// If old_fd and new_fd point to the same description, then `dup_fd` ensures we keep the underlying file description alive.
327-
if let Some(file_descriptor) = this.machine.fds.fds.insert(new_fd, dup_fd) {
331+
if let Some(file_description) = this.machine.fds.fds.insert(new_fd, dup_fd) {
328332
// Ignore close error (not interpreter's) according to dup2() doc.
329-
file_descriptor.close(this.machine.communicate())?.ok();
333+
file_description.close(this.machine.communicate())?.ok();
330334
}
331335
}
332336
Ok(new_fd)
@@ -427,10 +431,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
427431

428432
let fd = this.read_scalar(fd_op)?.to_i32()?;
429433

430-
let Some(file_descriptor) = this.machine.fds.remove(fd) else {
434+
let Some(file_description) = this.machine.fds.remove(fd) else {
431435
return Ok(Scalar::from_i32(this.fd_not_found()?));
432436
};
433-
let result = file_descriptor.close(this.machine.communicate())?;
437+
let result = file_description.close(this.machine.communicate())?;
434438
// return `0` if close is successful
435439
let result = result.map(|()| 0i32);
436440
Ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))

src/shims/unix/fs.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -576,13 +576,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
576576

577577
let communicate = this.machine.communicate();
578578

579-
let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else {
579+
let Some(mut file_description) = this.machine.fds.get_mut(fd) else {
580580
return Ok(Scalar::from_i64(this.fd_not_found()?));
581581
};
582-
let result = file_descriptor
582+
let result = file_description
583583
.seek(communicate, seek_from)?
584584
.map(|offset| i64::try_from(offset).unwrap());
585-
drop(file_descriptor);
585+
drop(file_description);
586586

587587
let result = this.try_unwrap_io_result(result)?;
588588
Ok(Scalar::from_i64(result))
@@ -1269,30 +1269,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12691269
return Ok(Scalar::from_i32(this.fd_not_found()?));
12701270
}
12711271

1272-
let Some(file_descriptor) = this.machine.fds.get(fd) else {
1272+
let Some(file_description) = this.machine.fds.get(fd) else {
12731273
return Ok(Scalar::from_i32(this.fd_not_found()?));
12741274
};
12751275

12761276
// FIXME: Support ftruncate64 for all FDs
12771277
let FileHandle { file, writable } =
1278-
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
1278+
file_description.downcast_ref::<FileHandle>().ok_or_else(|| {
12791279
err_unsup_format!("`ftruncate64` is only supported on file-backed file descriptors")
12801280
})?;
12811281

12821282
if *writable {
12831283
if let Ok(length) = length.try_into() {
12841284
let result = file.set_len(length);
1285-
drop(file_descriptor);
1285+
drop(file_description);
12861286
let result = this.try_unwrap_io_result(result.map(|_| 0i32))?;
12871287
Ok(Scalar::from_i32(result))
12881288
} else {
1289-
drop(file_descriptor);
1289+
drop(file_description);
12901290
let einval = this.eval_libc("EINVAL");
12911291
this.set_last_error(einval)?;
12921292
Ok(Scalar::from_i32(-1))
12931293
}
12941294
} else {
1295-
drop(file_descriptor);
1295+
drop(file_description);
12961296
// The file is not writable
12971297
let einval = this.eval_libc("EINVAL");
12981298
this.set_last_error(einval)?;
@@ -1322,16 +1322,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13221322

13231323
fn ffullsync_fd(&mut self, fd: i32) -> InterpResult<'tcx, i32> {
13241324
let this = self.eval_context_mut();
1325-
let Some(file_descriptor) = this.machine.fds.get(fd) else {
1325+
let Some(file_description) = this.machine.fds.get(fd) else {
13261326
return Ok(this.fd_not_found()?);
13271327
};
13281328
// Only regular files support synchronization.
13291329
let FileHandle { file, writable } =
1330-
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
1330+
file_description.downcast_ref::<FileHandle>().ok_or_else(|| {
13311331
err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
13321332
})?;
13331333
let io_result = maybe_sync_file(file, *writable, File::sync_all);
1334-
drop(file_descriptor);
1334+
drop(file_description);
13351335
this.try_unwrap_io_result(io_result)
13361336
}
13371337

@@ -1347,16 +1347,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13471347
return this.fd_not_found();
13481348
}
13491349

1350-
let Some(file_descriptor) = this.machine.fds.get(fd) else {
1350+
let Some(file_description) = this.machine.fds.get(fd) else {
13511351
return Ok(this.fd_not_found()?);
13521352
};
13531353
// Only regular files support synchronization.
13541354
let FileHandle { file, writable } =
1355-
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
1355+
file_description.downcast_ref::<FileHandle>().ok_or_else(|| {
13561356
err_unsup_format!("`fdatasync` is only supported on file-backed file descriptors")
13571357
})?;
13581358
let io_result = maybe_sync_file(file, *writable, File::sync_data);
1359-
drop(file_descriptor);
1359+
drop(file_description);
13601360
this.try_unwrap_io_result(io_result)
13611361
}
13621362

@@ -1395,18 +1395,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13951395
return Ok(Scalar::from_i32(this.fd_not_found()?));
13961396
}
13971397

1398-
let Some(file_descriptor) = this.machine.fds.get(fd) else {
1398+
let Some(file_description) = this.machine.fds.get(fd) else {
13991399
return Ok(Scalar::from_i32(this.fd_not_found()?));
14001400
};
14011401
// Only regular files support synchronization.
14021402
let FileHandle { file, writable } =
1403-
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
1403+
file_description.downcast_ref::<FileHandle>().ok_or_else(|| {
14041404
err_unsup_format!(
14051405
"`sync_data_range` is only supported on file-backed file descriptors"
14061406
)
14071407
})?;
14081408
let io_result = maybe_sync_file(file, *writable, File::sync_data);
1409-
drop(file_descriptor);
1409+
drop(file_description);
14101410
Ok(Scalar::from_i32(this.try_unwrap_io_result(io_result)?))
14111411
}
14121412

@@ -1702,11 +1702,11 @@ impl FileMetadata {
17021702
ecx: &mut MiriInterpCx<'tcx>,
17031703
fd: i32,
17041704
) -> InterpResult<'tcx, Option<FileMetadata>> {
1705-
let Some(file_descriptor) = ecx.machine.fds.get(fd) else {
1705+
let Some(file_description) = ecx.machine.fds.get(fd) else {
17061706
return ecx.fd_not_found().map(|_: i32| None);
17071707
};
17081708

1709-
let file = &file_descriptor
1709+
let file = &file_description
17101710
.downcast_ref::<FileHandle>()
17111711
.ok_or_else(|| {
17121712
err_unsup_format!(
@@ -1716,7 +1716,7 @@ impl FileMetadata {
17161716
.file;
17171717

17181718
let metadata = file.metadata();
1719-
drop(file_descriptor);
1719+
drop(file_description);
17201720
FileMetadata::from_meta(ecx, metadata)
17211721
}
17221722

0 commit comments

Comments
 (0)