diff options
Diffstat (limited to 'src/libutil/util.cc')
-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; + } } |