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