diff options
Diffstat (limited to 'src/engine/SCons/Platform/win32.py')
-rw-r--r-- | src/engine/SCons/Platform/win32.py | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 3eff40f..b386afa 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/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 |