Skip to content

Commit b936588

Browse files
committed
get_inheritable, dup for windows
1 parent 7250b1f commit b936588

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

Lib/test/test_os.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4621,7 +4621,6 @@ def test_process_cpu_count_affinity(self):
46214621
# FD inheritance check is only useful for systems with process support.
46224622
@support.requires_subprocess()
46234623
class FDInheritanceTests(unittest.TestCase):
4624-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
46254624
def test_get_set_inheritable(self):
46264625
fd = os.open(__file__, os.O_RDONLY)
46274626
self.addCleanup(os.close, fd)
@@ -4682,7 +4681,6 @@ def test_get_set_inheritable_badf(self):
46824681
os.set_inheritable(fd, False)
46834682
self.assertEqual(ctx.exception.errno, errno.EBADF)
46844683

4685-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
46864684
def test_open(self):
46874685
fd = os.open(__file__, os.O_RDONLY)
46884686
self.addCleanup(os.close, fd)
@@ -4696,7 +4694,6 @@ def test_pipe(self):
46964694
self.assertEqual(os.get_inheritable(rfd), False)
46974695
self.assertEqual(os.get_inheritable(wfd), False)
46984696

4699-
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON; os.dup on windows')
47004697
def test_dup(self):
47014698
fd1 = os.open(__file__, os.O_RDONLY)
47024699
self.addCleanup(os.close, fd1)
@@ -4705,13 +4702,11 @@ def test_dup(self):
47054702
self.addCleanup(os.close, fd2)
47064703
self.assertEqual(os.get_inheritable(fd2), False)
47074704

4708-
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON; os.dup on windows')
47094705
def test_dup_standard_stream(self):
47104706
fd = os.dup(1)
47114707
self.addCleanup(os.close, fd)
47124708
self.assertGreater(fd, 0)
47134709

4714-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.dup not implemented yet for all platforms')
47154710
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
47164711
def test_dup_nul(self):
47174712
# os.dup() was creating inheritable fds for character files.

crates/vm/src/stdlib/nt.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,13 @@ pub(crate) mod module {
391391
}
392392
}
393393

394+
#[pyfunction]
395+
fn get_inheritable(fd: i32, vm: &VirtualMachine) -> PyResult<bool> {
396+
let borrowed = unsafe { crt_fd::Borrowed::borrow_raw(fd) };
397+
let handle = crt_fd::as_handle(borrowed).map_err(|e| e.to_pyexception(vm))?;
398+
get_handle_inheritable(handle.as_raw_handle() as _, vm)
399+
}
400+
394401
#[pyfunction]
395402
fn getlogin(vm: &VirtualMachine) -> PyResult<String> {
396403
let mut buffer = [0u16; 257];
@@ -477,6 +484,8 @@ pub(crate) mod module {
477484

478485
unsafe extern "C" {
479486
fn _umask(mask: i32) -> i32;
487+
fn _dup(fd: i32) -> i32;
488+
fn _dup2(fd: i32, fd2: i32) -> i32;
480489
}
481490

482491
#[pyfunction]
@@ -489,6 +498,45 @@ pub(crate) mod module {
489498
}
490499
}
491500

501+
#[pyfunction]
502+
fn dup(fd: i32, vm: &VirtualMachine) -> PyResult<i32> {
503+
let fd2 = unsafe { suppress_iph!(_dup(fd)) };
504+
if fd2 < 0 {
505+
return Err(errno_err(vm));
506+
}
507+
// Set the new fd as non-inheritable
508+
let borrowed = unsafe { crt_fd::Borrowed::borrow_raw(fd2) };
509+
let handle = crt_fd::as_handle(borrowed).map_err(|e| e.to_pyexception(vm))?;
510+
raw_set_handle_inheritable(handle.as_raw_handle() as _, false)
511+
.map_err(|e| e.to_pyexception(vm))?;
512+
Ok(fd2)
513+
}
514+
515+
#[derive(FromArgs)]
516+
struct Dup2Args {
517+
#[pyarg(positional)]
518+
fd: i32,
519+
#[pyarg(positional)]
520+
fd2: i32,
521+
#[pyarg(any, default = true)]
522+
inheritable: bool,
523+
}
524+
525+
#[pyfunction]
526+
fn dup2(args: Dup2Args, vm: &VirtualMachine) -> PyResult<i32> {
527+
let result = unsafe { suppress_iph!(_dup2(args.fd, args.fd2)) };
528+
if result < 0 {
529+
return Err(errno_err(vm));
530+
}
531+
if !args.inheritable {
532+
let borrowed = unsafe { crt_fd::Borrowed::borrow_raw(args.fd2) };
533+
let handle = crt_fd::as_handle(borrowed).map_err(|e| e.to_pyexception(vm))?;
534+
raw_set_handle_inheritable(handle.as_raw_handle() as _, false)
535+
.map_err(|e| e.to_pyexception(vm))?;
536+
}
537+
Ok(args.fd2)
538+
}
539+
492540
pub(crate) fn support_funcs() -> Vec<SupportFunc> {
493541
Vec::new()
494542
}

0 commit comments

Comments
 (0)