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>
This commit is contained in:
parent
48511f3d38
commit
f368589492
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue