Index: build/extract_from_cab.py |
diff --git a/build/extract_from_cab.py b/build/extract_from_cab.py |
index d04bcfd14aa6c25ec2a56d3d4527ff6de58b08b2..76ee88865b9a0ab02ee368ccd0776f65fb3ad06d 100755 |
--- a/build/extract_from_cab.py |
+++ b/build/extract_from_cab.py |
@@ -10,25 +10,6 @@ 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 +18,39 @@ 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: |
+ # Setup the environment in case other versions of expand.exe do their work |
+ # in TEMP/TMP instead of or in addition to the output directory. |
+ subprocess_env = os.environ.copy() |
+ subprocess_env['TEMP'] = temp_dir |
M-A Ruel
2011/12/13 19:35:54
Can you pinpoint which of the two it's using and o
grt (UTC plus 2)
2011/12/13 19:47:24
The Win7 version I tested uses neither; it uses th
M-A Ruel
2011/12/13 19:51:35
Well, if the code has no effect, I'd rather remove
grt (UTC plus 2)
2011/12/13 20:06:44
Looks like TEMP/TMP aren't used in XP, so I've rem
|
+ subprocess_env['TMP'] = temp_dir |
# 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], |
+ env=subprocess_env) |
+ 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) |
+ try: |
+ os.rmdir(temp_dir) |
M-A Ruel
2011/12/13 19:35:54
Yes, shutil.rmtree(temp_dir, True) is better.
grt (UTC plus 2)
2011/12/13 19:47:24
Done.
|
+ except OSError: |
+ print 'Warning: unable to delete temporary directory ' + temp_dir |
+ |
+ 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 |