KDELibs4Support

k3socketdevice.cpp
1 /* -*- C++ -*-
2  * Copyright (C) 2003,2005 Thiago Macieira <[email protected]>
3  *
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 // syssocket.h needs to come before any header that includes k3socketbase.h
26 #include "syssocket.h"
27 
28 #include "k3socketdevice.h" //krazy:exclude=includes (KDE3 compat: not worth fixing)
29 
30 #include <config-network.h>
31 #include <config-kdelibs4support.h>
32 
33 #include <QMap>
34 
35 #if HAVE_SYS_FILIO_H
36 # include <sys/filio.h>
37 #endif
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <sys/time.h>
41 #include <sys/ioctl.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <netinet/in.h>
45 #include <netinet/tcp.h> // WARNING: verify if this is portable
46 #include <unistd.h>
47 
48 #if HAVE_POLL
49 # include <sys/poll.h>
50 #else
51 # if HAVE_SYS_SELECT_H
52 # include <sys/select.h>
53 # endif
54 #endif
55 
56 #ifdef Q_OS_WIN
57 #include <windows.h>
58 #endif
59 
60 #include <QMutex>
61 
62 #include "k3resolver.h"
63 #include "k3socketaddress.h"
64 using namespace KNetwork;
65 
66 class KNetwork::KSocketDevicePrivate
67 {
68 public:
69  mutable QSocketNotifier *input, *output, *exception;
70  KSocketAddress local, peer;
71  int af;
72  int proto;
73 
74  inline KSocketDevicePrivate()
75  {
76  input = output = exception = nullptr;
77  af = proto = 0;
78  }
79 };
80 
82  : KActiveSocketBase(objparent), m_sockfd(-1),
83  d(new KSocketDevicePrivate)
84 {
85  setSocketDevice(this);
86  if (parent) {
88  }
89 }
90 
92  : KActiveSocketBase(nullptr), m_sockfd(fd), d(new KSocketDevicePrivate)
93 {
94  if (mode) {
95  mode |= Unbuffered;
96  }
98  setSocketDevice(this);
99  d->af = localAddress().family();
100 }
101 
103  : KActiveSocketBase(parent), m_sockfd(-1), d(new KSocketDevicePrivate)
104 {
105  setSocketDevice(this);
106 }
107 
109  : KActiveSocketBase(nullptr), m_sockfd(-1), d(new KSocketDevicePrivate)
110 {
111  // do not set parent
112  if (parent) {
113  setSocketOptions(parent->socketOptions());
114  }
115 }
116 
118 {
119  close(); // deletes the notifiers
120  unsetSocketDevice(); // prevent double deletion
121  delete d;
122 }
123 
125 {
126  return m_sockfd;
127 }
128 
130 {
131  return 0;
132 }
133 
135 {
136  // must call parent
137  QMutexLocker locker(mutex());
139 
140  if (m_sockfd == -1) {
141  return true; // flags are stored
142  }
143 
144 #ifdef Q_OS_WIN
145  u_long iMode = ((opts & Blocking) == Blocking) ? 0 : 1;
146  // disable non blocking
147  if (ioctlsocket(m_sockfd, FIONBIO, &iMode) == SOCKET_ERROR) {
148  // socket can't made blocking because WSAAsyncSelect/WSAEventSelect (==QSocketNotifier)
149  // is activated for them
150  if (WSAGetLastError() == WSAEINVAL) {
151  return true;
152  }
153  qDebug("socket set %s failed %d", iMode ? "nonblocking" : "blocking", GetLastError());
154  setError(UnknownError);
155  return false; // error
156  }
157 
158 #else
159  {
160  int fdflags = fcntl(m_sockfd, F_GETFL, 0);
161  if (fdflags == -1) {
162  setError(UnknownError);
163  return false; // error
164  }
165 
166  if (opts & Blocking) {
167  fdflags &= ~O_NONBLOCK;
168  } else {
169  fdflags |= O_NONBLOCK;
170  }
171 
172  if (fcntl(m_sockfd, F_SETFL, fdflags) == -1) {
173  setError(UnknownError);
174  return false; // error
175  }
176  }
177 #endif
178 
179  {
180  int on = opts & AddressReuseable ? 1 : 0;
181  if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) {
182  setError(UnknownError);
183  return false; // error
184  }
185  }
186 
187 #if defined(IPV6_V6ONLY) && defined(AF_INET6)
188  if (d->af == AF_INET6) {
189  // don't try this on non-IPv6 sockets, or we'll get an error
190 
191  int on = opts & IPv6Only ? 1 : 0;
192  if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) == -1) {
193  setError(UnknownError);
194  return false; // error
195  }
196  }
197 #endif
198 
199  {
200  int on = opts & Broadcast ? 1 : 0;
201  if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) == -1) {
202  setError(UnknownError);
203  return false; // error
204  }
205  }
206 
207  if ((d->proto == IPPROTO_TCP || d->proto == 0) &&
208  (d->af == AF_INET
209 #if defined(AF_INET6)
210  || d->af == AF_INET6
211 #endif
212  )) {
213  int on = opts & NoDelay ? 1 : 0;
214  if (setsockopt(m_sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof(on)) == -1) {
215  setError(UnknownError);
216  return false; // error
217  }
218  }
219 
220  return true; // all went well
221 }
222 
224 {
225  resetError();
226  if (m_sockfd != -1) {
227  delete d->input;
228  delete d->output;
229  delete d->exception;
230 
231  d->input = d->output = d->exception = nullptr;
232 #ifdef Q_OS_WIN
233  ::closesocket(m_sockfd);
234 #else
235  d->local.setFamily(AF_UNSPEC);
236  d->peer.setFamily(AF_UNSPEC);
237 
238  ::close(m_sockfd);
239 #endif
240  }
241  setOpenMode(NotOpen); // closed
242 
243  m_sockfd = -1;
244 }
245 
247 {
248  return false;
249 }
250 
251 bool KSocketDevice::create(int family, int type, int protocol)
252 {
253  resetError();
254 
255  if (m_sockfd != -1) {
256  // it's already created!
257  setError(AlreadyCreated);
258  return false;
259  }
260 
261  // no socket yet; we have to create it
262  m_sockfd = kde_socket(family, type, protocol);
263 
264  if (m_sockfd == -1) {
265  setError(NotSupported);
266  return false;
267  }
268 
269  d->af = family;
270  d->proto = protocol;
272  setOpenMode(Unbuffered); // there's no "Open" flag
273  return true; // successfully created
274 }
275 
277 {
278  return create(address.family(), address.socketType(), address.protocol());
279 }
280 
282 {
283  resetError();
284 
285  if (m_sockfd == -1 && !create(address)) {
286  return false; // failed creating
287  }
288 
289  // we have a socket, so try and bind
290  if (kde_bind(m_sockfd, address.address(), address.length()) == -1) {
291  if (errno == EADDRINUSE) {
292  setError(AddressInUse);
293  return false;
294  } else if (errno == EINVAL) {
295  setError(AlreadyBound);
296  } else {
297 #ifdef Q_OS_WIN
298  qDebug(" bind failed: %s ", address.address().toString().toLatin1().constData());
299 #endif
300  // assume the address is the cause
301  setError(NotSupported);
302  return false;
303  }
304  }
305 
306  return true;
307 }
308 
309 bool KSocketDevice::listen(int backlog)
310 {
311  if (m_sockfd != -1) {
312  if (kde_listen(m_sockfd, backlog) == -1) {
313  setError(NotSupported);
314  return false;
315  }
316 
317  resetError();
319  return true;
320  }
321 
322  // we don't have a socket
323  // can't listen
324  setError(NotCreated);
325  return false;
326 }
327 
329 {
330  resetError();
331 
332  if (m_sockfd == -1 && !create(address)) {
333  return false; // failed creating!
334  }
335 
336  if (kde_connect(m_sockfd, address.address(), address.length()) == -1) {
337  if (errno == EISCONN) {
339  return true; // we're already connected
340  } else if (errno == EALREADY || errno == EINPROGRESS) {
342  setError(InProgress);
343  return true;
344  } else if (errno == ECONNREFUSED) {
345  setError(ConnectionRefused);
346  } else if (errno == ENETDOWN || errno == ENETUNREACH ||
347  errno == ENETRESET || errno == ECONNABORTED ||
348  errno == ECONNRESET || errno == EHOSTDOWN ||
349  errno == EHOSTUNREACH) {
350  setError(NetFailure);
351  } else {
352  setError(NotSupported);
353  }
354 
355  return false;
356  }
357 
359  return true; // all is well
360 }
361 
363 {
364  if (m_sockfd == -1) {
365  // can't accept without a socket
366  setError(NotCreated);
367  return nullptr;
368  }
369 
370  struct sockaddr sa;
371  socklen_t len = sizeof(sa);
372  int newfd = kde_accept(m_sockfd, &sa, &len);
373  if (newfd == -1) {
374  if (errno == EAGAIN || errno == EWOULDBLOCK) {
375  setError(WouldBlock);
376  } else {
377  setError(UnknownError);
378  }
379  return nullptr;
380  }
381 
382  return new KSocketDevice(newfd);
383 }
384 
386 {
387  resetError();
388 
389  if (m_sockfd == -1) {
390  return false; // can't create
391  }
392 
393  KSocketAddress address;
394  address.setFamily(AF_UNSPEC);
395  if (kde_connect(m_sockfd, address.address(), address.length()) == -1) {
396  if (errno == EALREADY || errno == EINPROGRESS) {
397  setError(InProgress);
398  return false;
399  } else if (errno == ECONNREFUSED) {
400  setError(ConnectionRefused);
401  } else if (errno == ENETDOWN || errno == ENETUNREACH ||
402  errno == ENETRESET || errno == ECONNABORTED ||
403  errno == ECONNRESET || errno == EHOSTDOWN ||
404  errno == EHOSTUNREACH) {
405  setError(NetFailure);
406  } else {
407  setError(NotSupported);
408  }
409 
410  return false;
411  }
412 
414  return true; // all is well
415 }
416 
418 {
419  if (m_sockfd == -1) {
420  return -1; // there's nothing to read in a closed socket
421  }
422 
423  int nchars;
424  if (kde_ioctl(m_sockfd, FIONREAD, &nchars) == -1) {
425  return -1; // error!
426  }
427 
428  return nchars;
429 }
430 
431 qint64 KSocketDevice::waitForMore(int msecs, bool *timeout)
432 {
433  if (m_sockfd == -1) {
434  return -1; // there won't ever be anything to read...
435  }
436 
437  bool input;
438  if (!poll(&input, nullptr, nullptr, msecs, timeout)) {
439  return -1; // failed polling
440  }
441 
442  return bytesAvailable();
443 }
444 
445 static int do_read_common(int sockfd, char *data, qint64 maxlen, KSocketAddress *from, ssize_t &retval, bool peek = false)
446 {
447  socklen_t len;
448  if (from) {
449  from->setLength(len = 128); // arbitrary length
450  retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
451  } else {
452  retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, nullptr, nullptr);
453  }
454 
455  if (retval == -1) {
456 #ifdef Q_OS_WIN
457  if (WSAGetLastError() == WSAEWOULDBLOCK) {
458  return KSocketDevice::WouldBlock;
459  } else
460 #endif
461  if (errno == EAGAIN || errno == EWOULDBLOCK) {
462  return KSocketDevice::WouldBlock;
463  } else {
464  return KSocketDevice::UnknownError;
465  }
466  }
467  if (retval == 0) {
468  return KSocketDevice::RemotelyDisconnected;
469  }
470 
471  if (from) {
472  from->setLength(len);
473  }
474  return 0;
475 }
476 
477 qint64 KSocketDevice::readData(char *data, qint64 maxlen, KSocketAddress *from)
478 {
479  resetError();
480  if (m_sockfd == -1) {
481  return -1; // nothing to do here
482  }
483 
484  if (data == nullptr || maxlen == 0) {
485  return 0; // user doesn't want to read
486  }
487 
488  ssize_t retval;
489  int err = do_read_common(m_sockfd, data, maxlen, from, retval);
490 
491  if (err) {
492  setError(static_cast<SocketError>(err));
493  return -1;
494  }
495 
496  return retval;
497 }
498 
499 qint64 KSocketDevice::peekData(char *data, qint64 maxlen, KSocketAddress *from)
500 {
501  resetError();
502  if (m_sockfd == -1) {
503  return -1; // nothing to do here
504  }
505 
506  if (data == nullptr || maxlen == 0) {
507  return 0; // user doesn't want to read
508  }
509 
510  ssize_t retval;
511  int err = do_read_common(m_sockfd, data, maxlen, from, retval, true);
512 
513  if (err) {
514  setError(static_cast<SocketError>(err));
515  return -1;
516  }
517 
518  return retval;
519 }
520 
521 qint64 KSocketDevice::writeData(const char *data, qint64 len, const KSocketAddress *to)
522 {
523  resetError();
524  if (m_sockfd == -1) {
525  return -1; // can't write to unopen socket
526  }
527 
528  if (data == nullptr || len == 0) {
529  return 0; // nothing to be written
530  }
531 
532  ssize_t retval;
533  if (to != nullptr) {
534  retval = ::sendto(m_sockfd, data, len, 0, to->address(), to->length());
535  } else
536 #ifdef Q_OS_WIN
537  retval = ::send(m_sockfd, data, len, 0);
538 #else
539  retval = ::write(m_sockfd, data, len);
540 #endif
541  if (retval == -1) {
542  if (errno == EAGAIN || errno == EWOULDBLOCK) {
543  setError(WouldBlock);
544  } else {
545  setError(UnknownError);
546  }
547  return -1; // nothing written
548  } else if (retval == 0) {
549  setError(RemotelyDisconnected);
550  }
551 
552  return retval;
553 }
554 
556 {
557  if (m_sockfd == -1) {
558  return KSocketAddress(); // not open, empty value
559  }
560 
561  if (d->local.family() != AF_UNSPEC) {
562  return d->local;
563  }
564 
565  socklen_t len;
567  localAddress.setLength(len = 32); // arbitrary value
568  if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
569  // error!
570  {
571  return d->local = KSocketAddress();
572  }
573 
574 #if HAVE_STRUCT_SOCKADDR_SA_LEN
575  len = localAddress.address()->sa_len;
576 #endif
577 
578  if (len <= localAddress.length()) {
579  // it has fit already
580  localAddress.setLength(len);
581  return d->local = localAddress;
582  }
583 
584  // no, the socket address is actually larger than we had anticipated
585  // call again
586  localAddress.setLength(len);
587  if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
588  // error!
589  {
590  return d->local = KSocketAddress();
591  }
592 
593  return d->local = localAddress;
594 }
595 
597 {
598  if (m_sockfd == -1) {
599  return KSocketAddress(); // not open, empty value
600  }
601 
602  if (d->peer.family() != AF_UNSPEC) {
603  return d->peer;
604  }
605 
606  socklen_t len;
608  peerAddress.setLength(len = 32); // arbitrary value
609  if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
610  // error!
611  {
612  return d->peer = KSocketAddress();
613  }
614 
615 #if HAVE_STRUCT_SOCKADDR_SA_LEN
616  len = peerAddress.address()->sa_len;
617 #endif
618 
619  if (len <= peerAddress.length()) {
620  // it has fit already
621  peerAddress.setLength(len);
622  return d->peer = peerAddress;
623  }
624 
625  // no, the socket address is actually larger than we had anticipated
626  // call again
627  peerAddress.setLength(len);
628  if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
629  // error!
630  {
631  return d->peer = KSocketAddress();
632  }
633 
634  return d->peer = peerAddress;
635 }
636 
638 {
639  // for normal sockets, the externally visible address is the same
640  // as the local address
641  return localAddress();
642 }
643 
645 {
646  if (d->input) {
647  return d->input;
648  }
649 
650  QMutexLocker locker(mutex());
651  if (d->input) {
652  return d->input;
653  }
654 
655  if (m_sockfd == -1) {
656  // socket doesn't exist; can't create notifier
657  return nullptr;
658  }
659 
660  return d->input = createNotifier(QSocketNotifier::Read);
661 }
662 
664 {
665  if (d->output) {
666  return d->output;
667  }
668 
669  QMutexLocker locker(mutex());
670  if (d->output) {
671  return d->output;
672  }
673 
674  if (m_sockfd == -1) {
675  // socket doesn't exist; can't create notifier
676  return nullptr;
677  }
678 
679  return d->output = createNotifier(QSocketNotifier::Write);
680 }
681 
683 {
684  if (d->exception) {
685  return d->exception;
686  }
687 
688  QMutexLocker locker(mutex());
689  if (d->exception) {
690  return d->exception;
691  }
692 
693  if (m_sockfd == -1) {
694  // socket doesn't exist; can't create notifier
695  return nullptr;
696  }
697 
698  return d->exception = createNotifier(QSocketNotifier::Exception);
699 }
700 
701 bool KSocketDevice::poll(bool *input, bool *output, bool *exception,
702  int timeout, bool *timedout)
703 {
704  if (m_sockfd == -1) {
705  setError(NotCreated);
706  return false;
707  }
708 
709  resetError();
710 #if HAVE_POLL
711  struct pollfd fds;
712  fds.fd = m_sockfd;
713  fds.events = 0;
714 
715  if (input) {
716  fds.events |= POLLIN;
717  *input = false;
718  }
719  if (output) {
720  fds.events |= POLLOUT;
721  *output = false;
722  }
723  if (exception) {
724  fds.events |= POLLPRI;
725  *exception = false;
726  }
727 
728  int retval = ::poll(&fds, 1, timeout);
729  if (retval == -1) {
730  setError(UnknownError);
731  return false;
732  }
733  if (retval == 0) {
734  // timeout
735  if (timedout) {
736  *timedout = true;
737  }
738  return true;
739  }
740 
741  if (input && fds.revents & POLLIN) {
742  *input = true;
743  }
744  if (output && fds.revents & POLLOUT) {
745  *output = true;
746  }
747  if (exception && fds.revents & POLLPRI) {
748  *exception = true;
749  }
750  if (timedout) {
751  *timedout = false;
752  }
753 
754  return true;
755 #else
756  /*
757  * We don't have poll(2). We'll have to make do with select(2).
758  */
759 
760  fd_set readfds, writefds, exceptfds;
761  fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
762 
763  if (input) {
764  preadfds = &readfds;
765  FD_ZERO(preadfds);
766  FD_SET(m_sockfd, preadfds);
767  *input = false;
768  }
769  if (output) {
770  pwritefds = &writefds;
771  FD_ZERO(pwritefds);
772  FD_SET(m_sockfd, pwritefds);
773  *output = false;
774  }
775  if (exception) {
776  pexceptfds = &exceptfds;
777  FD_ZERO(pexceptfds);
778  FD_SET(m_sockfd, pexceptfds);
779  *exception = false;
780  }
781 
782  int retval;
783  if (timeout < 0) {
784  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
785  } else {
786  // convert the milliseconds to timeval
787  struct timeval tv;
788  tv.tv_sec = timeout / 1000;
789  tv.tv_usec = timeout % 1000 * 1000;
790 
791  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
792  }
793 
794  if (retval == -1) {
795  setError(UnknownError);
796  return false;
797  }
798  if (retval == 0) {
799  // timeout
800  if (timedout) {
801  *timedout = true;
802  }
803  return true;
804  }
805 
806  if (input && FD_ISSET(m_sockfd, preadfds)) {
807  *input = true;
808  }
809  if (output && FD_ISSET(m_sockfd, pwritefds)) {
810  *output = true;
811  }
812  if (exception && FD_ISSET(m_sockfd, pexceptfds)) {
813  *exception = true;
814  }
815 
816  return true;
817 #endif
818 }
819 
820 bool KSocketDevice::poll(int timeout, bool *timedout)
821 {
822  bool input, output, exception;
823  return poll(&input, &output, &exception, timeout, timedout);
824 }
825 
827 {
828  if (m_sockfd == -1) {
829  return nullptr;
830  }
831 
832  return new QSocketNotifier(m_sockfd, type);
833 }
834 
835 namespace
836 {
837 // simple class to avoid pointer stuff
838 template<class T> class ptr
839 {
840  typedef T type;
841  type *obj;
842 public:
843  ptr() : obj(0)
844  { }
845 
846  ptr(const ptr<T> &other) : obj(other.obj)
847  { }
848 
849  ptr(type *_obj) : obj(_obj)
850  { }
851 
852  ~ptr()
853  { }
854 
855  ptr<T> &operator=(const ptr<T> &other)
856  {
857  obj = other.obj;
858  return *this;
859  }
860 
861  ptr<T> &operator=(T *_obj)
862  {
863  obj = _obj;
864  return *this;
865  }
866 
867  type *operator->() const
868  {
869  return obj;
870  }
871 
872  operator T *() const
873  {
874  return obj;
875  }
876 
877  bool isNull() const
878  {
879  return obj == 0;
880  }
881 };
882 }
883 
884 static KSocketDeviceFactoryBase *defaultImplFactory;
885 static QMutex defaultImplFactoryMutex;
887 static factoryMap factories;
888 
890 {
891  KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent);
892  if (device != nullptr) {
893  return device;
894  }
895 
896  if (defaultImplFactory) {
897  return defaultImplFactory->create(parent);
898  }
899 
900  // the really default
901  return new KSocketDevice(parent);
902 }
903 
905 {
906  KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent);
907  if (device != nullptr) {
908  return device;
909  }
910 
911  QMutexLocker locker(&defaultImplFactoryMutex);
912  factoryMap::ConstIterator it = factories.constBegin();
913  for (; it != factories.constEnd(); ++it)
914  if ((it.key() & capabilities) == capabilities)
915  // found a match
916  {
917  return it.value()->create(parent);
918  }
919 
920  return nullptr; // no default
921 }
922 
925 {
926  QMutexLocker locker(&defaultImplFactoryMutex);
927  KSocketDeviceFactoryBase *old = defaultImplFactory;
928  defaultImplFactory = factory;
929  return old;
930 }
931 
933 {
934  QMutexLocker locker(&defaultImplFactoryMutex);
935  if (factories.contains(capabilities)) {
936  delete factories[capabilities];
937  }
938  factories.insert(capabilities, factory);
939 }
940 
bool bind(const KResolverEntry &address) override
Binds this socket to the given address.
bool contains(const Key &key) const const
KSocketAddress externalAddress() const override
Returns this socket&#39;s externally visible local address.
Abstract class for active sockets.
Definition: k3socketbase.h:460
KSocketAddress peerAddress() const override
Returns this socket&#39;s peer address.
virtual QString toString() const
Returns this socket address as a string suitable for printing.
One resolution entry.
Definition: k3resolver.h:72
KSocketAddress & setLength(quint16 len)
Sets the length of this socket structure.
virtual bool flush()
This call is not supported on sockets.
void resetError()
Resets the socket error code and the I/O Device&#39;s status.
QSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
QMap::const_iterator constBegin() const const
Definition: netaccess.h:36
qint64 waitForMore(int msecs, bool *timeout=nullptr) override
Waits up to msecs for more data to be available on this socket.
virtual bool connect(const KResolverEntry &address, OpenMode mode=ReadWrite) override
Connect to a remote host.
virtual int capabilities() const
Returns the set of capabilities this socket class implements.
typedef OpenMode
int socket() const
Returns the file descriptor for this socket.
A generic socket address.
const sockaddr * address() const
Returns the socket address structure, to be passed down to low level functions.
qint64 peek(char *data, qint64 maxlen)
Peeks the data in the socket and the source address.
QSocketNotifier * exceptionNotifier() const
Returns a socket notifier for exceptional events on this socket.
virtual QSocketNotifier * createNotifier(QSocketNotifier::Type type) const
Creates a socket notifier of the given type.
qint64 readData(char *data, qint64 maxlen, KSocketAddress *from=nullptr) override
Reads data and the source address from this socket.
virtual ~KSocketDevice()
Destructor.
int protocol() const
Retrieves the protocol associated with this entry.
Definition: k3resolver.cpp:168
virtual KSocketAddress & setFamily(int family)
Sets the family of this object.
qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from=nullptr) override
Peeks the data in the socket and the source address.
A namespace to store all networking-related (socket) classes.
int family() const
Returns the family of this address.
QSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
bool listen(int backlog=5) override
Puts this socket into listening mode.
void close() override
Closes the socket.
static void addNewImpl(KSocketDeviceFactoryBase *factory, int capabilities)
Adds a factory of KSocketDevice objects to the list, along with its capabilities flag.
KSocketAddress localAddress() const override
Returns this socket&#39;s local address.
virtual bool create(int family, int type, int protocol)
Creates a socket but don&#39;t connect or bind anywhere.
void setSocketDevice(KSocketDevice *device) override
QMutex * mutex() const
Returns the internal mutex for this class.
QMap::const_iterator constEnd() const const
const char * constData() const const
bool setSocketOptions(int opts) override
This implementation sets the options on the socket.
virtual bool setSocketOptions(int opts)
Set the given socket options.
void setError(SocketError error)
Sets the socket&#39;s error code.
qint64 write(const char *data, qint64 len)
Writes the given data to the socket.
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:132
static KSocketDeviceFactoryBase * setDefaultImpl(KSocketDeviceFactoryBase *factory)
Sets the default KSocketDevice implementation to use and return the old factory.
quint16 length() const
Retrieves the length of the socket address structure.
Definition: k3resolver.cpp:138
int m_sockfd
The socket file descriptor.
QByteArray toLatin1() const const
int socketType() const
Retrieves the socket type associated with this entry.
Definition: k3resolver.cpp:162
KSocketDevice * accept() override
Accepts a new incoming connection.
quint16 length() const
Returns the length of this socket address structure.
virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress *to=nullptr) override
Writes the given data to the given destination address.
int family() const
Retrieves the family associated with this socket address.
Definition: k3resolver.cpp:144
bool disconnect() override
Disconnects this socket.
Low-level socket functionality.
QMap::iterator insert(const Key &key, const T &value)
virtual int socketOptions() const
Retrieves the socket options that have been set.
Basic socket functionality.
Definition: k3socketbase.h:86
typedef ConstIterator
void setOpenMode(QIODevice::OpenMode openMode)
QObject * parent() const const
KSocketDevice(const KSocketBase *=nullptr, QObject *objparent=nullptr)
Default constructor.
static KSocketDevice * createDefault(KSocketBase *parent)
Creates a new default KSocketDevice object given the parent object.
virtual bool poll(bool *input, bool *output, bool *exception=nullptr, int timeout=-1, bool *timedout=nullptr)
Executes a poll in the socket, via select(2) or poll(2).
bool open(OpenMode mode) override
Reimplemented from QIODevice.
qint64 bytesAvailable() const override
Returns the number of bytes available for reading without blocking.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Jan 18 2021 23:00:50 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.