QFileSystemEngine/Unix: use fchmod(2) if the file is open

This protects against the file having been renamed or deleted. We'll
still operate on the open file, regardless the name it may have on the
filesystem.

Change-Id: I1eba2b016de74620bfc8fffd14cca85cfd672e6d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2017-06-29 10:38:13 -07:00
parent fb13510681
commit 08a39ecf33
3 changed files with 32 additions and 3 deletions

View File

@ -92,6 +92,8 @@ public:
QFileSystemMetaData::MetaDataFlags what);
#if defined(Q_OS_UNIX)
static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags
static bool setPermissions(int fd, QFile::Permissions permissions, QSystemError &error,
QFileSystemMetaData *data = nullptr);
#endif
#if defined(Q_OS_WIN)

View File

@ -659,8 +659,7 @@ bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &
}
//static
bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data)
static mode_t toMode_t(QFile::Permissions permissions)
{
mode_t mode = 0;
if (permissions & (QFile::ReadOwner | QFile::ReadUser))
@ -681,6 +680,13 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per
mode |= S_IWOTH;
if (permissions & QFile::ExeOther)
mode |= S_IXOTH;
return mode;
}
//static
bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data)
{
mode_t mode = toMode_t(permissions);
bool success = ::chmod(entry.nativeFilePath().constData(), mode) == 0;
if (success && data) {
@ -693,6 +699,22 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per
return success;
}
//static
bool QFileSystemEngine::setPermissions(int fd, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data)
{
mode_t mode = toMode_t(permissions);
bool success = ::fchmod(fd, mode) == 0;
if (success && data) {
data->entryFlags &= ~QFileSystemMetaData::Permissions;
data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions));
data->knownFlagsMask |= QFileSystemMetaData::Permissions;
}
if (!success)
error = QSystemError(errno, QSystemError::StandardLibraryError);
return success;
}
QString QFileSystemEngine::homePath()
{
QString home = QFile::decodeName(qgetenv("HOME"));

View File

@ -654,7 +654,12 @@ bool QFSFileEngine::setPermissions(uint perms)
{
Q_D(QFSFileEngine);
QSystemError error;
if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error, 0)) {
bool ok;
if (d->fd != -1)
ok = QFileSystemEngine::setPermissions(d->fd, QFile::Permissions(perms), error, 0);
else
ok = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error, 0);
if (!ok) {
setError(QFile::PermissionsError, error.toString());
return false;
}