__try
{
char *path = tp.c_get ();
- if (gen_full_path_at (path, dirfd, pathname))
- __leave;
+ int res = gen_full_path_at (path, dirfd, pathname);
+ if (res)
+ {
+ if (errno != ENOENT)
+ __leave;
+ /* pathname is an empty string. This is OK if dirfd refers
+ to a symlink that was opened with O_PATH | O_NOFOLLOW.
+ In this case, readlinkat operates on the symlink. */
+ cygheap_fdget cfd (dirfd);
+ if (cfd < 0)
+ __leave;
+ if (!(cfd->issymlink ()
+ && cfd->get_flags () & O_PATH
+ && cfd->get_flags () & O_NOFOLLOW))
+ __leave;
+ strcpy (path, cfd->get_name ());
+ }
return readlink (path, buf, bufsize);
}
__except (EFAULT) {}