• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kio/kio
 

kio/kio

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., 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 <tqtimer.h>
00028 
00029 #include <sys/types.h>
00030 #include <sys/time.h>
00031 
00032 #include <errno.h>
00033 #include <fcntl.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <signal.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039 
00040 #include "kio/connection.h"
00041 
00042 #include <kdebug.h>
00043 #include <tqsocketnotifier.h>
00044 
00045 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
00046 #define __progname getprogname()
00047 #elif defined(_GNU_SOURCE) && defined(__GLIBC__)
00048 #define __progname program_invocation_short_name
00049 #else
00050 extern char *__progname;
00051 #endif
00052 
00053 using namespace KIO;
00054 
00055 Connection::Connection()
00056 {
00057     f_out = 0;
00058     fd_in = -1;
00059     socket = 0;
00060     notifier = 0;
00061     receiver = 0;
00062     member = 0;
00063     m_suspended = false;
00064     tasks.setAutoDelete(true);
00065 }
00066 
00067 Connection::~Connection()
00068 {
00069     close();
00070 }
00071 
00072 void Connection::suspend()
00073 {
00074     m_suspended = true;
00075     if (notifier)
00076        notifier->setEnabled(false);
00077 }
00078 
00079 void Connection::resume()
00080 {
00081     m_suspended = false;
00082     if (notifier)
00083        notifier->setEnabled(true);
00084 }
00085 
00086 void Connection::close()
00087 {
00088     delete notifier;
00089     notifier = 0;
00090     delete socket;
00091     socket = 0;
00092 
00093     // KSocket has already closed the file descriptor, but we need to
00094     // close the file-stream as well otherwise we leak memory. 
00095     // As a result we close the file descriptor twice, but that should
00096     // be harmless
00097     // KDE4: fix this
00098     if (f_out)
00099        fclose(f_out);
00100     f_out = 0;
00101     fd_in = -1;
00102     tasks.clear();
00103 }
00104 
00105 void Connection::send(int cmd, const TQByteArray& data)
00106 {
00107     if (!inited() || tasks.count() > 0) {
00108     Task *task = new Task();
00109     task->cmd = cmd;
00110     task->data = data;
00111     tasks.append(task);
00112     } else {
00113     sendnow( cmd, data );
00114     }
00115 }
00116 
00117 void Connection::dequeue()
00118 {
00119     if (!inited())
00120     return;
00121 
00122     while (tasks.count())
00123     {
00124        tasks.first();
00125        Task *task = tasks.take();
00126        sendnow( task->cmd, task->data );
00127        delete task;
00128     }
00129 }
00130 
00131 void Connection::init(KSocket *sock)
00132 {
00133     delete notifier;
00134     notifier = 0;
00135 #ifdef Q_OS_UNIX //TODO: not yet available on WIN32
00136     delete socket;
00137     socket = sock;
00138     fd_in = socket->socket();
00139     f_out = KDE_fdopen( socket->socket(), "wb" );
00140 #endif
00141     if (receiver && ( fd_in != -1 )) {
00142     notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
00143     if ( m_suspended ) {
00144             suspend();
00145     }
00146     TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
00147     }
00148     dequeue();
00149 }
00150 
00151 void Connection::init(int _fd_in, int fd_out)
00152 {
00153     delete notifier;
00154     notifier = 0;
00155     fd_in = _fd_in;
00156     f_out = KDE_fdopen( fd_out, "wb" );
00157     if (receiver && ( fd_in != -1 )) {
00158     notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
00159     if ( m_suspended ) {
00160             suspend();
00161     }
00162     TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
00163     }
00164     dequeue();
00165 }
00166 
00167 
00168 void Connection::connect(TQObject *_receiver, const char *_member)
00169 {
00170     receiver = _receiver;
00171     member = _member;
00172     delete notifier;
00173     notifier = 0;
00174     if (receiver && (fd_in != -1 )) {
00175     notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
00176         if ( m_suspended )
00177             suspend();
00178     TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
00179     }
00180 }
00181 
00182 bool Connection::sendnow( int _cmd, const TQByteArray &data )
00183 {
00184     if (f_out == 0) {
00185     return false;
00186     }
00187 
00188     if (data.size() > 0xffffff)
00189         return false;
00190 
00191     static char buffer[ 64 ];
00192     sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
00193 
00194     size_t n = fwrite( buffer, 1, 10, f_out );
00195 
00196     if ( n != 10 ) {
00197     kdError(7017) << "Could not send header (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00198     return false;
00199     }
00200 
00201     n = fwrite( data.data(), 1, data.size(), f_out );
00202 
00203     if ( n != data.size() ) {
00204     kdError(7017) << "Could not write data (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00205     return false;
00206     }
00207 
00208     if (fflush( f_out )) {
00209     kdError(7017) << "Could not write data (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00210     return false;
00211     }
00212 
00213     return true;
00214 }
00215 
00216 int Connection::read( int* _cmd, TQByteArray &data )
00217 {
00218     if (fd_in == -1 ) {
00219     kdError(7017) << "read: not yet inited (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00220     return -1;
00221     }
00222 
00223     static char buffer[ 10 ];
00224 
00225  again1:
00226     ssize_t n = ::read( fd_in, buffer, 10);
00227     if ( n == -1 && errno == EINTR )
00228     goto again1;
00229 
00230     if ( n == -1) {
00231     kdError(7017) << "Header read failed, errno=" << errno << " (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00232     }
00233 
00234     if ( n != 10 ) {
00235       if ( n ) // 0 indicates end of file
00236         kdError(7017) << "Header has invalid size (" << n << ") (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00237       return -1;
00238     }
00239 
00240     buffer[ 6 ] = 0;
00241     buffer[ 9 ] = 0;
00242 
00243     char *p = buffer;
00244     while( *p == ' ' ) p++;
00245     long int len = strtol( p, 0L, 16 );
00246 
00247     p = buffer + 7;
00248     while( *p == ' ' ) p++;
00249     long int cmd = strtol( p, 0L, 16 );
00250 
00251     data.resize( len );
00252 
00253     if ( len > 0L ) {
00254     size_t bytesToGo = len;
00255     size_t bytesRead = 0;
00256     do {
00257         n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
00258         if (n == -1) {
00259         if (errno == EINTR)
00260             continue;
00261 
00262         kdError(7017) << "Data read failed, errno=" << errno << " (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00263         return -1;
00264         }
00265         if ( !n ) { // 0 indicates end of file
00266             kdError(7017) << "Connection ended unexpectedly (" << n << "/" << bytesToGo << ") (pid " << getpid() << " process \"" << __progname << "\")" << endl;
00267             return -1;
00268             }
00269 
00270         bytesRead += n;
00271         bytesToGo -= n;
00272     }
00273     while(bytesToGo);
00274     }
00275 
00276     *_cmd = cmd;
00277     return len;
00278 }
00279 
00280 #include "connection.moc"

kio/kio

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

kio/kio

Skip menu "kio/kio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kio/kio by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |