diff options
Diffstat (limited to 'engine/SCons/Platform/win32.py')
| -rw-r--r-- | engine/SCons/Platform/win32.py | 60 | 
1 files changed, 36 insertions, 24 deletions
diff --git a/engine/SCons/Platform/win32.py b/engine/SCons/Platform/win32.py index 3eff40f..b386afa 100644 --- a/engine/SCons/Platform/win32.py +++ b/engine/SCons/Platform/win32.py @@ -30,7 +30,7 @@ selection method.  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  # -__revision__ = "src/engine/SCons/Platform/win32.py 72ae09dc35ac2626f8ff711d8c4b30b6138e08e3 2019-08-08 14:50:06 bdeegan" +__revision__ = "src/engine/SCons/Platform/win32.py bee7caf9defd6e108fc2998a2520ddb36a967691 2019-12-17 02:07:09 bdeegan"  import os  import os.path @@ -51,10 +51,6 @@ try:      import msvcrt      import win32api      import win32con - -    msvcrt.get_osfhandle -    win32api.SetHandleInformation -    win32con.HANDLE_FLAG_INHERIT  except ImportError:      parallel_msg = \          "you do not seem to have the pywin32 extensions installed;\n" + \ @@ -66,28 +62,44 @@ except AttributeError:  else:      parallel_msg = None -    _builtin_open = open +    if sys.version_info.major == 2: +        import __builtin__ + +        _builtin_file = __builtin__.file +        _builtin_open = __builtin__.open + +        def _scons_fixup_mode(mode): +            """Adjust 'mode' to mark handle as non-inheritable. + +            SCons is multithreaded, so allowing handles to be inherited by +            children opens us up to races, where (e.g.) processes spawned by +            the Taskmaster may inherit and retain references to files opened +            by other threads. This may lead to sharing violations and, +            ultimately, build failures. + +            By including 'N' as part of fopen's 'mode' parameter, all file +            handles returned from these functions are atomically marked as +            non-inheritable. +            """ +            if not mode: +                # Python's default is 'r'. +                # https://docs.python.org/2/library/functions.html#open +                mode = 'rN' +            elif 'N' not in mode: +                mode += 'N' +            return mode -    def _scons_open(*args, **kw): -        fp = _builtin_open(*args, **kw) -        win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), -                                      win32con.HANDLE_FLAG_INHERIT, -                                      0) -        return fp +        class _scons_file(_builtin_file): +            def __init__(self, name, mode=None, *args, **kwargs): +                _builtin_file.__init__(self, name, _scons_fixup_mode(mode), +                                       *args, **kwargs) -    open = _scons_open +        def _scons_open(name, mode=None, *args, **kwargs): +            return _builtin_open(name, _scons_fixup_mode(mode), +                                 *args, **kwargs) -    if sys.version_info.major == 2: -        _builtin_file = file -        class _scons_file(_builtin_file): -            def __init__(self, *args, **kw): -                _builtin_file.__init__(self, *args, **kw) -                win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), -                 win32con.HANDLE_FLAG_INHERIT, 0) -        file = _scons_file -    else: -        # No longer needed for python 3.4 and above. Files are opened non sharable -        pass +        __builtin__.file = _scons_file +        __builtin__.open = _scons_open  | 
