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

tdeio/tdeio

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

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.6.3
This website is maintained by Timothy Pearson.