• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

connection.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, 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     if (fflush( f_out )) {
00202     kdError(7017) << "Could not write data" << endl;
00203     return false;
00204     }
00205 
00206     return true;
00207 }
00208 
00209 int Connection::read( int* _cmd, QByteArray &data )
00210 {
00211     if (fd_in == -1 ) {
00212     kdError(7017) << "read: not yet inited" << endl;
00213     return -1;
00214     }
00215 
00216     static char buffer[ 10 ];
00217 
00218  again1:
00219     ssize_t n = ::read( fd_in, buffer, 10);
00220     if ( n == -1 && errno == EINTR )
00221     goto again1;
00222 
00223     if ( n == -1) {
00224     kdError(7017) << "Header read failed, errno=" << errno << endl;
00225     }
00226 
00227     if ( n != 10 ) {
00228       if ( n ) // 0 indicates end of file
00229         kdError(7017) << "Header has invalid size (" << n << ")" << endl;
00230       return -1;
00231     }
00232 
00233     buffer[ 6 ] = 0;
00234     buffer[ 9 ] = 0;
00235 
00236     char *p = buffer;
00237     while( *p == ' ' ) p++;
00238     long int len = strtol( p, 0L, 16 );
00239 
00240     p = buffer + 7;
00241     while( *p == ' ' ) p++;
00242     long int cmd = strtol( p, 0L, 16 );
00243 
00244     data.resize( len );
00245 
00246     if ( len > 0L ) {
00247     size_t bytesToGo = len;
00248     size_t bytesRead = 0;
00249     do {
00250         n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
00251         if (n == -1) {
00252         if (errno == EINTR)
00253             continue;
00254 
00255         kdError(7017) << "Data read failed, errno=" << errno << endl;
00256         return -1;
00257         }
00258         if ( !n ) { // 0 indicates end of file
00259             kdError(7017) << "Connection ended unexpectedly (" << n << "/" << bytesToGo << ")" << endl;
00260             return -1;
00261             }
00262 
00263         bytesRead += n;
00264         bytesToGo -= n;
00265     }
00266     while(bytesToGo);
00267     }
00268 
00269     *_cmd = cmd;
00270     return len;
00271 }
00272 
00273 #include "connection.moc"

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal