-rw-r--r-- | library/filemanager.cpp | 67 |
1 files changed, 55 insertions, 12 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp index cc657fa..91986a0 100644 --- a/library/filemanager.cpp +++ b/library/filemanager.cpp @@ -10,49 +10,58 @@ ** ** 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" #include <qdir.h> #include <qfile.h> #include <qfileinfo.h> #include <qtextstream.h> #include <qtextcodec.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <dirent.h> -#include <sys/sendfile.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. @@ -195,81 +204,115 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) ok = FALSE; else bytesRead -= bytesWritten; } } if ( ok ) ok = dest.writeLink(); 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 ); // remove the tmp file, otherwise, it will just lay around... QFile::remove( fn.latin1() ); } } else { QFile::remove( fn.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; 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; - 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 { +#ifdef Q_OS_MACX +#ifdef SENDMAIL + /* 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) + { + err = (int) written; + } +#else /* SENDMAIL */ + err == -1; + msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!"; + success = false; +# warning "Need workaround for sendfile!!(eilers)" +#endif /* SENDMAIL */ + +#else + 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; + } +#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; } } |