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.