summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/sec_posixacl.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2016-03-10 10:36:00 +0100
committerCorinna Vinschen <corinna@vinschen.de>2016-03-10 10:36:00 +0100
commitf368589492fa19e62049f2f654e4127216515bc6 (patch)
treea7e22ac831ee8e0193d3f9e717babc24a4f2c793 /winsup/cygwin/sec_posixacl.cc
parent48511f3d3847c35352d09cded56e25f0c1b22bc9 (diff)
downloadcygnal-f368589492fa19e62049f2f654e4127216515bc6.tar.gz
cygnal-f368589492fa19e62049f2f654e4127216515bc6.tar.bz2
cygnal-f368589492fa19e62049f2f654e4127216515bc6.zip
Revamp acl_extended_fd/acl_extended_file to avoid open(2) call
Calling open from acl_extended_file{_nofollow} indiscriminately may hang if the file is a FIFO. Ultimately the FIFO implementation needs a thorough rewrite, but for the time being we better do what stat(2) and friends do: Just create an fhandler directly. * sec_posixacl.cc (__acl_extended_fh): New static function calling fhandler::facl. (acl_extended_fd): Just call __acl_extended_fh. (__acl_extended_file): Take just a path_conv as parameter and create temporary fhandler to call __acl_extended_fh. (acl_extended_file): Create path_conv from incoming path and call __acl_extended_file on it. (acl_extended_file_nofollow): Ditto. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/sec_posixacl.cc')
-rw-r--r--winsup/cygwin/sec_posixacl.cc58
1 files changed, 44 insertions, 14 deletions
diff --git a/winsup/cygwin/sec_posixacl.cc b/winsup/cygwin/sec_posixacl.cc
index 8760ad5ec..6345220f3 100644
--- a/winsup/cygwin/sec_posixacl.cc
+++ b/winsup/cygwin/sec_posixacl.cc
@@ -953,6 +953,22 @@ acl_error (int code)
return acl_err_txt[code - ACL_MULTI_ERROR];
}
+static int
+__acl_extended_fh (fhandler_base *fh)
+{
+ int ret = -1;
+
+ if (!fh->pc.has_acls ())
+ set_errno (ENOTSUP);
+ else
+ {
+ ret = fh->facl (GETACLCNT, 0, NULL);
+ if (ret >= 0)
+ ret = (ret > MIN_ACL_ENTRIES) ? 1 : 0;
+ }
+ return ret;
+}
+
extern "C" int
acl_extended_fd (int fd)
{
@@ -961,12 +977,7 @@ acl_extended_fd (int fd)
cygheap_fdget cfd (fd);
if (cfd < 0)
__leave;
- if (!cfd->pc.has_acls ())
- {
- set_errno (ENOTSUP);
- __leave;
- }
- return cfd->facl (GETACLCNT, 0, NULL);
+ return __acl_extended_fh (cfd);
}
__except (EBADF) {}
__endtry
@@ -974,26 +985,45 @@ acl_extended_fd (int fd)
}
static int
-__acl_extended_file (const char *path_p, mode_t follow)
+__acl_extended_file (path_conv &pc)
{
- int fd = open (path_p, O_RDONLY | O_CLOEXEC | follow);
- if (fd < 0)
- return -1;
- int ret = acl_extended_fd (fd);
- close (fd);
+ int ret = -1;
+
+ __try
+ {
+ if (pc.error)
+ set_errno (pc.error);
+ else if (!pc.exists ())
+ set_errno (ENOENT);
+ else
+ {
+ fhandler_base *fh;
+
+ if (!(fh = build_fh_pc (pc)))
+ __leave;
+ ret = __acl_extended_fh (fh);
+ delete fh;
+ }
+ }
+ __except (EFAULT) {}
+ __endtry
return ret;
}
extern "C" int
acl_extended_file (const char *path_p)
{
- return __acl_extended_file (path_p, 0);
+ path_conv pc (path_p, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE,
+ stat_suffixes);
+ return __acl_extended_file (pc);
}
extern "C" int
acl_extended_file_nofollow (const char *path_p)
{
- return __acl_extended_file (path_p, O_NOFOLLOW);
+ path_conv pc (path_p, PC_SYM_NOFOLLOW | PC_POSIX | PC_KEEP_HANDLE,
+ stat_suffixes);
+ return __acl_extended_file (pc);
}
extern "C" acl_t