connection.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include <ksock.h>
00026 #include <qtimer.h>
00027
00028 #include <sys/types.h>
00029 #include <sys/signal.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 <qsocketnotifier.h>
00044
00045 using namespace KIO;
00046
00047 Connection::Connection()
00048 {
00049 f_out = 0;
00050 fd_in = -1;
00051 socket = 0;
00052 notifier = 0;
00053 receiver = 0;
00054 member = 0;
00055 m_suspended = false;
00056 tasks.setAutoDelete(true);
00057 }
00058
00059 Connection::~Connection()
00060 {
00061 close();
00062 }
00063
00064 void Connection::suspend()
00065 {
00066 m_suspended = true;
00067 if (notifier)
00068 notifier->setEnabled(false);
00069 }
00070
00071 void Connection::resume()
00072 {
00073 m_suspended = false;
00074 if (notifier)
00075 notifier->setEnabled(true);
00076 }
00077
00078 void Connection::close()
00079 {
00080 delete notifier;
00081 notifier = 0;
00082 delete socket;
00083 socket = 0;
00084 if (f_out)
00085 fclose(f_out);
00086 f_out = 0;
00087 fd_in = -1;
00088 tasks.clear();
00089 }
00090
00091 void Connection::send(int cmd, const QByteArray& data)
00092 {
00093 if (!inited() || tasks.count() > 0) {
00094 Task *task = new Task();
00095 task->cmd = cmd;
00096 task->data = data;
00097 tasks.append(task);
00098 } else {
00099 sendnow( cmd, data );
00100 }
00101 }
00102
00103 void Connection::dequeue()
00104 {
00105 if (!inited())
00106 return;
00107
00108 while (tasks.count())
00109 {
00110 tasks.first();
00111 Task *task = tasks.take();
00112 sendnow( task->cmd, task->data );
00113 delete task;
00114 }
00115 }
00116
00117 void Connection::init(KSocket *sock)
00118 {
00119 delete notifier;
00120 notifier = 0;
00121 delete socket;
00122 socket = sock;
00123 fd_in = socket->socket();
00124 f_out = fdopen( socket->socket(), "wb" );
00125 if (receiver && ( fd_in != -1 )) {
00126 notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
00127 if ( m_suspended ) {
00128 suspend();
00129 }
00130 QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
00131 }
00132 dequeue();
00133 }
00134
00135 void Connection::init(int _fd_in, int fd_out)
00136 {
00137 delete notifier;
00138 notifier = 0;
00139 fd_in = _fd_in;
00140 f_out = fdopen( fd_out, "wb" );
00141 if (receiver && ( fd_in != -1 )) {
00142 notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
00143 if ( m_suspended ) {
00144 suspend();
00145 }
00146 QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
00147 }
00148 dequeue();
00149 }
00150
00151
00152 void Connection::connect(QObject *_receiver, const char *_member)
00153 {
00154 receiver = _receiver;
00155 member = _member;
00156 delete notifier;
00157 notifier = 0;
00158 if (receiver && (fd_in != -1 )) {
00159 notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
00160 if ( m_suspended )
00161 suspend();
00162 QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
00163 }
00164 }
00165
00166 bool Connection::sendnow( int _cmd, const QByteArray &data )
00167 {
00168 if (f_out == 0) {
00169 return false;
00170 }
00171
00172 if (data.size() > 0xffffff)
00173 return false;
00174
00175 static char buffer[ 64 ];
00176 sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
00177
00178 size_t n = fwrite( buffer, 1, 10, f_out );
00179
00180 if ( n != 10 ) {
00181 kdError(7017) << "Could not send header" << endl;
00182 return false;
00183 }
00184
00185 n = fwrite( data.data(), 1, data.size(), f_out );
00186
00187 if ( n != data.size() ) {
00188 kdError(7017) << "Could not write data" << endl;
00189 return false;
00190 }
00191
00192 fflush( f_out );
00193
00194 return true;
00195 }
00196
00197 int Connection::read( int* _cmd, QByteArray &data )
00198 {
00199 if (fd_in == -1 ) {
00200 kdError(7017) << "read: not yet inited" << endl;
00201 return -1;
00202 }
00203
00204 static char buffer[ 10 ];
00205
00206 again1:
00207 ssize_t n = ::read( fd_in, buffer, 10);
00208 if ( n == -1 && errno == EINTR )
00209 goto again1;
00210
00211 if ( n == -1) {
00212 kdError(7017) << "Header read failed, errno=" << errno << endl;
00213 }
00214
00215 if ( n != 10 ) {
00216 if ( n )
00217 kdError(7017) << "Header has invalid size (" << n << ")" << endl;
00218 return -1;
00219 }
00220
00221 buffer[ 6 ] = 0;
00222 buffer[ 9 ] = 0;
00223
00224 char *p = buffer;
00225 while( *p == ' ' ) p++;
00226 long int len = strtol( p, 0L, 16 );
00227
00228 p = buffer + 7;
00229 while( *p == ' ' ) p++;
00230 long int cmd = strtol( p, 0L, 16 );
00231
00232 data.resize( len );
00233
00234 if ( len > 0L ) {
00235 size_t bytesToGo = len;
00236 size_t bytesRead = 0;
00237 do {
00238 n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
00239 if (n == -1) {
00240 if (errno == EINTR)
00241 continue;
00242
00243 kdError(7017) << "Data read failed, errno=" << errno << endl;
00244 return -1;
00245 }
00246
00247 bytesRead += n;
00248 bytesToGo -= n;
00249 }
00250 while(bytesToGo);
00251 }
00252
00253 *_cmd = cmd;
00254 return len;
00255 }
00256
00257 #include "connection.moc"
This file is part of the documentation for kdelibs Version 3.1.0.