diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2016-03-10 10:36:00 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-03-10 10:36:00 +0100 |
commit | f368589492fa19e62049f2f654e4127216515bc6 (patch) | |
tree | a7e22ac831ee8e0193d3f9e717babc24a4f2c793 /winsup/cygwin/sec_posixacl.cc | |
parent | 48511f3d3847c35352d09cded56e25f0c1b22bc9 (diff) | |
download | cygnal-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.cc | 58 |
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 |