Jinoh Kang (@iamahuman) commented about server/fd.c:
+ { + if (!(dirname = memdup( dst, dstname - dst ))) + return; + dirname[dstname - dst - 1] = '\0'; + if ((res = stat( dirname, &st ))) + file_set_error(); + free( dirname ); + if (res) + return; + } + + srcname = strrchr( src, '/' ) + 1; + if (!(dirname = memdup( src, srcname - src ))) + return; + dirname[srcname - src - 1] = '\0'; + if ((dirfd = open( dirname, O_RDONLY | O_NONBLOCK )) == -1) Better open the destination file's directory instead of the source file's directory.
1. We may only have search access to src directory but not read access (--x). 2. `O_PATH` is only available on Linux-like OSes. `O_SEARCH` is also not cross platform. Notably, macOS lacks `O_PATH`. To achieve this, we can switch the order: do stat() on src dirname, and open/fstat on dest dirname. If different directories, it must be a hardlink, so we simply remove the source and bail out. If the same, switching order did nothing, and we can proceed as normal. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6855#note_97185