source: trunk/src/network/qsocketdevice_pm.cpp

Last change on this file was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 19.4 KB
Line 
1/****************************************************************************
2** $Id: qsocketdevice_pm.cpp 8 2005-11-16 19:36:46Z dmik $
3**
4** Implementation of QSocketDevice class for OS/2
5**
6** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the network module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qsocketdevice.h"
39#include "qwindowdefs.h"
40#include "qdatetime.h"
41
42#include <string.h>
43
44#include <errno.h>
45#include <sys/time.h>
46#include <sys/socket.h>
47#include <sys/ioctl.h>
48#include <netinet/in.h>
49
50//#define QSOCKETDEVICE_DEBUG
51
52#if !defined (QT_NO_IPV6)
53#error IPv6 is not currently supported on OS/2
54#endif
55
56#define QT_SOCKLEN_T int
57#define QT_SOCKOPTLEN_T QT_SOCKLEN_T
58
59static inline void qt_socket_getportaddr( struct sockaddr *sa,
60 Q_UINT16 *port, QHostAddress *addr )
61{
62#if !defined(QT_NO_IPV6)
63 if ( sa->sa_family == AF_INET6 ) {
64 struct sockaddr_in6 *sa6 = ( struct sockaddr_in6 * )sa;
65 Q_IPV6ADDR tmp;
66 memcpy( &tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp) );
67 QHostAddress a( tmp );
68 *addr = a;
69 *port = ntohs( sa6->sin6_port );
70 return;
71 }
72#endif
73 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
74 QHostAddress a( ntohl( sa4->sin_addr.s_addr ) );
75 *port = ntohs( sa4->sin_port );
76 *addr = QHostAddress( ntohl( sa4->sin_addr.s_addr ) );
77 return;
78}
79
80void QSocketDevice::init()
81{
82}
83
84QSocketDevice::Protocol QSocketDevice::getProtocol() const
85{
86 if ( isValid() ) {
87#if !defined (QT_NO_IPV6)
88 struct sockaddr_storage sa;
89#else
90 struct sockaddr sa;
91#endif
92 memset( &sa, 0, sizeof(sa) );
93 QT_SOCKLEN_T sz = sizeof( sa );
94#if !defined (QT_NO_IPV6)
95 struct sockaddr *sap = reinterpret_cast<struct sockaddr *>(&sa);
96 if ( !::getsockname(fd, sap, &sz) ) {
97 switch ( sap->sa_family ) {
98 case AF_INET:
99 return IPv4;
100 case AF_INET6:
101 return IPv6;
102 default:
103 return Unknown;
104 }
105 }
106#else
107 if ( !::getsockname(fd, &sa, &sz) ) {
108 switch ( sa.sa_family ) {
109 case AF_INET:
110 return IPv4;
111 default:
112 return Unknown;
113 }
114 }
115#endif
116 }
117 return Unknown;
118}
119
120int QSocketDevice::createNewSocket( )
121{
122#if !defined(QT_NO_IPV6)
123 int s = ::socket( protocol() == IPv6 ? AF_INET6 : AF_INET,
124 t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0 );
125#else
126 int s = ::socket( AF_INET, t==Datagram?SOCK_DGRAM:SOCK_STREAM, 0 );
127#endif
128 if ( s < 0 ) {
129 switch( errno ) {
130 case EPROTONOSUPPORT:
131 e = InternalError; // 0 is supposed to work for both types
132 break;
133 case ENFILE:
134 e = NoFiles; // special case for this
135 break;
136 case EACCES:
137 e = Inaccessible;
138 break;
139 case ENOBUFS:
140 case ENOMEM:
141 e = NoResources;
142 break;
143 case EINVAL:
144 e = Impossible;
145 break;
146 default:
147 e = UnknownError;
148 break;
149 }
150 } else {
151 return s;
152 }
153 return -1;
154}
155
156
157void QSocketDevice::close()
158{
159 if ( fd == -1 || !isOpen() ) // already closed
160 return;
161 setFlags( IO_Sequential );
162 resetStatus();
163 setState( 0 );
164 ::soclose( fd );
165#if defined(QSOCKETDEVICE_DEBUG)
166 qDebug( "QSocketDevice::close: Closed socket %x", fd );
167#endif
168 fd = -1;
169 fetchConnectionParameters();
170}
171
172
173bool QSocketDevice::blocking() const
174{
175//@@TODO (dmik): the below 'if...' (which is the same for all platforms)
176// conflicts with Qt docs saying that this method returns FALSE for
177// invalid sockets. why do they conflict?
178 if ( !isValid() )
179 return TRUE;
180 return TRUE;
181}
182
183
184void QSocketDevice::setBlocking( bool enable )
185{
186#if defined(QSOCKETDEVICE_DEBUG)
187 qDebug( "QSocketDevice::setBlocking( %d )", enable );
188#endif
189 if ( !isValid() )
190 return;
191
192 unsigned long dummy = enable ? 0 : 1;
193 if ( ioctl( fd, FIONBIO, &dummy ) >= 0 )
194 return;
195
196 if ( e )
197 return;
198 switch( errno ) {
199 case EACCES:
200 case EBADF:
201 e = Impossible;
202 break;
203 case EFAULT:
204 case EAGAIN:
205#if EAGAIN != EWOULDBLOCK
206 case EWOULDBLOCK:
207#endif
208 case EDEADLK:
209 case EINTR:
210 case EINVAL:
211 case EMFILE:
212 case ENOLCK:
213 case EPERM:
214 default:
215 e = UnknownError;
216 }
217}
218
219
220int QSocketDevice::option( Option opt ) const
221{
222 if ( !isValid() )
223 return -1;
224 int n = -1;
225 int v = -1;
226 switch ( opt ) {
227 case Broadcast:
228 n = SO_BROADCAST;
229 break;
230 case ReceiveBuffer:
231 n = SO_RCVBUF;
232 break;
233 case ReuseAddress:
234 n = SO_REUSEADDR;
235 break;
236 case SendBuffer:
237 n = SO_SNDBUF;
238 break;
239 }
240 if ( n != -1 ) {
241 QT_SOCKOPTLEN_T len;
242 len = sizeof(v);
243 int r = ::getsockopt( fd, SOL_SOCKET, n, (char*)&v, &len );
244 if ( r >= 0 )
245 return v;
246 if ( !e ) {
247 QSocketDevice *that = (QSocketDevice*)this; // mutable function
248 switch( errno ) {
249 case EBADF:
250 case ENOTSOCK:
251 that->e = Impossible;
252 break;
253 case EFAULT:
254 that->e = InternalError;
255 break;
256 default:
257 that->e = UnknownError;
258 break;
259 }
260 }
261 return -1;
262 }
263 return v;
264}
265
266
267void QSocketDevice::setOption( Option opt, int v )
268{
269 if ( !isValid() )
270 return;
271 int n = -1; // for really, really bad compilers
272 switch ( opt ) {
273 case Broadcast:
274 n = SO_BROADCAST;
275 break;
276 case ReceiveBuffer:
277 n = SO_RCVBUF;
278 break;
279 case ReuseAddress:
280 n = SO_REUSEADDR;
281 break;
282 case SendBuffer:
283 n = SO_SNDBUF;
284 break;
285 default:
286 return;
287 }
288 if ( ::setsockopt( fd, SOL_SOCKET, n, (char*)&v, sizeof(v)) < 0 &&
289 e == NoError ) {
290 switch( errno ) {
291 case EBADF:
292 case ENOTSOCK:
293 e = Impossible;
294 break;
295 case EFAULT:
296 e = InternalError;
297 break;
298 default:
299 e = UnknownError;
300 break;
301 }
302 }
303}
304
305
306bool QSocketDevice::connect( const QHostAddress &addr, Q_UINT16 port )
307{
308 if ( !isValid() )
309 return FALSE;
310
311 pa = addr;
312 pp = port;
313
314 struct sockaddr_in a4;
315 struct sockaddr *aa;
316 QT_SOCKLEN_T aalen;
317
318#if !defined(QT_NO_IPV6)
319 struct sockaddr_in6 a6;
320
321 if ( addr.isIPv6Address() ) {
322 memset( &a6, 0, sizeof(a6) );
323 a6.sin6_family = AF_INET6;
324 a6.sin6_port = htons( port );
325 Q_IPV6ADDR ip6 = addr.toIPv6Address();
326 memcpy( &a6.sin6_addr.s6_addr, &ip6, sizeof(ip6) );
327
328 aalen = sizeof( a6 );
329 aa = (struct sockaddr *)&a6;
330 } else
331#endif
332 if ( addr.isIPv4Address() ) {
333 memset( &a4, 0, sizeof(a4) );
334 a4.sin_family = AF_INET;
335 a4.sin_port = htons( port );
336 a4.sin_addr.s_addr = htonl( addr.toIPv4Address() );
337
338 aalen = sizeof(a4);
339 aa = (struct sockaddr *)&a4;
340 } else {
341 e = Impossible;
342 return FALSE;
343 }
344
345 int r = ::connect( fd, aa, aalen );
346 if ( r == 0 ) {
347 fetchConnectionParameters();
348 return TRUE;
349 }
350 if ( errno == EISCONN || errno == EALREADY || errno == EINPROGRESS ) {
351 fetchConnectionParameters();
352 return TRUE;
353 }
354 if ( e != NoError || errno == EAGAIN || errno == EWOULDBLOCK ) {
355 return FALSE;
356 }
357 switch( errno ) {
358 case EBADF:
359 case ENOTSOCK:
360 e = Impossible;
361 break;
362 case EFAULT:
363 case EAFNOSUPPORT:
364 e = InternalError;
365 break;
366 case ECONNREFUSED:
367 e = ConnectionRefused;
368 break;
369 case ETIMEDOUT:
370 case ENETUNREACH:
371 e = NetworkFailure;
372 break;
373 case EADDRINUSE:
374 e = NoResources;
375 break;
376 case EACCES:
377 case EPERM:
378 e = Inaccessible;
379 break;
380 default:
381 e = UnknownError;
382 break;
383 }
384 return FALSE;
385}
386
387
388bool QSocketDevice::bind( const QHostAddress &address, Q_UINT16 port )
389{
390 if ( !isValid() )
391 return FALSE;
392 int r;
393 struct sockaddr_in a4;
394#if !defined(QT_NO_IPV6)
395 struct sockaddr_in6 a6;
396
397 if ( address.isIPv6Address() ) {
398 memset( &a6, 0, sizeof(a6) );
399 a6.sin6_family = AF_INET6;
400 a6.sin6_port = htons( port );
401 Q_IPV6ADDR tmp = address.toIPv6Address();
402 memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
403
404 r = ::bind( fd, (struct sockaddr *)&a6, sizeof(a6) );
405 } else
406#endif
407 if ( address.isIPv4Address() ) {
408 memset( &a4, 0, sizeof(a4) );
409 a4.sin_family = AF_INET;
410 a4.sin_port = htons( port );
411 a4.sin_addr.s_addr = htonl( address.toIPv4Address() );
412
413 r = ::bind( fd, (struct sockaddr*)&a4, sizeof(a4) );
414 } else {
415 e = Impossible;
416 return FALSE;
417 }
418
419 if ( r < 0 ) {
420 switch( errno ) {
421 case EINVAL:
422 e = AlreadyBound;
423 break;
424 case EACCES:
425 e = Inaccessible;
426 break;
427 case ENOMEM:
428 e = NoResources;
429 break;
430 case EFAULT: // a was illegal
431 case ENAMETOOLONG: // sz was wrong
432 e = InternalError;
433 break;
434 case EBADF: // AF_UNIX only
435 case ENOTSOCK: // AF_UNIX only
436 case EROFS: // AF_UNIX only
437 case ENOENT: // AF_UNIX only
438 case ENOTDIR: // AF_UNIX only
439 case ELOOP: // AF_UNIX only
440 e = Impossible;
441 break;
442 default:
443 e = UnknownError;
444 break;
445 }
446 return FALSE;
447 }
448 fetchConnectionParameters();
449 return TRUE;
450}
451
452
453bool QSocketDevice::listen( int backlog )
454{
455 if ( !isValid() )
456 return FALSE;
457 if ( ::listen( fd, backlog ) >= 0 )
458 return TRUE;
459 if ( !e )
460 e = Impossible;
461 return FALSE;
462}
463
464
465int QSocketDevice::accept()
466{
467 if ( !isValid() )
468 return -1;
469
470#if !defined (QT_NO_IPV6)
471 struct sockaddr_storage aa;
472#else
473 struct sockaddr aa;
474#endif
475 QT_SOCKLEN_T l = sizeof( aa );
476 bool done;
477 int s;
478 do {
479 s = ::accept( fd, (struct sockaddr*)&aa, &l );
480 // we'll blithely throw away the stuff accept() wrote to aa
481 done = TRUE;
482 if ( s < 0 && e == NoError ) {
483 switch( errno ) {
484 case EINTR:
485 done = FALSE;
486 break;
487#if defined(EPROTO)
488 case EPROTO:
489#endif
490#if defined(ENONET)
491 case ENONET:
492#endif
493 case ENOPROTOOPT:
494 case EHOSTDOWN:
495 case EOPNOTSUPP:
496 case EHOSTUNREACH:
497 case ENETDOWN:
498 case ENETUNREACH:
499 case ETIMEDOUT:
500 // in all these cases, an error happened during connection
501 // setup. we're not interested in what happened, so we
502 // just treat it like the client-closed-quickly case.
503 case EPERM:
504 // firewalling wouldn't let us accept. we treat it like
505 // the client-closed-quickly case.
506 case EAGAIN:
507#if EAGAIN != EWOULDBLOCK
508 case EWOULDBLOCK:
509#endif
510 // the client closed the connection before we got around
511 // to accept()ing it.
512 break;
513 case EBADF:
514 case ENOTSOCK:
515 e = Impossible;
516 break;
517 case EFAULT:
518 e = InternalError;
519 break;
520 case ENOMEM:
521 case ENOBUFS:
522 e = NoResources;
523 break;
524 default:
525 e = UnknownError;
526 break;
527 }
528 }
529 } while (!done);
530 return s;
531}
532
533
534Q_LONG QSocketDevice::bytesAvailable() const
535{
536 if ( !isValid() )
537 return -1;
538 size_t nbytes = 0;
539 // gives shorter than true amounts on Unix domain sockets.
540 if ( ::ioctl(fd, FIONREAD, (char*)&nbytes) < 0 )
541 return -1;
542 return (Q_LONG) *((int *) &nbytes);
543}
544
545
546Q_LONG QSocketDevice::waitForMore( int msecs, bool *timeout ) const
547{
548 if ( !isValid() )
549 return -1;
550 if ( fd >= FD_SETSIZE )
551 return -1;
552
553 fd_set fds;
554 struct timeval tv;
555
556 FD_ZERO( &fds );
557 FD_SET( fd, &fds );
558
559 tv.tv_sec = msecs / 1000;
560 tv.tv_usec = (msecs % 1000) * 1000;
561
562 int rv = select( fd+1, &fds, 0, 0, msecs < 0 ? 0 : &tv );
563
564 if ( rv < 0 )
565 return -1;
566
567 if ( timeout ) {
568 if ( rv == 0 )
569 *timeout = TRUE;
570 else
571 *timeout = FALSE;
572 }
573
574 return bytesAvailable();
575}
576
577
578Q_LONG QSocketDevice::readBlock( char *data, Q_ULONG maxlen )
579{
580#if defined(QT_CHECK_NULL)
581 if ( data == 0 && maxlen != 0 ) {
582 qWarning( "QSocketDevice::readBlock: Null pointer error" );
583 }
584#endif
585#if defined(QT_CHECK_STATE)
586 if ( !isValid() ) {
587 qWarning( "QSocketDevice::readBlock: Invalid socket" );
588 return -1;
589 }
590 if ( !isOpen() ) {
591 qWarning( "QSocketDevice::readBlock: Device is not open" );
592 return -1;
593 }
594 if ( !isReadable() ) {
595 qWarning( "QSocketDevice::readBlock: Read operation not permitted" );
596 return -1;
597 }
598#endif
599 bool done = FALSE;
600 int r = 0;
601 while ( done == FALSE ) {
602 if ( t == Datagram ) {
603#if !defined(QT_NO_IPV6)
604 struct sockaddr_storage aa;
605#else
606 struct sockaddr_in aa;
607#endif
608 memset( &aa, 0, sizeof(aa) );
609 QT_SOCKLEN_T sz;
610 sz = sizeof( aa );
611 r = ::recvfrom( fd, data, maxlen, 0,
612 (struct sockaddr *)&aa, &sz );
613
614 qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);
615
616 } else {
617 r = ::recv( fd, data, maxlen, 0 );
618 }
619 done = TRUE;
620 if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
621 // nothing
622 } else if ( errno == EINTR ) {
623 done = FALSE;
624 } else if ( e == NoError ) {
625 switch( errno ) {
626 case EIO:
627 case EISDIR:
628 case EBADF:
629 case EINVAL:
630 case EFAULT:
631 case ENOTCONN:
632 case ENOTSOCK:
633 e = Impossible;
634 break;
635#if defined(ENONET)
636 case ENONET:
637#endif
638 case EHOSTUNREACH:
639 case ENETDOWN:
640 case ENETUNREACH:
641 case ETIMEDOUT:
642 e = NetworkFailure;
643 break;
644 case EPIPE:
645 case ECONNRESET:
646 // connection closed
647 close();
648 r = 0;
649 break;
650 default:
651 e = UnknownError;
652 break;
653 }
654 }
655 }
656 return r;
657}
658
659
660Q_LONG QSocketDevice::writeBlock( const char *data, Q_ULONG len )
661{
662 if ( data == 0 && len != 0 ) {
663#if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
664 qWarning( "QSocketDevice::writeBlock: Null pointer error" );
665#endif
666 return -1;
667 }
668 if ( !isValid() ) {
669#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
670 qWarning( "QSocketDevice::writeBlock: Invalid socket" );
671#endif
672 return -1;
673 }
674 if ( !isOpen() ) {
675#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
676 qWarning( "QSocketDevice::writeBlock: Device is not open" );
677#endif
678 return -1;
679 }
680 if ( !isWritable() ) {
681#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
682 qWarning( "QSocketDevice::writeBlock: Write operation not permitted" );
683#endif
684 return -1;
685 }
686 bool done = FALSE;
687 int r = 0;
688 bool timeout;
689 while ( !done ) {
690 r = ::send( fd, data, len, 0 );
691 done = TRUE;
692 if ( r < 0 && e == NoError &&
693 errno != EAGAIN && errno != EWOULDBLOCK ) {
694 switch( errno ) {
695 case EINTR: // signal - call read() or whatever again
696 done = FALSE;
697 break;
698 case EPIPE:
699 // connection closed
700 close();
701 r = 0;
702 break;
703 case ENOSPC:
704 case EIO:
705 case EISDIR:
706 case EBADF:
707 case EINVAL:
708 case EFAULT:
709 case ENOTCONN:
710 case ENOTSOCK:
711 e = Impossible;
712 break;
713#if defined(ENONET)
714 case ENONET:
715#endif
716 case EHOSTUNREACH:
717 case ENETDOWN:
718 case ENETUNREACH:
719 case ETIMEDOUT:
720 e = NetworkFailure;
721 break;
722 default:
723 e = UnknownError;
724 break;
725 }
726 } else if ( waitForMore( 0, &timeout ) == 0 ) {
727 if ( !timeout ) {
728 // connection closed
729 close();
730 }
731 }
732 }
733 return r;
734}
735
736
737Q_LONG QSocketDevice::writeBlock( const char * data, Q_ULONG len,
738 const QHostAddress & host, Q_UINT16 port )
739{
740 if ( t != Datagram ) {
741#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
742 qWarning( "QSocketDevice::sendBlock: Not datagram" );
743#endif
744 return -1; // for now - later we can do t/tcp
745 }
746
747 if ( data == 0 && len != 0 ) {
748#if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
749 qWarning( "QSocketDevice::sendBlock: Null pointer error" );
750#endif
751 return -1;
752 }
753 if ( !isValid() ) {
754#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
755 qWarning( "QSocketDevice::sendBlock: Invalid socket" );
756#endif
757 return -1;
758 }
759 if ( !isOpen() ) {
760#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
761 qWarning( "QSocketDevice::sendBlock: Device is not open" );
762#endif
763 return -1;
764 }
765 if ( !isWritable() ) {
766#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
767 qWarning( "QSocketDevice::sendBlock: Write operation not permitted" );
768#endif
769 return -1;
770 }
771 struct sockaddr_in a4;
772 struct sockaddr *aa;
773 QT_SOCKLEN_T slen;
774#if !defined(QT_NO_IPV6)
775 struct sockaddr_in6 a6;
776 if ( host.isIPv6Address() ) {
777 memset( &a6, 0, sizeof(a6) );
778 a6.sin6_family = AF_INET6;
779 a6.sin6_port = htons( port );
780
781 Q_IPV6ADDR tmp = host.toIPv6Address();
782 memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
783 slen = sizeof( a6 );
784 aa = (struct sockaddr *)&a6;
785 } else
786#endif
787 if ( host.isIPv4Address() ) {
788 memset( &a4, 0, sizeof(a4) );
789 a4.sin_family = AF_INET;
790 a4.sin_port = htons( port );
791 a4.sin_addr.s_addr = htonl( host.toIPv4Address() );
792 slen = sizeof(a4);
793 aa = (struct sockaddr *)&a4;
794 } else {
795 e = Impossible;
796 return -1;
797 }
798
799 // we'd use MSG_DONTWAIT + MSG_NOSIGNAL if Stevens were right.
800 // but apparently Stevens and most implementors disagree
801 bool done = FALSE;
802 int r = 0;
803 while ( !done ) {
804 r = ::sendto( fd, data, len, 0, aa, slen);
805 done = TRUE;
806 if ( r < 0 && e == NoError &&
807 errno != EAGAIN && errno != EWOULDBLOCK ) {
808 switch( errno ) {
809 case EINTR: // signal - call read() or whatever again
810 done = FALSE;
811 break;
812 case ENOSPC:
813 case EPIPE:
814 case EIO:
815 case EISDIR:
816 case EBADF:
817 case EINVAL:
818 case EFAULT:
819 case ENOTCONN:
820 case ENOTSOCK:
821 e = Impossible;
822 break;
823#if defined(ENONET)
824 case ENONET:
825#endif
826 case EHOSTUNREACH:
827 case ENETDOWN:
828 case ENETUNREACH:
829 case ETIMEDOUT:
830 e = NetworkFailure;
831 break;
832 default:
833 e = UnknownError;
834 break;
835 }
836 }
837 }
838 return r;
839}
840
841
842void QSocketDevice::fetchConnectionParameters()
843{
844 if ( !isValid() ) {
845 p = 0;
846 a = QHostAddress();
847 pp = 0;
848 pa = QHostAddress();
849 return;
850 }
851#if !defined(QT_NO_IPV6)
852 struct sockaddr_storage sa;
853#else
854 struct sockaddr_in sa;
855#endif
856 memset( &sa, 0, sizeof(sa) );
857 QT_SOCKLEN_T sz;
858 sz = sizeof( sa );
859 if ( !::getsockname( fd, (struct sockaddr *)(&sa), &sz ) )
860 qt_socket_getportaddr( (struct sockaddr *)&sa, &p, &a );
861
862 sz = sizeof( sa );
863 if ( !::getpeername( fd, (struct sockaddr *)(&sa), &sz ) )
864 qt_socket_getportaddr( (struct sockaddr *)&sa, &pp, &pa );
865}
866
867
868Q_UINT16 QSocketDevice::peerPort() const
869{
870 return pp;
871}
872
873
874QHostAddress QSocketDevice::peerAddress() const
875{
876 return pa;
877}
878
Note: See TracBrowser for help on using the repository browser.