From 57ca8d2698f1eaf30f1110ba47445c04d2bcd0f7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Dec 2015 12:08:47 +0100 Subject: make write_file() capable of making files (not) executable Change-Id: I9ca96bc3408160261781697a3471c1f446c86c3a Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 27 +++++++++++++++++++-------- qmake/library/qmakeevaluator.h | 2 +- qmake/library/qmakevfs.cpp | 17 ++++++++++++++--- qmake/library/qmakevfs.h | 2 +- tests/auto/tools/qmakelib/evaltest.cpp | 11 +++++++++-- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index f57d9c89a7..e8be2f42fd 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -358,10 +358,10 @@ static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const Q QMakeEvaluator::VisitReturn QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, - const QString &contents) + bool exe, const QString &contents) { QString errStr; - if (!m_vfs->writeFile(fn, mode, contents, &errStr)) { + if (!m_vfs->writeFile(fn, mode, exe, contents, &errStr)) { evalError(fL1S("Cannot write %1file %2: %3") .arg(ctx, QDir::toNativeSeparators(fn), errStr)); return ReturnFalse; @@ -1543,22 +1543,33 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } case T_WRITE_FILE: { if (args.count() > 3) { - evalError(fL1S("write_file(name, [content var, [append]]) requires one to three arguments.")); + evalError(fL1S("write_file(name, [content var, [append] [exe]]) requires one to three arguments.")); return ReturnFalse; } QIODevice::OpenMode mode = QIODevice::Truncate; + bool exe = false; QString contents; if (args.count() >= 2) { const ProStringList &vals = values(args.at(1).toKey()); if (!vals.isEmpty()) contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n'); - if (args.count() >= 3) - if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive)) - mode = QIODevice::Append; + if (args.count() >= 3) { + foreach (const ProString &opt, split_value_list(args.at(2).toQString(m_tmp2))) { + opt.toQString(m_tmp3); + if (m_tmp3 == QLatin1String("append")) { + mode = QIODevice::Append; + } else if (m_tmp3 == QLatin1String("exe")) { + exe = true; + } else { + evalError(fL1S("write_file(): invalid flag %1.").arg(m_tmp3)); + return ReturnFalse; + } + } + } } QString path = resolvePath(args.at(0).toQString(m_tmp1)); path.detach(); // make sure to not leak m_tmp1 into the map of written files. - return writeFile(QString(), path, mode, contents); + return writeFile(QString(), path, mode, exe, contents); } case T_TOUCH: { if (args.count() != 2) { @@ -1769,7 +1780,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn); } } - return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr); + return writeFile(fL1S("cache "), fn, QIODevice::Append, false, varstr); } default: evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1))); diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 8995d49582..b61c066193 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -235,7 +235,7 @@ public: QMultiMap &rootSet) const; VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, - const QString &contents); + bool exe, const QString &contents); #ifndef QT_BOOTSTRAPPED void runProcess(QProcess *proc, const QString &command) const; #endif diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 613e4e90d7..d23d1f06ff 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -52,8 +52,8 @@ QMakeVfs::QMakeVfs() { } -bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents, - QString *errStr) +bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, + const QString &contents, QString *errStr) { #ifndef PROEVALUATOR_FULL # ifdef PROEVALUATOR_THREAD_SAFE @@ -75,8 +75,16 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QStr QByteArray bytes = contents.toLocal8Bit(); QFile cfile(fn); if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) { - if (cfile.readAll() == bytes) + if (cfile.readAll() == bytes) { + if (exe) { + cfile.setPermissions(cfile.permissions() + | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); + } else { + cfile.setPermissions(cfile.permissions() + & ~(QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther)); + } return true; + } cfile.close(); } if (!cfile.open(mode | QIODevice::WriteOnly | QIODevice::Text)) { @@ -89,6 +97,9 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QStr *errStr = cfile.errorString(); return false; } + if (exe) + cfile.setPermissions(cfile.permissions() + | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); return true; #endif } diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h index 8eeae15dcc..1bc11d3593 100644 --- a/qmake/library/qmakevfs.h +++ b/qmake/library/qmakevfs.h @@ -52,7 +52,7 @@ class QMAKE_EXPORT QMakeVfs public: QMakeVfs(); - bool writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents, QString *errStr); + bool writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, const QString &contents, QString *errStr); bool readFile(const QString &fn, QString *contents, QString *errStr); bool exists(const QString &fn); diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index bed4c792a1..beafef5ad2 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2205,9 +2205,10 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "" << true; + // FIXME: This also tests that 'exe' is accepted, but does not test whether it actually works. QTest::newRow("write_file(): append") << "VAR = 'one more line'\n" - "write_file(" + wpath + ", VAR, append): OK = 1\n" + "write_file(" + wpath + ", VAR, append exe): OK = 1\n" "OUT = $$cat(" + wpath + ", lines)" << "OK = 1\nOUT = 'other content' 'one more line'" << "" @@ -2227,7 +2228,13 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) QTest::newRow("write_file(): bad number of arguments") << "write_file(1, 2, 3, 4): OK = 1" << "OK = UNDEF" - << "##:1: write_file(name, [content var, [append]]) requires one to three arguments." + << "##:1: write_file(name, [content var, [append] [exe]]) requires one to three arguments." + << true; + + QTest::newRow("write_file(): invalid flag") + << "write_file(file, VAR, fail): OK = 1" + << "OK = UNDEF" + << "##:1: write_file(): invalid flag fail." << true; // FIXME: This doesn't test whether it actually works. -- cgit v1.2.3