Skip to content

cmake: Fix '-E touch_nocreate' on broken symlink

Jack Guo requested to merge jackguo380/cmake:TouchNoCreate into master

So took at stab at fixing #21002 (closed). Essentially what I found was that PathExists is being used which calls lstat which specifically handles symlinks without resolving them. From the man page:

lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to.

I changed the call to FileExists which is just a call to access. I found that this works with the existing use cases of touch:

  • Creating a new file
  • Updating the timestamp of a existing file or directory
  • Updating the timestamp of a file or directory behind a symlink

This also fixes the corner cases, including the one I was facing:

  • Creating the target of a broken symlink (used to result in an error)
    • E.g. ln -s missingfile.txt brokenlink.txt && cmake -E touch brokenlink.txt results in cmake -E touch: failed to update "brokenlink.txt".
    • The unix touch command is able to do this.
  • Silently ignore when using touch no create on a broken symlink (used to result in an error like above).
    • The unix touch command with -c is able to do this.

While I was at it, I added some unit tests and "RunCMake" tests to check these cases. I only am able to test on my Linux system so I guess I will need to rely on CI for other platforms.

Fixes: #21002 (closed)

Edited by buildbot

Merge request reports