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

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