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 #include <QSocketNotifier>
62 
63 #include "k3resolver.h"
64 #include "k3socketaddress.h"
65 #include "k3socketbase.h"
66 using namespace KNetwork;
67 
68 class KNetwork::KSocketDevicePrivate
69 {
70 public:
71  mutable QSocketNotifier *input, *output, *exception;
72  KSocketAddress local, peer;
73  int af;
74  int proto;
75 
76  inline KSocketDevicePrivate()
77  {
78  input = output = exception = nullptr;
79  af = proto = 0;
80  }
81 };
82 
84  : KActiveSocketBase(objparent), m_sockfd(-1),
85  d(new KSocketDevicePrivate)
86 {
87  setSocketDevice(this);
88  if (parent) {
90  }
91 }
92 
94  : KActiveSocketBase(nullptr), m_sockfd(fd), d(new KSocketDevicePrivate)
95 {
96  if (mode) {
97  mode |= Unbuffered;
98  }
100  setSocketDevice(this);
101  d->af = localAddress().family();
102 }
103 
105  : KActiveSocketBase(parent), m_sockfd(-1), d(new KSocketDevicePrivate)
106 {
107  setSocketDevice(this);
108 }
109 
111  : KActiveSocketBase(nullptr), m_sockfd(-1), d(new KSocketDevicePrivate)
112 {
113  // do not set parent
114  if (parent) {
115  setSocketOptions(parent->socketOptions());
116  }
117 }
118 
120 {
121  close(); // deletes the notifiers
122  unsetSocketDevice(); // prevent double deletion
123  delete d;
124 }
125 
127 {
128  return m_sockfd;
129 }
130 
132 {
133  return 0;
134 }
135 
137 {
138  // must call parent
139  QMutexLocker locker(mutex());
141 
142  if (m_sockfd == -1) {
143  return true; // flags are stored
144  }
145 
146 #ifdef Q_OS_WIN
147  u_long iMode = ((opts & Blocking) == Blocking) ? 0 : 1;
148  // disable non blocking
149  if (ioctlsocket(m_sockfd, FIONBIO, &iMode) == SOCKET_ERROR) {
150  // socket can't made blocking because WSAAsyncSelect/WSAEventSelect (==QSocketNotifier)
151  // is activated for them
152  if (WSAGetLastError() == WSAEINVAL) {
153  return true;
154  }
155  qDebug("socket set %s failed %d", iMode ? "nonblocking" : "blocking", GetLastError());
156  setError(UnknownError);
157  return false; // error
158  }
159 
160 #else
161  {
162  int fdflags = fcntl(m_sockfd, F_GETFL, 0);
163  if (fdflags == -1) {
164  setError(UnknownError);
165  return false; // error
166  }
167 
168  if (opts & Blocking) {
169  fdflags &= ~O_NONBLOCK;
170  } else {
171  fdflags |= O_NONBLOCK;
172  }
173 
174  if (fcntl(m_sockfd, F_SETFL, fdflags) == -1) {
175  setError(UnknownError);
176  return false; // error
177  }
178  }
179 #endif
180 
181  {
182  int on = opts & AddressReuseable ? 1 : 0;
183  if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) {
184  setError(UnknownError);
185  return false; // error
186  }
187  }
188 
189 #if defined(IPV6_V6ONLY) && defined(AF_INET6)
190  if (d->af == AF_INET6) {
191  // don't try this on non-IPv6 sockets, or we'll get an error
192 
193  int on = opts & IPv6Only ? 1 : 0;
194  if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) == -1) {
195  setError(UnknownError);
196  return false; // error
197  }
198  }
199 #endif
200 
201  {
202  int on = opts & Broadcast ? 1 : 0;
203  if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) == -1) {
204  setError(UnknownError);
205  return false; // error
206  }
207  }
208 
209  if ((d->proto == IPPROTO_TCP || d->proto == 0) &&
210  (d->af == AF_INET
211 #if defined(AF_INET6)
212  || d->af == AF_INET6
213 #endif
214  )) {
215  int on = opts & NoDelay ? 1 : 0;
216  if (setsockopt(m_sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof(on)) == -1) {
217  setError(UnknownError);
218  return false; // error
219  }
220  }
221 
222  return true; // all went well
223 }
224 
226 {
227  resetError();
228  if (m_sockfd != -1) {
229  delete d->input;
230  delete d->output;
231  delete d->exception;
232 
233  d->input = d->output = d->exception = nullptr;
234 #ifdef Q_OS_WIN
235  ::closesocket(m_sockfd);
236 #else
237  d->local.setFamily(AF_UNSPEC);
238  d->peer.setFamily(AF_UNSPEC);
239 
240  ::close(m_sockfd);
241 #endif
242  }
243  setOpenMode(NotOpen); // closed
244 
245  m_sockfd = -1;
246 }
247 
249 {
250  return false;
251 }
252 
253 bool KSocketDevice::create(int family, int type, int protocol)
254 {
255  resetError();
256 
257  if (m_sockfd != -1) {
258  // it's already created!
259  setError(AlreadyCreated);
260  return false;
261  }
262 
263  // no socket yet; we have to create it
264  m_sockfd = kde_socket(family, type, protocol);
265 
266  if (m_sockfd == -1) {
267  setError(NotSupported);
268  return false;
269  }
270 
271  d->af = family;
272  d->proto = protocol;
274  setOpenMode(Unbuffered); // there's no "Open" flag
275  return true; // successfully created
276 }
277 
279 {
280  return create(address.family(), address.socketType(), address.protocol());
281 }
282 
284 {
285  resetError();
286 
287  if (m_sockfd == -1 && !create(address)) {
288  return false; // failed creating
289  }
290 
291  // we have a socket, so try and bind
292  if (kde_bind(m_sockfd, address.address(), address.length()) == -1) {
293  if (errno == EADDRINUSE) {
294  setError(AddressInUse);
295  return false;
296  } else if (errno == EINVAL) {
297  setError(AlreadyBound);
298  } else {
299 #ifdef Q_OS_WIN
300  qDebug(" bind failed: %s ", address.address().toString().toLatin1().constData());
301 #endif
302  // assume the address is the cause
303  setError(NotSupported);
304  return false;
305  }
306  }
307 
308  return true;
309 }
310 
311 bool KSocketDevice::listen(int backlog)
312 {
313  if (m_sockfd != -1) {
314  if (kde_listen(m_sockfd, backlog) == -1) {
315  setError(NotSupported);
316  return false;
317  }
318 
319  resetError();
320  setOpenMode(QIODevice::Unbuffered | QIODevice::ReadWrite);
321  return true;
322  }
323 
324  // we don't have a socket
325  // can't listen
326  setError(NotCreated);
327  return false;
328 }
329 
331 {
332  resetError();
333 
334  if (m_sockfd == -1 && !create(address)) {
335  return false; // failed creating!
336  }
337 
338  if (kde_connect(m_sockfd, address.address(), address.length()) == -1) {
339  if (errno == EISCONN) {
340  KActiveSocketBase::open(Unbuffered | mode);
341  return true; // we're already connected
342  } else if (errno == EALREADY || errno == EINPROGRESS) {
343  KActiveSocketBase::open(Unbuffered | mode);
344  setError(InProgress);
345  return true;
346  } else if (errno == ECONNREFUSED) {
347  setError(ConnectionRefused);
348  } else if (errno == ENETDOWN || errno == ENETUNREACH ||
349  errno == ENETRESET || errno == ECONNABORTED ||
350  errno == ECONNRESET || errno == EHOSTDOWN ||
351  errno == EHOSTUNREACH) {
352  setError(NetFailure);
353  } else {
354  setError(NotSupported);
355  }
356 
357  return false;
358  }
359 
360  KActiveSocketBase::open(Unbuffered | mode);
361  return true; // all is well
362 }
363 
365 {
366  if (m_sockfd == -1) {
367  // can't accept without a socket
368  setError(NotCreated);
369  return nullptr;
370  }
371 
372  struct sockaddr sa;
373  socklen_t len = sizeof(sa);
374  int newfd = kde_accept(m_sockfd, &sa, &len);
375  if (newfd == -1) {
376  if (errno == EAGAIN || errno == EWOULDBLOCK) {
377  setError(WouldBlock);
378  } else {
379  setError(UnknownError);
380  }
381  return nullptr;
382  }
383 
384  return new KSocketDevice(newfd);
385 }
386 
388 {
389  resetError();
390 
391  if (m_sockfd == -1) {
392  return false; // can't create
393  }
394 
395  KSocketAddress address;
396  address.setFamily(AF_UNSPEC);
397  if (kde_connect(m_sockfd, address.address(), address.length()) == -1) {
398  if (errno == EALREADY || errno == EINPROGRESS) {
399  setError(InProgress);
400  return false;
401  } else if (errno == ECONNREFUSED) {
402  setError(ConnectionRefused);
403  } else if (errno == ENETDOWN || errno == ENETUNREACH ||
404  errno == ENETRESET || errno == ECONNABORTED ||
405  errno == ECONNRESET || errno == EHOSTDOWN ||
406  errno == EHOSTUNREACH) {
407  setError(NetFailure);
408  } else {
409  setError(NotSupported);
410  }
411 
412  return false;
413  }
414 
415  setOpenMode(QIODevice::Unbuffered | QIODevice::ReadWrite);
416  return true; // all is well
417 }
418 
420 {
421  if (m_sockfd == -1) {
422  return -1; // there's nothing to read in a closed socket
423  }
424 
425  int nchars;
426  if (kde_ioctl(m_sockfd, FIONREAD, &nchars) == -1) {
427  return -1; // error!
428  }
429 
430  return nchars;
431 }
432 
433 qint64 KSocketDevice::waitForMore(int msecs, bool *timeout)
434 {
435  if (m_sockfd == -1) {
436  return -1; // there won't ever be anything to read...
437  }
438 
439  bool input;
440  if (!poll(&input, nullptr, nullptr, msecs, timeout)) {
441  return -1; // failed polling
442  }
443 
444  return bytesAvailable();
445 }
446 
447 static int do_read_common(int sockfd, char *data, qint64 maxlen, KSocketAddress *from, ssize_t &retval, bool peek = false)
448 {
449  socklen_t len;
450  if (from) {
451  from->setLength(len = 128); // arbitrary length
452  retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
453  } else {
454  retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, nullptr, nullptr);
455  }
456 
457  if (retval == -1) {
458 #ifdef Q_OS_WIN
459  if (WSAGetLastError() == WSAEWOULDBLOCK) {
460  return KSocketDevice::WouldBlock;
461  } else
462 #endif
463  if (errno == EAGAIN || errno == EWOULDBLOCK) {
464  return KSocketDevice::WouldBlock;
465  } else {
466  return KSocketDevice::UnknownError;
467  }
468  }
469  if (retval == 0) {
470  return KSocketDevice::RemotelyDisconnected;
471  }
472 
473  if (from) {
474  from->setLength(len);
475  }
476  return 0;
477 }
478 
479 qint64 KSocketDevice::readData(char *data, qint64 maxlen, KSocketAddress *from)
480 {
481  resetError();
482  if (m_sockfd == -1) {
483  return -1; // nothing to do here
484  }
485 
486  if (data == nullptr || maxlen == 0) {
487  return 0; // user doesn't want to read
488  }
489 
490  ssize_t retval;
491  int err = do_read_common(m_sockfd, data, maxlen, from, retval);
492 
493  if (err) {
494  setError(static_cast<SocketError>(err));
495  return -1;
496  }
497 
498  return retval;
499 }
500 
501 qint64 KSocketDevice::peekData(char *data, qint64 maxlen, KSocketAddress *from)
502 {
503  resetError();
504  if (m_sockfd == -1) {
505  return -1; // nothing to do here
506  }
507 
508  if (data == nullptr || maxlen == 0) {
509  return 0; // user doesn't want to read
510  }
511 
512  ssize_t retval;
513  int err = do_read_common(m_sockfd, data, maxlen, from, retval, true);
514 
515  if (err) {
516  setError(static_cast<SocketError>(err));
517  return -1;
518  }
519 
520  return retval;
521 }
522 
523 qint64 KSocketDevice::writeData(const char *data, qint64 len, const KSocketAddress *to)
524 {
525  resetError();
526  if (m_sockfd == -1) {
527  return -1; // can't write to unopen socket
528  }
529 
530  if (data == nullptr || len == 0) {
531  return 0; // nothing to be written
532  }
533 
534  ssize_t retval;
535  if (to != nullptr) {
536  retval = ::sendto(m_sockfd, data, len, 0, to->address(), to->length());
537  } else
538 #ifdef Q_OS_WIN
539  retval = ::send(m_sockfd, data, len, 0);
540 #else
541  retval = ::write(m_sockfd, data, len);
542 #endif
543  if (retval == -1) {
544  if (errno == EAGAIN || errno == EWOULDBLOCK) {
545  setError(WouldBlock);
546  } else {
547  setError(UnknownError);
548  }
549  return -1; // nothing written
550  } else if (retval == 0) {
551  setError(RemotelyDisconnected);
552  }
553 
554  return retval;
555 }
556 
558 {
559  if (m_sockfd == -1) {
560  return KSocketAddress(); // not open, empty value
561  }
562 
563  if (d->local.family() != AF_UNSPEC) {
564  return d->local;
565  }
566 
567  socklen_t len;
569  localAddress.setLength(len = 32); // arbitrary value
570  if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
571  // error!
572  {
573  return d->local = KSocketAddress();
574  }
575 
576 #if HAVE_STRUCT_SOCKADDR_SA_LEN
577  len = localAddress.address()->sa_len;
578 #endif
579 
580  if (len <= localAddress.length()) {
581  // it has fit already
582  localAddress.setLength(len);
583  return d->local = localAddress;
584  }
585 
586  // no, the socket address is actually larger than we had anticipated
587  // call again
588  localAddress.setLength(len);
589  if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
590  // error!
591  {
592  return d->local = KSocketAddress();
593  }
594 
595  return d->local = localAddress;
596 }
597 
599 {
600  if (m_sockfd == -1) {
601  return KSocketAddress(); // not open, empty value
602  }
603 
604  if (d->peer.family() != AF_UNSPEC) {
605  return d->peer;
606  }
607 
608  socklen_t len;
610  peerAddress.setLength(len = 32); // arbitrary value
611  if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
612  // error!
613  {
614  return d->peer = KSocketAddress();
615  }
616 
617 #if HAVE_STRUCT_SOCKADDR_SA_LEN
618  len = peerAddress.address()->sa_len;
619 #endif
620 
621  if (len <= peerAddress.length()) {
622  // it has fit already
623  peerAddress.setLength(len);
624  return d->peer = peerAddress;
625  }
626 
627  // no, the socket address is actually larger than we had anticipated
628  // call again
629  peerAddress.setLength(len);
630  if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
631  // error!
632  {
633  return d->peer = KSocketAddress();
634  }
635 
636  return d->peer = peerAddress;
637 }
638 
640 {
641  // for normal sockets, the externally visible address is the same
642  // as the local address
643  return localAddress();
644 }
645 
647 {
648  if (d->input) {
649  return d->input;
650  }
651 
652  QMutexLocker locker(mutex());
653  if (d->input) {
654  return d->input;
655  }
656 
657  if (m_sockfd == -1) {
658  // socket doesn't exist; can't create notifier
659  return nullptr;
660  }
661 
662  return d->input = createNotifier(QSocketNotifier::Read);
663 }
664 
666 {
667  if (d->output) {
668  return d->output;
669  }
670 
671  QMutexLocker locker(mutex());
672  if (d->output) {
673  return d->output;
674  }
675 
676  if (m_sockfd == -1) {
677  // socket doesn't exist; can't create notifier
678  return nullptr;
679  }
680 
681  return d->output = createNotifier(QSocketNotifier::Write);
682 }
683 
685 {
686  if (d->exception) {
687  return d->exception;
688  }
689 
690  QMutexLocker locker(mutex());
691  if (d->exception) {
692  return d->exception;
693  }
694 
695  if (m_sockfd == -1) {
696  // socket doesn't exist; can't create notifier
697  return nullptr;
698  }
699 
700  return d->exception = createNotifier(QSocketNotifier::Exception);
701 }
702 
703 bool KSocketDevice::poll(bool *input, bool *output, bool *exception,
704  int timeout, bool *timedout)
705 {
706  if (m_sockfd == -1) {
707  setError(NotCreated);
708  return false;
709  }
710 
711  resetError();
712 #if HAVE_POLL
713  struct pollfd fds;
714  fds.fd = m_sockfd;
715  fds.events = 0;
716 
717  if (input) {
718  fds.events |= POLLIN;
719  *input = false;
720  }
721  if (output) {
722  fds.events |= POLLOUT;
723  *output = false;
724  }
725  if (exception) {
726  fds.events |= POLLPRI;
727  *exception = false;
728  }
729 
730  int retval = ::poll(&fds, 1, timeout);
731  if (retval == -1) {
732  setError(UnknownError);
733  return false;
734  }
735  if (retval == 0) {
736  // timeout
737  if (timedout) {
738  *timedout = true;
739  }
740  return true;
741  }
742 
743  if (input && fds.revents & POLLIN) {
744  *input = true;
745  }
746  if (output && fds.revents & POLLOUT) {
747  *output = true;
748  }
749  if (exception && fds.revents & POLLPRI) {
750  *exception = true;
751  }
752  if (timedout) {
753  *timedout = false;
754  }
755 
756  return true;
757 #else
758  /*
759  * We don't have poll(2). We'll have to make do with select(2).
760  */
761 
762  fd_set readfds, writefds, exceptfds;
763  fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
764 
765  if (input) {
766  preadfds = &readfds;
767  FD_ZERO(preadfds);
768  FD_SET(m_sockfd, preadfds);
769  *input = false;
770  }
771  if (output) {
772  pwritefds = &writefds;
773  FD_ZERO(pwritefds);
774  FD_SET(m_sockfd, pwritefds);
775  *output = false;
776  }
777  if (exception) {
778  pexceptfds = &exceptfds;
779  FD_ZERO(pexceptfds);
780  FD_SET(m_sockfd, pexceptfds);
781  *exception = false;
782  }
783 
784  int retval;
785  if (timeout < 0) {
786  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
787  } else {
788  // convert the milliseconds to timeval
789  struct timeval tv;
790  tv.tv_sec = timeout / 1000;
791  tv.tv_usec = timeout % 1000 * 1000;
792 
793  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
794  }
795 
796  if (retval == -1) {
797  setError(UnknownError);
798  return false;
799  }
800  if (retval == 0) {
801  // timeout
802  if (timedout) {
803  *timedout = true;
804  }
805  return true;
806  }
807 
808  if (input && FD_ISSET(m_sockfd, preadfds)) {
809  *input = true;
810  }
811  if (output && FD_ISSET(m_sockfd, pwritefds)) {
812  *output = true;
813  }
814  if (exception && FD_ISSET(m_sockfd, pexceptfds)) {
815  *exception = true;
816  }
817 
818  return true;
819 #endif
820 }
821 
822 bool KSocketDevice::poll(int timeout, bool *timedout)
823 {
824  bool input, output, exception;
825  return poll(&input, &output, &exception, timeout, timedout);
826 }
827 
828 QSocketNotifier *KSocketDevice::createNotifier(QSocketNotifier::Type type) const
829 {
830  if (m_sockfd == -1) {
831  return nullptr;
832  }
833 
834  return new QSocketNotifier(m_sockfd, type);
835 }
836 
837 namespace
838 {
839 // simple class to avoid pointer stuff
840 template<class T> class ptr
841 {
842  typedef T type;
843  type *obj;
844 public:
845  ptr() : obj(0)
846  { }
847 
848  ptr(const ptr<T> &other) : obj(other.obj)
849  { }
850 
851  ptr(type *_obj) : obj(_obj)
852  { }
853 
854  ~ptr()
855  { }
856 
857  ptr<T> &operator=(const ptr<T> &other)
858  {
859  obj = other.obj;
860  return *this;
861  }
862 
863  ptr<T> &operator=(T *_obj)
864  {
865  obj = _obj;
866  return *this;
867  }
868 
869  type *operator->() const
870  {
871  return obj;
872  }
873 
874  operator T *() const
875  {
876  return obj;
877  }
878 
879  bool isNull() const
880  {
881  return obj == 0;
882  }
883 };
884 }
885 
886 static KSocketDeviceFactoryBase *defaultImplFactory;
887 static QMutex defaultImplFactoryMutex;
889 static factoryMap factories;
890 
892 {
893  KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent);
894  if (device != nullptr) {
895  return device;
896  }
897 
898  if (defaultImplFactory) {
899  return defaultImplFactory->create(parent);
900  }
901 
902  // the really default
903  return new KSocketDevice(parent);
904 }
905 
907 {
908  KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent);
909  if (device != nullptr) {
910  return device;
911  }
912 
913  QMutexLocker locker(&defaultImplFactoryMutex);
914  factoryMap::ConstIterator it = factories.constBegin();
915  for (; it != factories.constEnd(); ++it)
916  if ((it.key() & capabilities) == capabilities)
917  // found a match
918  {
919  return it.value()->create(parent);
920  }
921 
922  return nullptr; // no default
923 }
924 
927 {
928  QMutexLocker locker(&defaultImplFactoryMutex);
929  KSocketDeviceFactoryBase *old = defaultImplFactory;
930  defaultImplFactory = factory;
931  return old;
932 }
933 
935 {
936  QMutexLocker locker(&defaultImplFactoryMutex);
937  if (factories.contains(capabilities)) {
938  delete factories[capabilities];
939  }
940  factories.insert(capabilities, factory);
941 }
942 
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.
QString from() const
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:169
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.
QString to() const
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:133
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:139
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:163
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:145
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-2020 The KDE developers.
Generated on Wed May 27 2020 22:55:35 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.