tests/test-stdio.py
changeset 45147 c2c862b9b544
parent 45104 eb26a9cf7821
child 45148 a37f290a7124
equal deleted inserted replaced
45146:a0791bfd9cfa 45147:c2c862b9b544
    12 import sys
    12 import sys
    13 import tempfile
    13 import tempfile
    14 import unittest
    14 import unittest
    15 
    15 
    16 from mercurial import pycompat
    16 from mercurial import pycompat
       
    17 
       
    18 
       
    19 if pycompat.ispy3:
       
    20 
       
    21     def set_noninheritable(fd):
       
    22         # On Python 3, file descriptors are non-inheritable by default.
       
    23         pass
       
    24 
       
    25 
       
    26 else:
       
    27     if pycompat.iswindows:
       
    28         # unused
       
    29         set_noninheritable = None
       
    30     else:
       
    31         import fcntl
       
    32 
       
    33         def set_noninheritable(fd):
       
    34             old = fcntl.fcntl(fd, fcntl.F_GETFD)
       
    35             fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
    17 
    36 
    18 
    37 
    19 TEST_BUFFERING_CHILD_SCRIPT = r'''
    38 TEST_BUFFERING_CHILD_SCRIPT = r'''
    20 import os
    39 import os
    21 
    40 
    62                 os.close(fd)
    81                 os.close(fd)
    63             except EnvironmentError:
    82             except EnvironmentError:
    64                 pass
    83                 pass
    65 
    84 
    66 
    85 
       
    86 # In the following, we set the FDs non-inheritable mainly to make it possible
       
    87 # for tests to close the receiving end of the pipe / PTYs.
       
    88 
       
    89 
    67 @contextlib.contextmanager
    90 @contextlib.contextmanager
    68 def _devnull():
    91 def _devnull():
    69     devnull = os.open(os.devnull, os.O_WRONLY)
    92     devnull = os.open(os.devnull, os.O_WRONLY)
       
    93     # We don't have a receiving end, so it's not worth the effort on Python 2
       
    94     # on Windows to make the FD non-inheritable.
    70     with _closing([devnull]):
    95     with _closing([devnull]):
    71         yield (None, devnull)
    96         yield (None, devnull)
    72 
    97 
    73 
    98 
    74 @contextlib.contextmanager
    99 @contextlib.contextmanager
    75 def _pipes():
   100 def _pipes():
    76     rwpair = os.pipe()
   101     rwpair = os.pipe()
       
   102     # Pipes are already non-inheritable on Windows.
       
   103     if not pycompat.iswindows:
       
   104         set_noninheritable(rwpair[0])
       
   105         set_noninheritable(rwpair[1])
    77     with _closing(rwpair):
   106     with _closing(rwpair):
    78         yield rwpair
   107         yield rwpair
    79 
   108 
    80 
   109 
    81 @contextlib.contextmanager
   110 @contextlib.contextmanager
    84         raise unittest.SkipTest("PTYs are not supported on Windows")
   113         raise unittest.SkipTest("PTYs are not supported on Windows")
    85     import pty
   114     import pty
    86     import tty
   115     import tty
    87 
   116 
    88     rwpair = pty.openpty()
   117     rwpair = pty.openpty()
       
   118     set_noninheritable(rwpair[0])
       
   119     set_noninheritable(rwpair[1])
    89     with _closing(rwpair):
   120     with _closing(rwpair):
    90         tty.setraw(rwpair[0])
   121         tty.setraw(rwpair[0])
    91         yield rwpair
   122         yield rwpair
    92 
   123 
    93 
   124