aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/syscalls.cc47
1 files changed, 11 insertions, 36 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 9c7ad61..04907b9 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -4441,7 +4441,7 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname,
cygheap_fdget cfd (dirfd);
if (cfd < 0)
return -1;
- if (!cfd->pc.isdir ())
+ if (!cfd->pc.isdir () && !(flags & AT_EMPTY_PATH))
{
set_errno (ENOTDIR);
return -1;
@@ -4452,6 +4452,8 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname,
{
if (!*pathname)
{
+ if (flags & AT_EMPTY_PATH)
+ return 0;
set_errno (ENOENT);
return -1;
}
@@ -4573,29 +4575,14 @@ fchownat (int dirfd, const char *pathname, uid_t uid, gid_t gid, int flags)
__leave;
}
char *path = tp.c_get ();
- int res = gen_full_path_at (path, dirfd, pathname);
+ int res = gen_full_path_at (path, dirfd, pathname, flags);
if (res)
+ __leave;
+ if (!*pathname) /* Implies AT_EMPTY_PATH */
{
- if (!(errno == ENOENT && (flags & AT_EMPTY_PATH)))
- __leave;
- /* pathname is an empty string. Operate on dirfd. */
- if (dirfd == AT_FDCWD)
- {
- cwdstuff::acquire_read ();
- strcpy (path, cygheap->cwd.get_posix ());
- cwdstuff::release_read ();
- }
- else
- {
- cygheap_fdget cfd (dirfd);
- if (cfd < 0)
- __leave;
- strcpy (path, cfd->get_name ());
- /* If dirfd refers to a symlink (which was necessarily
- opened with O_PATH | O_NOFOLLOW), we must operate
- directly on that symlink.. */
- flags = AT_SYMLINK_NOFOLLOW;
- }
+ /* If dirfd refers to a symlink (which was necessarily opened with
+ O_PATH | O_NOFOLLOW), we must operate directly on that symlink. */
+ flags = AT_SYMLINK_NOFOLLOW;
}
return chown_worker (path, (flags & AT_SYMLINK_NOFOLLOW)
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, uid, gid);
@@ -4618,21 +4605,9 @@ fstatat (int dirfd, const char *__restrict pathname, struct stat *__restrict st,
__leave;
}
char *path = tp.c_get ();
- int res = gen_full_path_at (path, dirfd, pathname);
+ int res = gen_full_path_at (path, dirfd, pathname, flags);
if (res)
- {
- if (!(errno == ENOENT && (flags & AT_EMPTY_PATH)))
- __leave;
- /* pathname is an empty string. Operate on dirfd. */
- if (dirfd == AT_FDCWD)
- {
- cwdstuff::acquire_read ();
- strcpy (path, cygheap->cwd.get_posix ());
- cwdstuff::release_read ();
- }
- else
- return fstat (dirfd, st);
- }
+ __leave;
path_conv pc (path, ((flags & AT_SYMLINK_NOFOLLOW)
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW)
| PC_POSIX | PC_KEEP_HANDLE, stat_suffixes);