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

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