Skip to content

Commit c87e3fe

Browse files
authored
Rollup merge of #51816 - nodakai:conf-py-tmpfile, r=kennytm
bootstrap: write texts to a .tmp file first for atomicity If you are using a hard-linked file as your config.toml, this change will affect the way other instances of the file is modified. The original version would modify all other instances whereas the new version will leave others unchanged, reducing the ref count by one.
2 parents d334027 + 97d0bc3 commit c87e3fe

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

src/bootstrap/bootstrap.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,19 @@ def default_build_triple():
303303
return "{}-{}".format(cputype, ostype)
304304

305305

306+
@contextlib.contextmanager
307+
def output(filepath):
308+
tmp = filepath + '.tmp'
309+
with open(tmp, 'w') as f:
310+
yield f
311+
try:
312+
os.remove(filepath) # PermissionError/OSError on Win32 if in use
313+
os.rename(tmp, filepath)
314+
except OSError:
315+
shutil.copy2(tmp, filepath)
316+
os.remove(tmp)
317+
318+
306319
class RustBuild(object):
307320
"""Provide all the methods required to build Rust"""
308321
def __init__(self):
@@ -346,7 +359,7 @@ def download_stage0(self):
346359
self._download_stage0_helper(filename, "rustc")
347360
self.fix_executable("{}/bin/rustc".format(self.bin_root()))
348361
self.fix_executable("{}/bin/rustdoc".format(self.bin_root()))
349-
with open(self.rustc_stamp(), 'w') as rust_stamp:
362+
with output(self.rustc_stamp()) as rust_stamp:
350363
rust_stamp.write(self.date)
351364

352365
# This is required so that we don't mix incompatible MinGW
@@ -363,7 +376,7 @@ def download_stage0(self):
363376
filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build)
364377
self._download_stage0_helper(filename, "cargo")
365378
self.fix_executable("{}/bin/cargo".format(self.bin_root()))
366-
with open(self.cargo_stamp(), 'w') as cargo_stamp:
379+
with output(self.cargo_stamp()) as cargo_stamp:
367380
cargo_stamp.write(self.date)
368381

369382
def _download_stage0_helper(self, filename, pattern):
@@ -776,7 +789,7 @@ def bootstrap(help_triggered):
776789
if build.use_vendored_sources:
777790
if not os.path.exists('.cargo'):
778791
os.makedirs('.cargo')
779-
with open('.cargo/config', 'w') as cargo_config:
792+
with output('.cargo/config') as cargo_config:
780793
cargo_config.write("""
781794
[source.crates-io]
782795
replace-with = 'vendored-sources'

src/bootstrap/configure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def configure_section(lines, config):
432432
# order that we read it in.
433433
p("")
434434
p("writing `config.toml` in current directory")
435-
with open('config.toml', 'w') as f:
435+
with bootstrap.output('config.toml') as f:
436436
for section in section_order:
437437
if section == 'target':
438438
for target in targets:
@@ -442,7 +442,7 @@ def configure_section(lines, config):
442442
for line in sections[section]:
443443
f.write(line + "\n")
444444

445-
with open('Makefile', 'w') as f:
445+
with bootstrap.output('Makefile') as f:
446446
contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
447447
contents = open(contents).read()
448448
contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')

0 commit comments

Comments
 (0)