예제 #1
0
/* antlarr: KDE 4.0:  make the first parameter "const QString &" */
bool KConfigINIBackEnd::writeConfigFile(QString filename, bool bGlobal, bool bMerge)
{
    // is the config object read-only?
    if(pConfig->isReadOnly())
        return true; // pretend we wrote it

    KEntryMap aTempMap;
    QFile *mergeFile = (bMerge ? new QFile(filename) : 0);
    bool bEntriesLeft = getEntryMap(aTempMap, bGlobal, mergeFile);
    delete mergeFile;
    if(bFileImmutable)
        return true; // pretend we wrote it

    // OK now the temporary map should be full of ALL entries.
    // write it out to disk.

    // Check if file exists:
    int fileMode = -1;
    bool createNew = true;

    KDE_struct_stat buf;
    if(KDE_stat(QFile::encodeName(filename), &buf) == 0)
    {
        if(buf.st_uid == getuid())
        {
            // Preserve file mode if file exists and is owned by user.
            fileMode = buf.st_mode & 0777;
        }
        else
        {
            // File is not owned by user:
            // Don't create new file but write to existing file instead.
            createNew = false;
        }
    }

    KSaveFile *pConfigFile = 0;
    FILE *pStream = 0;

    if(createNew)
    {
        pConfigFile = new KSaveFile(filename, 0600);

        if(pConfigFile->status() != 0)
        {
            delete pConfigFile;
            return bEntriesLeft;
        }

        if(!bGlobal && (fileMode == -1))
            fileMode = mFileMode;

        if(fileMode != -1)
        {
            fchmod(pConfigFile->handle(), fileMode);
        }

        pStream = pConfigFile->fstream();
    }
    else
    {
        // Open existing file.
        // We use open() to ensure that we call without O_CREAT.
        int fd = KDE_open(QFile::encodeName(filename), O_WRONLY | O_TRUNC);
        if(fd < 0)
        {
            return bEntriesLeft;
        }
        pStream = KDE_fdopen(fd, "w");
        if(!pStream)
        {
            close(fd);
            return bEntriesLeft;
        }
    }

    writeEntries(pStream, aTempMap);

    if(pConfigFile)
    {
        bool bEmptyFile = (ftell(pStream) == 0);
        if(bEmptyFile && ((fileMode == -1) || (fileMode == 0600)))
        {
            // File is empty and doesn't have special permissions: delete it.
            ::unlink(QFile::encodeName(filename));
            pConfigFile->abort();
        }
        else
        {
            // Normal case: Close the file
            pConfigFile->close();
        }
        delete pConfigFile;
    }
    else
    {
        fclose(pStream);
    }

    return bEntriesLeft;
}
예제 #2
0
void KSaveFileTest::test_ksavefile()
{
    QString targetFile;

    {
        //This will be the file we eventually write to. Yes, I know you
        //should never remove the temporaryfile and then expect the filename
        //to continue to be unique, but this is a test for crying out loud. :)
        KTemporaryFile file;
        file.setPrefix("ksavefiletest");
        QVERIFY( file.open() );
        targetFile = file.fileName();
    }

    {
        //Test basic functionality
        KSaveFile saveFile;
        saveFile.setFileName(targetFile);
        QVERIFY( saveFile.open() );
        QVERIFY( !QFile::exists(targetFile) );

        QTextStream ts ( &saveFile );
        ts << "This is test data one.\n";
        ts.flush();
        QCOMPARE( saveFile.error(), QFile::NoError );
        QVERIFY( !QFile::exists(targetFile) );

        QVERIFY( saveFile.finalize() );
        QVERIFY( QFile::exists(targetFile) );

        QFile::remove(targetFile);
        QVERIFY( !QFile::exists(targetFile) );
    }

    {
        //Make sure destructor does what it is supposed to do.
        {
            KSaveFile saveFile;
            saveFile.setFileName(targetFile);
            QVERIFY( saveFile.open() );
            QVERIFY( !QFile::exists(targetFile) );
        }

        QVERIFY( QFile::exists(targetFile) );
        QFile::remove(targetFile);
        QVERIFY( !QFile::exists(targetFile) );
    }

    {
        //Test some error conditions
        KSaveFile saveFile;
        QVERIFY( !saveFile.open() ); //no filename
        saveFile.setFileName(targetFile);
        QVERIFY( saveFile.open() );
        QVERIFY( !QFile::exists(targetFile) );
        QVERIFY( !saveFile.open() ); //already open

        QVERIFY( saveFile.finalize() );
        QVERIFY( QFile::exists(targetFile) );
        QVERIFY( !saveFile.finalize() ); //already finalized

        QFile::remove(targetFile);
        QVERIFY( !QFile::exists(targetFile) );
    }

    {
        //Do it again, aborting this time
        KSaveFile saveFile ( targetFile );
        QVERIFY( saveFile.open() );
        QVERIFY( !QFile::exists(targetFile) );

        QTextStream ts ( &saveFile );
        ts << "This is test data two.\n";
        ts.flush();
        QCOMPARE( saveFile.error(), QFile::NoError );
        QVERIFY( !QFile::exists(targetFile) );

        saveFile.abort();
        QVERIFY( !QFile::exists(targetFile) );
    }

    QFile file ( targetFile );
    QVERIFY( file.open(QIODevice::WriteOnly | QIODevice::Text) );
    QVERIFY( file.setPermissions( file.permissions() | QFile::ExeUser ) );
    file.close();

    {
        //Test how it works when the file already exists
        //Also check for special permissions
        KSaveFile saveFile ( targetFile );
        QVERIFY( saveFile.open() );

        QVERIFY( QFile::exists(targetFile) );
        QFileInfo fi ( targetFile );

#ifndef Q_WS_WIN
        // Windows: qt_ntfs_permission_lookup is not set by default in
        // qfsfileengine_win.cpp, could change in future Qt versions.
        QVERIFY( fi.permission( QFile::ExeUser ) );
#endif
        QVERIFY( fi.size() == 0 );

        QTextStream ts ( &saveFile );
        ts << "This is test data three.\n";
        ts.flush();

        fi.refresh();
        QVERIFY( fi.size() == 0 );
        QVERIFY( saveFile.finalize() );

        fi.refresh();
        QVERIFY( fi.size() != 0 );
#ifndef Q_WS_WIN
        QVERIFY( fi.permission( QFile::ExeUser ) );
#endif

        QFile::remove(targetFile);
    }

    {
        QFileInfo fi ( targetFile );
        targetFile = fi.fileName();
        QDir::setCurrent(fi.path());

        //one more time, this time with relative filenames
        KSaveFile saveFile ( targetFile );
        QVERIFY( saveFile.open() );
        QVERIFY( !QFile::exists(targetFile) );

        QTextStream ts ( &saveFile );
        ts << "This is test data four.\n";
        ts.flush();
        QCOMPARE( saveFile.error(), QFile::NoError );
        QVERIFY( !QFile::exists(targetFile) );

        QVERIFY( saveFile.finalize() );
        QVERIFY( QFile::exists(targetFile) );
        QFile::remove(targetFile);
    }

}