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

kio/kio

  • kio
  • kio
connection.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
3  David Faure <faure@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 // $Id$
22 
23 #include <config.h>
24 
25 #include <kde_file.h>
26 #include <ksock.h>
27 #include <tqtimer.h>
28 
29 #include <sys/types.h>
30 #include <sys/signal.h>
31 #include <sys/time.h>
32 
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <unistd.h>
40 
41 #include "kio/connection.h"
42 
43 #include <kdebug.h>
44 #include <tqsocketnotifier.h>
45 
46 using namespace KIO;
47 
48 Connection::Connection()
49 {
50  f_out = 0;
51  fd_in = -1;
52  socket = 0;
53  notifier = 0;
54  receiver = 0;
55  member = 0;
56  m_suspended = false;
57  tasks.setAutoDelete(true);
58 }
59 
60 Connection::~Connection()
61 {
62  close();
63 }
64 
65 void Connection::suspend()
66 {
67  m_suspended = true;
68  if (notifier)
69  notifier->setEnabled(false);
70 }
71 
72 void Connection::resume()
73 {
74  m_suspended = false;
75  if (notifier)
76  notifier->setEnabled(true);
77 }
78 
79 void Connection::close()
80 {
81  delete notifier;
82  notifier = 0;
83  delete socket;
84  socket = 0;
85 
86  // KSocket has already closed the file descriptor, but we need to
87  // close the file-stream as well otherwise we leak memory.
88  // As a result we close the file descriptor twice, but that should
89  // be harmless
90  // KDE4: fix this
91  if (f_out)
92  fclose(f_out);
93  f_out = 0;
94  fd_in = -1;
95  tasks.clear();
96 }
97 
98 void Connection::send(int cmd, const TQByteArray& data)
99 {
100  if (!inited() || tasks.count() > 0) {
101  Task *task = new Task();
102  task->cmd = cmd;
103  task->data = data;
104  tasks.append(task);
105  } else {
106  sendnow( cmd, data );
107  }
108 }
109 
110 void Connection::dequeue()
111 {
112  if (!inited())
113  return;
114 
115  while (tasks.count())
116  {
117  tasks.first();
118  Task *task = tasks.take();
119  sendnow( task->cmd, task->data );
120  delete task;
121  }
122 }
123 
124 void Connection::init(KSocket *sock)
125 {
126  delete notifier;
127  notifier = 0;
128 #ifdef Q_OS_UNIX //TODO: not yet available on WIN32
129  delete socket;
130  socket = sock;
131  fd_in = socket->socket();
132  f_out = KDE_fdopen( socket->socket(), "wb" );
133 #endif
134  if (receiver && ( fd_in != -1 )) {
135  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
136  if ( m_suspended ) {
137  suspend();
138  }
139  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
140  }
141  dequeue();
142 }
143 
144 void Connection::init(int _fd_in, int fd_out)
145 {
146  delete notifier;
147  notifier = 0;
148  fd_in = _fd_in;
149  f_out = KDE_fdopen( fd_out, "wb" );
150  if (receiver && ( fd_in != -1 )) {
151  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
152  if ( m_suspended ) {
153  suspend();
154  }
155  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
156  }
157  dequeue();
158 }
159 
160 
161 void Connection::connect(TQObject *_receiver, const char *_member)
162 {
163  receiver = _receiver;
164  member = _member;
165  delete notifier;
166  notifier = 0;
167  if (receiver && (fd_in != -1 )) {
168  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
169  if ( m_suspended )
170  suspend();
171  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
172  }
173 }
174 
175 bool Connection::sendnow( int _cmd, const TQByteArray &data )
176 {
177  if (f_out == 0) {
178  return false;
179  }
180 
181  if (data.size() > 0xffffff)
182  return false;
183 
184  static char buffer[ 64 ];
185  sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
186 
187  size_t n = fwrite( buffer, 1, 10, f_out );
188 
189  if ( n != 10 ) {
190  kdError(7017) << "Could not send header" << endl;
191  return false;
192  }
193 
194  n = fwrite( data.data(), 1, data.size(), f_out );
195 
196  if ( n != data.size() ) {
197  kdError(7017) << "Could not write data" << endl;
198  return false;
199  }
200 
201  if (fflush( f_out )) {
202  kdError(7017) << "Could not write data" << endl;
203  return false;
204  }
205 
206  return true;
207 }
208 
209 int Connection::read( int* _cmd, TQByteArray &data )
210 {
211  if (fd_in == -1 ) {
212  kdError(7017) << "read: not yet inited" << endl;
213  return -1;
214  }
215 
216  static char buffer[ 10 ];
217 
218  again1:
219  ssize_t n = ::read( fd_in, buffer, 10);
220  if ( n == -1 && errno == EINTR )
221  goto again1;
222 
223  if ( n == -1) {
224  kdError(7017) << "Header read failed, errno=" << errno << endl;
225  }
226 
227  if ( n != 10 ) {
228  if ( n ) // 0 indicates end of file
229  kdError(7017) << "Header has invalid size (" << n << ")" << endl;
230  return -1;
231  }
232 
233  buffer[ 6 ] = 0;
234  buffer[ 9 ] = 0;
235 
236  char *p = buffer;
237  while( *p == ' ' ) p++;
238  long int len = strtol( p, 0L, 16 );
239 
240  p = buffer + 7;
241  while( *p == ' ' ) p++;
242  long int cmd = strtol( p, 0L, 16 );
243 
244  data.resize( len );
245 
246  if ( len > 0L ) {
247  size_t bytesToGo = len;
248  size_t bytesRead = 0;
249  do {
250  n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
251  if (n == -1) {
252  if (errno == EINTR)
253  continue;
254 
255  kdError(7017) << "Data read failed, errno=" << errno << endl;
256  return -1;
257  }
258  if ( !n ) { // 0 indicates end of file
259  kdError(7017) << "Connection ended unexpectedly (" << n << "/" << bytesToGo << ")" << endl;
260  return -1;
261  }
262 
263  bytesRead += n;
264  bytesToGo -= n;
265  }
266  while(bytesToGo);
267  }
268 
269  *_cmd = cmd;
270  return len;
271 }
272 
273 #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.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |