diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2017-07-11T21·20+0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2017-07-11T21·21+0200 |
commit | 2965d40612e16388ef2177d2a13d168848c6ca8a (patch) | |
tree | 71bc2ff5c9ca7860d4c32793940ee5fb557767b9 | |
parent | 8e8caf7f3e535d4e397f422f6c0effd81f497305 (diff) |
replaceSymlink(): Handle the case where the temporary file already exists
Not really necessary anymore for #849, but still nice to have.
-rw-r--r-- | src/libutil/util.cc | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 6bf4b3d91805..d9f8011b6fb9 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -496,12 +496,21 @@ void createSymlink(const Path & target, const Path & link) void replaceSymlink(const Path & target, const Path & link) { - Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link)); + for (unsigned int n = 0; true; n++) { + Path tmp = canonPath(fmt("%s/.%d_%s", dirOf(link), n, baseNameOf(link))); - createSymlink(target, tmp); + try { + createSymlink(target, tmp); + } catch (SysError & e) { + if (e.errNo == EEXIST) continue; + throw; + } - if (rename(tmp.c_str(), link.c_str()) != 0) - throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % link); + if (rename(tmp.c_str(), link.c_str()) != 0) + throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % link); + + break; + } } |