kio Library: connection.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# connection.cpp

    00001 /* This file is part of the KDE libraries
    00002     Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
    00003                        David Faure <faure@kde.org>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public License
    00016     along with this library; see the file COPYING.LIB.  If not, write to
    00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00018     Boston, MA 02111-1307, USA.
    00019 */
    00020
    00021 // $Id$
    00022
    00023 #include <config.h>
    00024
    00025 #include <kde_file.h>
    00026 #include <ksock.h>
    00027 #include <qtimer.h>
    00028
    00029 #include <sys/types.h>
    00030 #include <sys/signal.h>
    00031 #include <sys/time.h>
    00032
    00033 #include <errno.h>
    00034 #include <fcntl.h>
    00035 #include <stdio.h>
    00036 #include <stdlib.h>
    00037 #include <signal.h>
    00038 #include <string.h>
    00039 #include <unistd.h>
    00040
    00041 #include "kio/connection.h"
    00042
    00043 #include <kdebug.h>
    00044 #include <qsocketnotifier.h>
    00045
    00046 using namespace KIO;
    00047
    00048 Connection::Connection()
    00049 {
    00050     f_out = 0;
    00051     fd_in = -1;
    00052     socket = 0;
    00053     notifier = 0;
    00054     receiver = 0;
    00055     member = 0;
    00056     m_suspended = false;
    00057     tasks.setAutoDelete(true);
    00058 }
    00059
    00060 Connection::~Connection()
    00061 {
    00062     close();
    00063 }
    00064
    00065 void Connection::suspend()
    00066 {
    00067     m_suspended = true;
    00068     if (notifier)
    00069        notifier->setEnabled(false);
    00070 }
    00071
    00072 void Connection::resume()
    00073 {
    00074     m_suspended = false;
    00075     if (notifier)
    00076        notifier->setEnabled(true);
    00077 }
    00078
    00079 void Connection::close()
    00080 {
    00081     delete notifier;
    00082     notifier = 0;
    00083     delete socket;
    00084     socket = 0;
    00085
    00086     // KSocket has already closed the file descriptor, but we need to
    00087     // close the file-stream as well otherwise we leak memory.
    00088     // As a result we close the file descriptor twice, but that should
    00089     // be harmless
    00090     // KDE4: fix this
    00091     if (f_out)
    00092        fclose(f_out);
    00093     f_out = 0;
    00094     fd_in = -1;
    00095     tasks.clear();
    00096 }
    00097
    00098 void Connection::send(int cmd, const QByteArray& data)
    00099 {
    00100     if (!inited() || tasks.count() > 0) {
    00101     Task *task = new Task();
    00102     task->cmd = cmd;
    00103     task->data = data;
    00104     tasks.append(task);
    00105     } else {
    00106     sendnow( cmd, data );
    00107     }
    00108 }
    00109
    00110 void Connection::dequeue()
    00111 {
    00112     if (!inited())
    00113     return;
    00114
    00115     while (tasks.count())
    00116     {
    00117        tasks.first();
    00118        Task *task = tasks.take();
    00119        sendnow( task->cmd, task->data );
    00120        delete task;
    00121     }
    00122 }
    00123
    00124 void Connection::init(KSocket *sock)
    00125 {
    00126     delete notifier;
    00127     notifier = 0;
    00128 #ifdef Q_OS_UNIX //TODO: not yet available on WIN32
    00129     delete socket;
    00130     socket = sock;
    00131     fd_in = socket->socket();
    00132     f_out = KDE_fdopen( socket->socket(), "wb" );
    00133 #endif
    00134     if (receiver && ( fd_in != -1 )) {
    00135     notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00136     if ( m_suspended ) {
    00137             suspend();
    00138     }
    00139     QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00140     }
    00141     dequeue();
    00142 }
    00143
    00144 void Connection::init(int _fd_in, int fd_out)
    00145 {
    00146     delete notifier;
    00147     notifier = 0;
    00148     fd_in = _fd_in;
    00149     f_out = KDE_fdopen( fd_out, "wb" );
    00150     if (receiver && ( fd_in != -1 )) {
    00151     notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00152     if ( m_suspended ) {
    00153             suspend();
    00154     }
    00155     QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00156     }
    00157     dequeue();
    00158 }
    00159
    00160
    00161 void Connection::connect(QObject *_receiver, const char *_member)
    00162 {
    00163     receiver = _receiver;
    00164     member = _member;
    00165     delete notifier;
    00166     notifier = 0;
    00167     if (receiver && (fd_in != -1 )) {
    00168     notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00169         if ( m_suspended )
    00170             suspend();
    00171     QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00172     }
    00173 }
    00174
    00175 bool Connection::sendnow( int _cmd, const QByteArray &data )
    00176 {
    00177     if (f_out == 0) {
    00178     return false;
    00179     }
    00180
    00181     if (data.size() > 0xffffff)
    00182         return false;
    00183
    00184     static char buffer[ 64 ];
    00185     sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
    00186
    00187     size_t n = fwrite( buffer, 1, 10, f_out );
    00188
    00189     if ( n != 10 ) {
    00190     kdError(7017) << "Could not send header" << endl;
    00191     return false;
    00192     }
    00193
    00194     n = fwrite( data.data(), 1, data.size(), f_out );
    00195
    00196     if ( n != data.size() ) {
    00197     kdError(7017) << "Could not write data" << endl;
    00198     return false;
    00199     }
    00200
    00201     fflush( f_out );
    00202
    00203     return true;
    00204 }
    00205
    00206 int Connection::read( int* _cmd, QByteArray &data )
    00207 {
    00208     if (fd_in == -1 ) {
    00209     kdError(7017) << "read: not yet inited" << endl;
    00210     return -1;
    00211     }
    00212
    00213     static char buffer[ 10 ];
    00214
    00215  again1:
    00216     ssize_t n = ::read( fd_in, buffer, 10);
    00217     if ( n == -1 && errno == EINTR )
    00218     goto again1;
    00219
    00220     if ( n == -1) {
    00221     kdError(7017) << "Header read failed, errno=" << errno << endl;
    00222     }
    00223
    00224     if ( n != 10 ) {
    00225       if ( n ) // 0 indicates end of file
    00226         kdError(7017) << "Header has invalid size (" << n << ")" << endl;
    00227       return -1;
    00228     }
    00229
    00230     buffer[ 6 ] = 0;
    00231     buffer[ 9 ] = 0;
    00232
    00233     char *p = buffer;
    00234     while( *p == ' ' ) p++;
    00235     long int len = strtol( p, 0L, 16 );
    00236
    00237     p = buffer + 7;
    00238     while( *p == ' ' ) p++;
    00239     long int cmd = strtol( p, 0L, 16 );
    00240
    00241     data.resize( len );
    00242
    00243     if ( len > 0L ) {
    00244     size_t bytesToGo = len;
    00245     size_t bytesRead = 0;
    00246     do {
    00247         n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
    00248         if (n == -1) {
    00249         if (errno == EINTR)
    00250             continue;
    00251
    00252         kdError(7017) << "Data read failed, errno=" << errno << endl;
    00253         return -1;
    00254         }
    00255
    00256         bytesRead += n;
    00257         bytesToGo -= n;
    00258     }
    00259     while(bytesToGo);
    00260     }
    00261
    00262     *_cmd = cmd;
    00263     return len;
    00264 }
    00265
    00266 #include "connection.moc"

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:52 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003