summaryrefslogtreecommitdiff
authorar <ar>2004-06-15 22:33:30 (UTC)
committer ar <ar>2004-06-15 22:33:30 (UTC)
commit80bf424ffc8394026c8bea825d91413b472d502a (patch) (side-by-side diff)
treebf0aa66a5743d5389626de9d6e3a4366eb61cea2
parent4b1fb9237a832aaa34c97421165916e1583b8b1a (diff)
downloadopie-80bf424ffc8394026c8bea825d91413b472d502a.zip
opie-80bf424ffc8394026c8bea825d91413b472d502a.tar.gz
opie-80bf424ffc8394026c8bea825d91413b472d502a.tar.bz2
- remove sendfile. it doesn't work on linux kernel 2.6 and on mac os x
- cleanup code
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/filemanager.cpp308
1 files changed, 98 insertions, 210 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index adfe590..47af1c6 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -1,440 +1,328 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
+
#include "filemanager.h"
#include "applnk.h"
+/* QT */
+#include <qdir.h>
#include <qfileinfo.h>
#include <qtextstream.h>
-#include <errno.h>
+/* STD */
#include <stdlib.h>
-#include <unistd.h>
#include <sys/stat.h>
-#include <dirent.h>
-#ifdef Q_OS_MACX
-// MacOS X does not have sendfile.. :(
-// But maybe in the future.. !?
-# ifdef SENDFILE
-# include <sys/types.h>
-# include <sys/socket.h>
-# endif
-#else
-# include <sys/sendfile.h>
-#endif /* Q_OS_MACX */
-#include <fcntl.h>
/*!
\class FileManager
\brief The FileManager class assists with AppLnk input/output.
*/
/*!
Constructs a FileManager.
*/
FileManager::FileManager()
{
}
/*!
Destroys a FileManager.
*/
FileManager::~FileManager()
{
-
}
/*!
Saves \a data as the document specified by \a f.
Returns whether the operation succeeded.
*/
bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
{
- QString fn = f.file() + ".new";
- ensurePathExists( fn );
- QFile fl( fn );
- if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
+ QString fileName = f.file() + ".new";
+ ensurePathExists( fileName );
+ QFile file( fileName );
+
+ //write data in temporary .new file
+ if ( !file.open( IO_WriteOnly|IO_Raw ) )
+ {
qWarning("open failed");
return FALSE;
}
- int total_written = fl.writeBlock( data );
- fl.close();
- if ( total_written != int(data.size()) || !f.writeLink() ) {
- QFile::remove( fn );
+ int total_written = file.writeBlock( data );
+ file.close();
+ //check if every was written
+ if ( total_written != int(data.size()) || !f.writeLink() )
+ {
+ QFile::remove( fileName );
return FALSE;
}
qDebug("total written %d out of %d", total_written, data.size());
- // else rename the file...
- if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- f.file().latin1(), errno );
- // remove the file...
- }
+
+ //rename temporary .new file in original filenam
+ if ( !renameFile( fileName, f.file() ) )
+ QFile::remove( fileName);
return TRUE;
}
/*!
Saves \a text as the document specified by \a f.
The text is saved in UTF8 format.
Returns whether the operation succeeded.
*/
bool FileManager::saveFile( const DocLnk &f, const QString &text )
{
- QString fn = f.file() + ".new";
- ensurePathExists( fn );
- QFile fl( fn );
- if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
+ QString fileName = f.file() + ".new";
+ ensurePathExists( fileName );
+ QFile file( fileName );
+
+ //write data in temporary .new file
+ if ( !file.open( IO_WriteOnly|IO_Raw ) )
+ {
qWarning("open failed");
return FALSE;
}
QCString cstr = text.utf8();
int total_written;
- total_written = fl.writeBlock( cstr.data(), cstr.length() );
- fl.close();
- if ( total_written != int(cstr.length()) || !f.writeLink() ) {
- QFile::remove( fn );
+ total_written = file.writeBlock( cstr.data(), cstr.length() );
+ file.close();
+ if ( total_written != int(cstr.length()) || !f.writeLink() )
+ {
+ QFile::remove( fileName );
return FALSE;
}
- // okay now rename the file..
- if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- f.file().latin1(), errno );
- }
+ // okay now rename the file..
+ if ( !renameFile( fileName, f.file() ) )
+ QFile::remove( fileName);
return TRUE;
}
/*!
Loads \a text from the document specified by \a f.
The text is required to be in UTF8 format.
Returns whether the operation succeeded.
*/
bool FileManager::loadFile( const DocLnk &f, QString &text )
{
QString fn = f.file();
QFile fl( fn );
if ( !fl.open( IO_ReadOnly ) )
return FALSE;
QTextStream ts( &fl );
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
// The below should work, but doesn't in Qt 2.3.0
ts.setCodec( QTextCodec::codecForMib( 106 ) );
#else
ts.setEncoding( QTextStream::UnicodeUTF8 );
#endif
text = ts.read();
fl.close();
return TRUE;
}
/*!
Loads \a ba from the document specified by \a f.
Returns whether the operation succeeded.
*/
bool FileManager::loadFile( const DocLnk &f, QByteArray &ba )
{
QString fn = f.file();
QFile fl( fn );
if ( !fl.open( IO_ReadOnly ) )
return FALSE;
ba.resize( fl.size() );
if ( fl.size() > 0 )
fl.readBlock( ba.data(), fl.size() );
fl.close();
return TRUE;
}
/*!
Copies the document specified by \a src to the document specified
by \a dest.
Returns whether the operation succeeded.
*/
bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
{
- QFile sf( src.file() );
- if ( !sf.open( IO_ReadOnly ) )
+ QFile srcFile( src.file() );
+ if ( !srcFile.open( IO_ReadOnly ) )
return FALSE;
- QString fn = dest.file() + ".new";
- ensurePathExists( fn );
- QFile df( fn );
- if ( !df.open( IO_WriteOnly|IO_Raw ) )
- return FALSE;
+ QString fileName = dest.file() + ".new";
+
+ ensurePathExists( fileName );
- const int bufsize = 16384;
- char buffer[bufsize];
bool ok = TRUE;
- int bytesRead = 0;
- while ( ok && !sf.atEnd() ) {
- bytesRead = sf.readBlock( buffer, bufsize );
- if ( bytesRead < 0 )
- ok = FALSE;
- while ( ok && bytesRead > 0 ) {
- int bytesWritten = df.writeBlock( buffer, bytesRead );
- if ( bytesWritten < 0 )
- ok = FALSE;
- else
- bytesRead -= bytesWritten;
- }
- }
+ ok = copyFile( src.file(), fileName );
if ( ok )
ok = dest.writeLink();
- if ( ok ) {
+ if ( ok )
+ {
// okay now rename the file...
- if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- dest.file().latin1(), errno );
+ if ( !renameFile( fileName.latin1(), dest.file().latin1() ) )
// remove the tmp file, otherwise, it will just lay around...
- QFile::remove( fn.latin1() );
+ QFile::remove( fileName.latin1() );
}
- } else {
- QFile::remove( fn.latin1() );
+ else
+ {
+ QFile::remove( fileName.latin1() );
}
-
return ok;
}
-bool FileManager::copyFile( const QString & src, const QString & dest ) {
- bool success = true;
- struct stat status;
- int read_fd=0;
- int write_fd=0;
- struct stat stat_buf;
- off_t offset = 0;
+bool FileManager::copyFile( const QString & src, const QString & dest )
+{
+ //open read file
QFile srcFile(src);
- QFile destFile(dest);
-
- if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
- return success = false;
- }
- read_fd = srcFile.handle();
- if(read_fd != -1) {
- fstat (read_fd, &stat_buf);
- if( !destFile.open( IO_WriteOnly|IO_Raw ) )
- return success = false;
- write_fd = destFile.handle();
- if(write_fd != -1) {
- int err=0;
- QString msg;
-#ifdef Q_OS_MACX
-#ifdef SENDFILE
- /* FreeBSD does support a different kind of
- * sendfile. (eilers)
- * I took this from Very Secure FTPd
- * Licence: GPL
- * Author: Chris Evans
- * sysdeputil.c
- */
- /* XXX - start_pos will truncate on 32-bit machines - can we
- * say "start from current pos"?
- */
- off_t written = 0;
- int retval = 0;
- retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL,
- &written, 0);
- /* Translate to Linux-like retval */
- if (written > 0)
+ if( !srcFile.open( IO_ReadOnly|IO_Raw) )
{
- err = (int) written;
- }
-#else /* SENDFILE */
- err == -1;
- msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!";
- success = false;
-# warning "Need workaround for sendfile!!(eilers)"
-#endif /* SENDFILE */
-
-#else
- err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
- if( err == -1) {
- switch(errno) {
- case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
- case EINVAL: msg = "Descriptor is not valid or locked. ";
- case ENOMEM: msg = "Insufficient memory to read from in_fd.";
- case EIO: msg = "Unspecified error while reading from in_fd.";
- };
- success = false;
- }
-#endif /* Q_OS_MACX */
- if( !success )
- qWarning( msg );
- } else {
- qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
- success = false;
- }
- } else {
qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
- success = false;
- }
- srcFile.close();
- destFile.close();
- // Set file permissions
- if( stat( (const char *) src, &status ) == 0 ) {
- chmod( (const char *) dest, status.st_mode );
- }
-
- return success;
-}
-
-
-bool FileManager::renameFile( const QString & src, const QString & dest ) {
- if(copyFile( src, dest )) {
- if(QFile::remove(src) ) {
- return true;
- }
- }
- return false;
+ return FALSE;
}
-/*
-bool FileManager::copyFile( const QString & src, const QString & dest ) {
- bool success = true;
- struct stat status;
- int read_fd=0;
- int write_fd=0;
- struct stat stat_buf;
- off_t offset = 0;
- QFile srcFile(src);
+ //open write file
QFile destFile(dest);
-
- if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
- return success = false;
- }
- read_fd = srcFile.handle();
- if(read_fd != -1) {
- fstat (read_fd, &stat_buf);
if( !destFile.open( IO_WriteOnly|IO_Raw ) )
- return success = false;
- write_fd = destFile.handle();
- if(write_fd != -1) {
- int err=0;
- QString msg;
- err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
- if( err == -1) {
- switch(err) {
- case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
- case EINVAL: msg = "Descriptor is not valid or locked. ";
- case ENOMEM: msg = "Insufficient memory to read from in_fd.";
- case EIO: msg = "Unspecified error while reading from in_fd.";
- };
- success = false;
- }
- } else {
+ {
qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
- success = false;
+ srcFile.close();
+ return FALSE;
+ }
+
+ //copy content
+ const int bufsize = 16384;
+ char buffer[bufsize];
+ bool ok = TRUE;
+ int bytesRead = 0;
+ while ( ok && !srcFile.atEnd() )
+ {
+ bytesRead = srcFile.readBlock( buffer, bufsize );
+ if ( bytesRead < 0 )
+ ok = FALSE;
+ while ( ok && bytesRead > 0 )
+ {
+ int bytesWritten = destFile.writeBlock( buffer, bytesRead );
+ if ( bytesWritten < 0 )
+ ok = FALSE;
+ else
+ bytesRead -= bytesWritten;
}
- } else {
- qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
- success = false;
}
srcFile.close();
destFile.close();
// Set file permissions
- if( stat( (const char *) src, &status ) == 0 ) {
+ struct stat status;
+ if( stat( (const char *) src, &status ) == 0 )
+ {
chmod( (const char *) dest, status.st_mode );
}
-
- return success;
+ return ok;
}
-bool FileManager::renameFile( const QString & src, const QString & dest ) {
- if(copyFile( src, dest )) {
- if(QFile::remove(src) ) {
- return true;
- }
- }
+bool FileManager::renameFile( const QString & src, const QString & dest )
+{
+ QDir dir( QFileInfo( src ).absFilePath() );
+ if ( !dir.rename( src, dest ) )
+ {
+ qWarning( "problem renaming file %s to %s", src, dest );
return false;
}
-*/
+ return true;
+}
/*!
Opens the document specified by \a f as a readable QIODevice.
The caller must delete the return value.
Returns 0 if the operation fails.
*/
QIODevice* FileManager::openFile( const DocLnk& f )
{
QString fn = f.file();
QFile* fl = new QFile( fn );
- if ( !fl->open( IO_ReadOnly ) ) {
+ if ( !fl->open( IO_ReadOnly ) )
+ {
delete fl;
fl = 0;
}
return fl;
}
/*!
Opens the document specified by \a f as a writable QIODevice.
The caller must delete the return value.
Returns 0 if the operation fails.
*/
QIODevice* FileManager::saveFile( const DocLnk& f )
{
QString fn = f.file();
ensurePathExists( fn );
QFile* fl = new QFile( fn );
- if ( fl->open( IO_WriteOnly ) ) {
+ if ( fl->open( IO_WriteOnly ) )
+ {
f.writeLink();
- } else {
+ }
+ else
+ {
delete fl;
fl = 0;
}
return fl;
}
/*!
Returns whether the document specified by \a f current exists
as a file on disk.
*/
bool FileManager::exists( const DocLnk &f )
{
return QFile::exists(f.file());
}
-
/*!
Ensures that the path \a fn exists, by creating required directories.
Returns TRUE if successful.
*/
bool FileManager::ensurePathExists( const QString &fn )
{
QFileInfo fi(fn);
fi.setFile( fi.dirPath(TRUE) );
- if ( !fi.exists() ) {
+ if ( !fi.exists() )
+ {
if ( system(("mkdir -p "+fi.filePath())) )
return FALSE;
}
return TRUE;
}