@@ -4485,6 +4485,61 @@ def test_openpty(self):
4485
4485
self .assertEqual (os .get_inheritable (master_fd ), False )
4486
4486
self .assertEqual (os .get_inheritable (slave_fd ), False )
4487
4487
4488
+ @unittest .skipUnless (hasattr (os , 'spawnl' ), "need os.openpty()" )
4489
+ def test_pipe_spawnl (self ):
4490
+ # gh-77046: On Windows, os.pipe() file descriptors must be created with
4491
+ # _O_NOINHERIT to make them non-inheritable. UCRT has no public API to
4492
+ # get (_osfile(fd) & _O_NOINHERIT), so use a functional test.
4493
+ #
4494
+ # Make sure that fd is not inherited by a child process created by
4495
+ # os.spawnl(): get_osfhandle() and dup() must fail with EBADF.
4496
+
4497
+ fd , fd2 = os .pipe ()
4498
+ self .addCleanup (os .close , fd )
4499
+ self .addCleanup (os .close , fd2 )
4500
+
4501
+ code = textwrap .dedent (f"""
4502
+ import errno
4503
+ import os
4504
+ import test.support
4505
+ try:
4506
+ import msvcrt
4507
+ except ImportError:
4508
+ msvcrt = None
4509
+
4510
+ fd = { fd }
4511
+
4512
+ with test.support.SuppressCrashReport():
4513
+ if msvcrt is not None:
4514
+ try:
4515
+ handle = msvcrt.get_osfhandle(fd)
4516
+ except OSError as exc:
4517
+ if exc.errno != errno.EBADF:
4518
+ raise
4519
+ # get_osfhandle(fd) failed with EBADF as expected
4520
+ else:
4521
+ raise Exception("get_osfhandle() must fail")
4522
+
4523
+ try:
4524
+ fd3 = os.dup(fd)
4525
+ except OSError as exc:
4526
+ if exc.errno != errno.EBADF:
4527
+ raise
4528
+ # os.dup(fd) failed with EBADF as expected
4529
+ else:
4530
+ os.close(fd3)
4531
+ raise Exception("dup must fail")
4532
+ """ )
4533
+
4534
+ filename = os_helper .TESTFN
4535
+ self .addCleanup (os_helper .unlink , os_helper .TESTFN )
4536
+ with open (filename , "w" ) as fp :
4537
+ print (code , file = fp , end = "" )
4538
+
4539
+ cmd = [sys .executable , filename ]
4540
+ exitcode = os .spawnl (os .P_WAIT , cmd [0 ], * cmd )
4541
+ self .assertEqual (exitcode , 0 )
4542
+
4488
4543
4489
4544
class PathTConverterTests (unittest .TestCase ):
4490
4545
# tuples of (function name, allows fd arguments, additional arguments to
0 commit comments