| Index: build/extract_from_cab.py
|
| diff --git a/build/extract_from_cab.py b/build/extract_from_cab.py
|
| index d04bcfd14aa6c25ec2a56d3d4527ff6de58b08b2..d5410d64d8e6a0af24508da30345222c07e82377 100755
|
| --- a/build/extract_from_cab.py
|
| +++ b/build/extract_from_cab.py
|
| @@ -6,29 +6,11 @@
|
| """Extracts a single file from a CAB archive."""
|
|
|
| import os
|
| +import shutil
|
| import subprocess
|
| import sys
|
| import tempfile
|
|
|
| -lock_file = os.path.join(tempfile.gettempdir(), 'expand.lock')
|
| -
|
| -
|
| -def acquire_lock():
|
| - while True:
|
| - try:
|
| - fd = os.open(lock_file, os.O_CREAT | os.O_EXCL | os.O_RDWR)
|
| - return fd
|
| - except OSError as e:
|
| - if e.errno != errno.EEXIST:
|
| - raise
|
| - print 'Cab extraction could not get exclusive lock. Retrying in 100ms...'
|
| - time.sleep(0.1)
|
| -
|
| -
|
| -def release_lock(fd):
|
| - os.close(fd)
|
| - os.unlink(lock_file)
|
| -
|
|
|
| def main():
|
| if len(sys.argv) != 4:
|
| @@ -37,15 +19,30 @@ def main():
|
|
|
| [cab_path, archived_file, output_dir] = sys.argv[1:]
|
|
|
| - lock_fd = acquire_lock()
|
| + # Expand.exe does its work in a fixed-named temporary directory created within
|
| + # the given output directory. This is a problem for concurrent extractions, so
|
| + # create a unique temp dir within the desired output directory to work around
|
| + # this limitation.
|
| + temp_dir = tempfile.mkdtemp(dir=output_dir)
|
| +
|
| try:
|
| # Invoke the Windows expand utility to extract the file.
|
| level = subprocess.call(
|
| - ['expand', cab_path, '-F:' + archived_file, output_dir])
|
| - if level != 0:
|
| - return level
|
| + ['expand', cab_path, '-F:' + archived_file, temp_dir])
|
| + if level == 0:
|
| + # Move the output file into place, preserving expand.exe's behavior of
|
| + # paving over any preexisting file.
|
| + output_file = os.path.join(output_dir, archived_file)
|
| + try:
|
| + os.remove(output_file)
|
| + except OSError:
|
| + pass
|
| + os.rename(os.path.join(temp_dir, archived_file), output_file)
|
| finally:
|
| - release_lock(lock_fd)
|
| + shutil.rmtree(temp_dir, True)
|
| +
|
| + if level != 0:
|
| + return level
|
|
|
| # The expand utility preserves the modification date and time of the archived
|
| # file. Touch the extracted file. This helps build systems that compare the
|
|
|