[frameworks/kio] /: kioworkers/file: Restore ACL writes in FileProtocol::chmod()

Méven Car <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 8715dbd23a4ccd3f5cef4ef0247958a7777aa152 by Méven Car, on behalf of David Wild.
Committed on 21/07/2026 at 08:47.
Pushed by meven into branch 'master'.

kioworkers/file: Restore ACL writes in FileProtocol::chmod()


Amends c84f9435

M  +45   -0    autotests/jobtest.cpp
M  +1    -0    autotests/jobtest.h
M  +5    -3    src/kioworkers/file/file.cpp

https://invent.kde.org/frameworks/kio/-/commit/8715dbd23a4ccd3f5cef4ef0247958a7777aa152

diff --git a/autotests/jobtest.cpp b/autotests/jobtest.cpp
index dbea010037..132f12ceb7 100644
--- a/autotests/jobtest.cpp
+++ b/autotests/jobtest.cpp
@@ -2377,6 +2377,51 @@ void JobTest::chmodFile()
     QFile::remove(filePath);
 }
 
+void JobTest::chmodFileSetAcl()
+{
+#if !HAVE_POSIX_ACL
+    QSKIP("POSIX ACL support not compiled in");
+#elif defined(Q_OS_FREEBSD)
+    QSKIP("The test is not adapted for FreeBSD yet");
+#else
+    const QString filePath = homeTmpDir() + "fileForChmodAcl";
+    createTestFile(filePath);
+    KFileItem item(QUrl::fromLocalFile(filePath));
+    KFileItemList items;
+    items << item;
+    KIO::Job *job = KIO::chmod(items, item.permissions(), S_IWGRP, QString(), QString(), false, KIO::HideProgressInfo);
+    job->setUiDelegate(nullptr);
+
+    // A named-user entry makes this an *extended* ACL
+    QByteArray want = "user::rw-\nuser:root:rwx\ngroup::rw-\nmask::rwx\nother::r--\n";
+    job->addMetaData(QStringLiteral("ACL_STRING"), want);
+
+    QVERIFY2(job->exec(), qPrintable(job->errorString()));
+
+    auto aclText = [](const QByteArray &path) {
+        acl_t acl = acl_get_file(path.constData(), ACL_TYPE_ACCESS);
+        char *text = acl ? acl_to_text(acl, nullptr) : nullptr;
+        const QByteArray result = text ? QByteArray(text) : QByteArray();
+        if (text) {
+            acl_free(text);
+        }
+        if (acl) {
+            acl_free(acl);
+        }
+        return result;
+    };
+
+    const QByteArray srcEnc = QFile::encodeName(filePath);
+
+    const QByteArray srcAcl = aclText(srcEnc);
+    QVERIFY(!srcAcl.isEmpty());
+
+    QCOMPARE(aclText(srcEnc), want);
+
+    QFile::remove(filePath);
+#endif
+}
+
 #ifdef Q_OS_UNIX
 void JobTest::chmodSticky()
 {
diff --git a/autotests/jobtest.h b/autotests/jobtest.h
index 1fbbfc156d..7180c463f3 100644
--- a/autotests/jobtest.h
+++ b/autotests/jobtest.h
@@ -105,6 +105,7 @@ private Q_SLOTS:
     void mostLocalUrl();
     void mostLocalUrlHttp();
     void chmodFile();
+    void chmodFileSetAcl();    
 #ifdef Q_OS_UNIX
     void chmodSticky();
 #endif
diff --git a/src/kioworkers/file/file.cpp b/src/kioworkers/file/file.cpp
index 9485f14ac7..c1650cc7e6 100644
--- a/src/kioworkers/file/file.cpp
+++ b/src/kioworkers/file/file.cpp
@@ -172,11 +172,13 @@ WorkerResult FileProtocol::chmod(const QUrl &_url, int permissions)
     const QByteArray _path(QFile::encodeName(path));
 #ifdef Q_OS_UNIX
     // QFile::Permissions does not support special attributes like sticky
-    if (::chmod(_path.constData(), permissions) == -1)
+    if (::chmod(_path.constData(), permissions) == -1 ||
 #else
-    if (!QFile::setPermissions(path, modeToQFilePermissions(permissions)))
+    if (!QFile::setPermissions(path, modeToQFilePermissions(permissions)) ||
 #endif
-    {
+        (setACL(_path.data(), permissions, false) == -1) ||
+        /* if not a directory, cannot set default ACLs */
+        (setACL(_path.data(), permissions, true) == -1 && errno != ENOTDIR)) {
         return WorkerResult::fail(KIO::ERR_CANNOT_CHMOD, path);
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.