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

tdeio/tdeio

  • tdeio
  • tdeio
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/time.h>
31 
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <signal.h>
37 #include <string.h>
38 #include <unistd.h>
39 
40 #include "tdeio/connection.h"
41 
42 #include <kdebug.h>
43 #include <tqsocketnotifier.h>
44 
45 #if defined(__OpenBSD__) || defined(__FreeBSD__)
46 #define __progname getprogname()
47 #else
48 extern char *__progname;
49 #endif
50 
51 using namespace TDEIO;
52 
53 Connection::Connection()
54 {
55  f_out = 0;
56  fd_in = -1;
57  socket = 0;
58  notifier = 0;
59  receiver = 0;
60  member = 0;
61  m_suspended = false;
62  tasks.setAutoDelete(true);
63 }
64 
65 Connection::~Connection()
66 {
67  close();
68 }
69 
70 void Connection::suspend()
71 {
72  m_suspended = true;
73  if (notifier)
74  notifier->setEnabled(false);
75 }
76 
77 void Connection::resume()
78 {
79  m_suspended = false;
80  if (notifier)
81  notifier->setEnabled(true);
82 }
83 
84 void Connection::close()
85 {
86  delete notifier;
87  notifier = 0;
88  delete socket;
89  socket = 0;
90 
91  // TDESocket has already closed the file descriptor, but we need to
92  // close the file-stream as well otherwise we leak memory.
93  // As a result we close the file descriptor twice, but that should
94  // be harmless
95  // KDE4: fix this
96  if (f_out)
97  fclose(f_out);
98  f_out = 0;
99  fd_in = -1;
100  tasks.clear();
101 }
102 
103 void Connection::send(int cmd, const TQByteArray& data)
104 {
105  if (!inited() || tasks.count() > 0) {
106  Task *task = new Task();
107  task->cmd = cmd;
108  task->data = data;
109  tasks.append(task);
110  } else {
111  sendnow( cmd, data );
112  }
113 }
114 
115 void Connection::dequeue()
116 {
117  if (!inited())
118  return;
119 
120  while (tasks.count())
121  {
122  tasks.first();
123  Task *task = tasks.take();
124  sendnow( task->cmd, task->data );
125  delete task;
126  }
127 }
128 
129 void Connection::init(TDESocket *sock)
130 {
131  delete notifier;
132  notifier = 0;
133 #ifdef Q_OS_UNIX //TODO: not yet available on WIN32
134  delete socket;
135  socket = sock;
136  fd_in = socket->socket();
137  f_out = KDE_fdopen( socket->socket(), "wb" );
138 #endif
139  if (receiver && ( fd_in != -1 )) {
140  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
141  if ( m_suspended ) {
142  suspend();
143  }
144  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
145  }
146  dequeue();
147 }
148 
149 void Connection::init(int _fd_in, int fd_out)
150 {
151  delete notifier;
152  notifier = 0;
153  fd_in = _fd_in;
154  f_out = KDE_fdopen( fd_out, "wb" );
155  if (receiver && ( fd_in != -1 )) {
156  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
157  if ( m_suspended ) {
158  suspend();
159  }
160  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
161  }
162  dequeue();
163 }
164 
165 
166 void Connection::connect(TQObject *_receiver, const char *_member)
167 {
168  receiver = _receiver;
169  member = _member;
170  delete notifier;
171  notifier = 0;
172  if (receiver && (fd_in != -1 )) {
173  notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read);
174  if ( m_suspended )
175  suspend();
176  TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member);
177  }
178 }
179 
180 bool Connection::sendnow( int _cmd, const TQByteArray &data )
181 {
182  if (f_out == 0) {
183  return false;
184  }
185 
186  if (data.size() > 0xffffff)
187  return false;
188 
189  static char buffer[ 64 ];
190  sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
191 
192  size_t n = fwrite( buffer, 1, 10, f_out );
193 
194  if ( n != 10 ) {
195  kdError(7017) << "Could not send header (pid " << getpid() << " process \"" << __progname << "\")" << endl;
196  return false;
197  }
198 
199  n = fwrite( data.data(), 1, data.size(), f_out );
200 
201  if ( n != data.size() ) {
202  kdError(7017) << "Could not write data (pid " << getpid() << " process \"" << __progname << "\")" << endl;
203  return false;
204  }
205 
206  if (fflush( f_out )) {
207  kdError(7017) << "Could not write data (pid " << getpid() << " process \"" << __progname << "\")" << endl;
208  return false;
209  }
210 
211  return true;
212 }
213 
214 int Connection::read( int* _cmd, TQByteArray &data )
215 {
216  if (fd_in == -1 ) {
217  kdError(7017) << "read: not yet inited (pid " << getpid() << " process \"" << __progname << "\")" << endl;
218  return -1;
219  }
220 
221  static char buffer[ 10 ];
222 
223  again1:
224  ssize_t n = ::read( fd_in, buffer, 10);
225  if ( n == -1 && errno == EINTR )
226  goto again1;
227 
228  if ( n == -1) {
229  kdError(7017) << "Header read failed, errno=" << errno << " (pid " << getpid() << " process \"" << __progname << "\")" << endl;
230  }
231 
232  if ( n != 10 ) {
233  if ( n ) // 0 indicates end of file
234  kdError(7017) << "Header has invalid size (" << n << ") (pid " << getpid() << " process \"" << __progname << "\")" << endl;
235  return -1;
236  }
237 
238  buffer[ 6 ] = 0;
239  buffer[ 9 ] = 0;
240 
241  char *p = buffer;
242  while( *p == ' ' ) p++;
243  long int len = strtol( p, 0L, 16 );
244 
245  p = buffer + 7;
246  while( *p == ' ' ) p++;
247  long int cmd = strtol( p, 0L, 16 );
248 
249  data.resize( len );
250 
251  if ( len > 0L ) {
252  size_t bytesToGo = len;
253  size_t bytesRead = 0;
254  do {
255  n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
256  if (n == -1) {
257  if (errno == EINTR)
258  continue;
259 
260  kdError(7017) << "Data read failed, errno=" << errno << " (pid " << getpid() << " process \"" << __progname << "\")" << endl;
261  return -1;
262  }
263  if ( !n ) { // 0 indicates end of file
264  kdError(7017) << "Connection ended unexpectedly (" << n << "/" << bytesToGo << ") (pid " << getpid() << " process \"" << __progname << "\")" << endl;
265  return -1;
266  }
267 
268  bytesRead += n;
269  bytesToGo -= n;
270  }
271  while(bytesToGo);
272  }
273 
274  *_cmd = cmd;
275  return len;
276 }
277 
278 #include "connection.moc"
TDEIO::Connection::close
void close()
Closes the connection.
Definition: connection.cpp:84
TDEIO::Connection::sendnow
bool sendnow(int _cmd, const TQByteArray &data)
Sends the given command immediately.
Definition: connection.cpp:180
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29
TDEIO::Connection::read
int read(int *_cmd, TQByteArray &data)
Receive data.
Definition: connection.cpp:214
TDEIO::Connection::Connection
Connection()
Creates a new connection.
Definition: connection.cpp:53
TDEIO::Connection::suspend
void suspend()
Don&#39;t handle incoming data until resumed.
Definition: connection.cpp:70
TDEIO::Connection::inited
bool inited() const
Checks whether the connection has been initialized.
Definition: connection.h:94
TDEIO::Connection::send
void send(int cmd, const TQByteArray &arr=TQByteArray())
Sends/queues the given command to be sent.
Definition: connection.cpp:103
TDEIO::Connection::init
void init(TDESocket *sock)
Initialize this connection to use the given socket.
Definition: connection.cpp:129
TDEIO::Connection::resume
void resume()
Resume handling of incoming data.
Definition: connection.cpp:77

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.8.13
This website is maintained by Timothy Pearson.