Skip to content

Commit 78c4228

Browse files
committed
Honor mmap trackfd on Unix
When trackfd is false, do not keep a duplicated file descriptor. size() then fails with EBADF and resize() raises ValueError. Assisted-by: Grok:grok-4.6
1 parent 8bcef35 commit 78c4228

2 files changed

Lines changed: 16 additions & 3 deletions

File tree

‎Lib/test/test_mmap.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ def test_access_parameter(self):
271271
self.assertRaises(TypeError, m.write_byte, 0)
272272
m.close()
273273

274-
@unittest.expectedFailure # TODO: RUSTPYTHON
275274
@unittest.skipIf(os.name == 'nt', 'trackfd not present on Windows')
276275
def test_trackfd_parameter(self):
277276
size = 64
@@ -307,7 +306,6 @@ def test_trackfd_parameter(self):
307306
self.assertEqual(m.closed, True)
308307
self.assertEqual(os.stat(TESTFN).st_size, size)
309308

310-
@unittest.expectedFailure # TODO: RUSTPYTHON
311309
@unittest.skipIf(os.name == 'nt', 'trackfd not present on Windows')
312310
def test_trackfd_neg1(self):
313311
size = 64

‎crates/stdlib/src/mmap.rs‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ mod mmap {
188188
pos: AtomicCell<usize>, // relative to offset
189189
exports: AtomicCell<usize>,
190190
access: AccessMode,
191+
#[cfg(unix)]
192+
trackfd: bool,
191193
}
192194

193195
impl PyMmap {
@@ -229,6 +231,8 @@ mod mmap {
229231
access: AccessMode,
230232
#[pyarg(any, default = 0)]
231233
offset: i64,
234+
#[pyarg(any, default = true)]
235+
trackfd: bool,
232236
}
233237

234238
#[cfg(windows)]
@@ -364,6 +368,7 @@ mod mmap {
364368
prot,
365369
access,
366370
offset,
371+
trackfd,
367372
..
368373
} = args;
369374

@@ -443,12 +448,17 @@ mod mmap {
443448
Ok(Self {
444449
closed: AtomicCell::new(false),
445450
mmap: PyMutex::new(Some(MmapObj::Mapped(mmap))),
446-
fd: AtomicCell::new(fd.map_or(-1, |fd| fd.into_raw())),
451+
fd: AtomicCell::new(if trackfd {
452+
fd.map_or(-1, |owned| owned.into_raw())
453+
} else {
454+
-1
455+
}),
447456
offset,
448457
size: AtomicCell::new(map_size),
449458
pos: AtomicCell::new(0),
450459
exports: AtomicCell::new(0),
451460
access,
461+
trackfd,
452462
})
453463
}
454464

@@ -752,6 +762,11 @@ mod mmap {
752762
return Err(vm.new_buffer_error("mmap can't resize with extant buffers exported."));
753763
}
754764

765+
#[cfg(unix)]
766+
if !self.trackfd {
767+
return Err(vm.new_value_error("mmap can't resize with trackfd=False."));
768+
}
769+
755770
if self.access == AccessMode::Write || self.access == AccessMode::Default {
756771
return Ok(());
757772
}

0 commit comments

Comments
 (0)