Skip to content

Commit 41f0bdf

Browse files
ravenAtSafebdbaddog
authored andcommitted
Prevent files from being partially read from the cache
1 parent 038dc4b commit 41f0bdf

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

SCons/CacheDir.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,20 @@ def CacheRetrieveFunc(target, source, env) -> int:
6666
if fs.islink(cachefile):
6767
fs.symlink(fs.readlink(cachefile), t.get_internal_path())
6868
else:
69-
cd.copy_from_cache(env, cachefile, t.get_internal_path())
69+
try:
70+
env.copy_from_cache(cachefile, t.get_internal_path())
71+
except:
72+
try:
73+
# In case file was partially retrieved (and now corrupt)
74+
# delete it to avoid poisoning commands like 'ar' that
75+
# read from the initial state of the file they are writing
76+
# to.
77+
t.fs.unlink(t.get_internal_path())
78+
except:
79+
pass
80+
81+
raise
82+
7083
try:
7184
os.utime(cachefile, None)
7285
except OSError:
@@ -80,8 +93,8 @@ def CacheRetrieveString(target, source, env) -> str:
8093
cd = env.get_CacheDir()
8194
cachedir, cachefile = cd.cachepath(t)
8295
if t.fs.exists(cachefile):
83-
return "Retrieved `%s' from cache" % t.get_internal_path()
84-
return ""
96+
return "Retrieving `%s' from cache" % t.get_internal_path()
97+
return None
8598

8699
CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)
87100

SCons/Taskmaster/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,13 @@ def execute(self):
233233
cached_targets.append(t)
234234
if len(cached_targets) < len(self.targets):
235235
# Remove targets before building. It's possible that we
236-
# partially retrieved targets from the cache, leaving
237-
# them in read-only mode. That might cause the command
236+
# retrieved a subset of targets from the cache, leaving
237+
# them in an inconsistent state. That might cause the command
238238
# to fail.
239239
#
240+
# Note that retrieve_from_cache() ensures no single target can
241+
# be partially retrieved (file left in corrupt state).
242+
#
240243
for t in cached_targets:
241244
try:
242245
t.fs.unlink(t.get_internal_path())

0 commit comments

Comments
 (0)