libzypp 17.37.17
socket.cc
Go to the documentation of this file.
1#include "private/socket_p.h"
2#include <errno.h>
3#include <string.h>
6#include <zypp-core/zyppng/base/EventDispatcher>
8#include <sys/ioctl.h> //For FIONREAD
9#include <sys/types.h>
10#include <sys/socket.h>
11#include <fcntl.h>
12
13#include <iostream>
14
15namespace zyppng {
16
18 : _writeBuffer( std::move(writeBuffer) )
19 { }
20
22 {
23 if ( _socket >= 0 )
24 return true;
25
27 _emittedErr = false;
28
29 // Since Linux 2.6.27 we can pass additional flags with the type argument to avoid fcntl
30 // if creating sockets fails we might need to change that
31 _socket = eintrSafeCall( ::socket, _domain, _type | SOCK_NONBLOCK | SOCK_CLOEXEC, _protocol );
32 if ( _socket >= 0 )
33 return true;
34
35 switch ( errno ) {
36 case EACCES:
38 break;
39 case EINVAL:
41 break;
42 case EMFILE:
43 case ENFILE:
44 case ENOBUFS:
45 case ENOMEM:
47 break;
48 case EAFNOSUPPORT:
49 case EPROTONOSUPPORT:
51 break;
52 default:
54 break;
55 }
56
57 return false;
58 }
59
60 void SocketPrivate::setError( Socket::SocketError error , std::string &&err, bool emit )
61 {
62 // we only remember the first error that happend
63 if ( _error == Socket::NoError && _error != error ) {
64 _emittedErr = emit;
65 _error = error;
66 _errorDesc = std::move(err);
67 }
68 if ( emit && !_emittedErr )
69 _sigError.emit( error );
70 }
71
73 {
74 const auto oldState = state();
75
76 if ( oldState == newState )
77 return true;
78
79 switch ( newState ) {
81 setError( Socket::InternalError, "Invalid state transition" );
82 return false;
84 if ( oldState != Socket::InitialState && oldState != Socket::ClosedState ) {
85 setError( Socket::InternalError, "Invalid state transition" );
86 return false;
87 }
89 return connectToHost();
90 break;
92 if ( oldState != Socket::InitialState && oldState != Socket::ConnectingState ) {
93 setError( Socket::InternalError, "Invalid state transition" );
94 return false;
95 }
96 auto &s = _state.emplace<SocketPrivate::ConnectedState>();
98 s._socketNotifier->connect( &SocketNotifier::sigActivated, *this, &SocketPrivate::onSocketActivatedSlot );
99
100 z_func()->IODevice::open( IODevice::ReadOnly | IODevice::WriteOnly );
101
102 _connected.emit();
103 break;
104 }
106 if ( state() != Socket::InitialState ) {
107 setError( Socket::InternalError, "Invalid state transition" );
108 return false;
109 }
110 auto &s = _state.emplace<SocketPrivate::ListeningState>();
112 s._socketNotifier->connect( &SocketNotifier::sigActivated, *this, &SocketPrivate::onSocketActivatedSlot );
113 break;
114 }
116 if ( state() != Socket::ConnectedState ) {
117 setError( Socket::InternalError, "Invalid state transition" );
118 return false;
119 }
120
121 auto wbOld = std::move( std::get<ConnectedState>(_state)._writeBuffer );
122 auto &s = _state.emplace<SocketPrivate::ClosingState>( std::move( wbOld ) );
124 s._socketNotifier->connect( &SocketNotifier::sigActivated, *this, &SocketPrivate::onSocketActivatedSlot );
125 break;
126 }
127 case Socket::ClosedState: {
129 if ( z_func()->canRead() )
130 z_func()->finishReadChannel( 0 );
131 if ( _socket >= 0 && !_borrowedSocket )
132 ::close( _socket );
133 _socket = -1;
134 _targetAddr.reset();
135 _disconnected.emit();
136 z_func()->IODevice::close();
137 break;
138 }
139 }
140 return true;
141 }
142
144 {
145 auto &state = std::get<ConnectingState>( _state );
146
147 const int res = eintrSafeCall( ::connect, _socket, _targetAddr->nativeSockAddr(), _targetAddr->size() );
148
149 auto doDelayedConnect = [ this, &state ](){
150 if ( !state._connectNotifier ) {
151 state._connectNotifier = SocketNotifier::create( _socket, SocketNotifier::Write, true );
152 state._connectNotifier->connect( &SocketNotifier::sigActivated, *this, &SocketPrivate::onSocketActivatedSlot );
153 }
154
155 if ( !state._connectTimeout ) {
156 state._connectTimeout = Timer::create();
157 state._connectTimeout->connectFunc( &Timer::sigExpired, [this, &state ]( const auto &) {
158 setError( Socket::ConnectionTimeout, "The connection timed out." );
159 state._connectNotifier.reset();
160 state._connectTimeout.reset();
161 }, *z_func());
162 }
163 state._connectTimeout->setSingleShot( true );
164 state._connectTimeout->start( 30000 );
166 return false;
167 };
168
169 if ( res < 0 ) {
170 switch ( errno ) {
171 case EAGAIN: {
172 if ( _targetAddr->nativeSockAddr()->sa_family == AF_UNIX ) {
173 // the Servers backlog is full , we need to wait
174 return doDelayedConnect();
175 } else {
177 z_func()->close();
178 return false;
179 }
180 break;
181 }
182 case EINPROGRESS:
183 return doDelayedConnect();
184 break;
185
186 default:
187 if ( handleConnectError( errno ) == false ) {
188 z_func()->close();
189 return false;
190 }
191 }
192 }
193
194 // connected yay
196 z_func()->close();
197 return false;
198 }
199 return true;
200 }
201
203 {
204 if ( state() != Socket::ConnectedState )
205 return 0;
206
208 }
209
211 {
212 Z_Z();
213 auto bytesToRead = rawBytesAvailable();
214 if ( bytesToRead == 0 ) {
215 // make sure to check if bytes are available even if the ioctl call returns something different
216 bytesToRead = 4096;
217 }
218
219 auto &readBuf = _readChannels[0];
220 char *buf = readBuf.reserve( bytesToRead );
221 const auto bytesRead = z_func()->readData( 0, buf, bytesToRead );
222
223 if ( bytesRead <= 0 ) {
224 readBuf.chop( bytesToRead );
225
226 switch ( bytesRead ) {
227 case -2:
228 // there is simply no data to read ignore and try again
229 return true;
230 case 0: {
231 // remote close
232 setError( Socket::ConnectionClosedByRemote, "The remote host closed the connection", true );
233 break;
234 }
235 case -1:
236 default: {
238 break;
239 }
240 }
241 z->abort();
242 return false;
243 }
244
245 if ( bytesToRead > bytesRead )
246 readBuf.chop( bytesToRead-bytesRead );
247
248 _readyRead.emit();
249 _channelReadyRead.emit(0);
250 return true;
251 }
252
254 {
255 return std::visit( [this]( auto &s ){
256 using T = std::decay_t<decltype (s)>;
257 if constexpr ( std::is_same_v<T, ConnectedState> || std::is_same_v<T, ClosingState> ) {
258 const auto nwrite = s._writeBuffer.frontSize();
259 if ( !nwrite ) {
260 // disable Write notifications so we do not wake up without the need to
261 s._socketNotifier->setMode( SocketNotifier::Read | SocketNotifier::Error );
262 return true;
263 }
264
265 const auto nBuf = s._writeBuffer.front();
266 const auto written = eintrSafeCall( ::send, _socket, nBuf, nwrite, MSG_NOSIGNAL );
267 if ( written == -1 ) {
268 switch ( errno ) {
269 case EACCES:
271 return false;
272 case EAGAIN:
273#if EAGAIN != EWOULDBLOCK
274 case EWOULDBLOCK:
275#endif
276 return true;
277 case EPIPE:
278 case ECONNRESET:
280 return false;
281 default:
283 return false;
284 }
285 return false;
286 }
287 s._writeBuffer.discard( written );
288 _sigBytesWritten.emit( written );
289 if ( s._writeBuffer.size() == 0 )
290 _sigAllBytesWritten.emit();
291 }
292 return true;
293 }, _state );
294 }
295
301 {
302 switch ( error ) {
303 case EACCES:
304 case EPERM:
306 return false;
307 case EADDRINUSE:
309 return false;
310 case EADDRNOTAVAIL:
312 return false;
313 case EAFNOSUPPORT:
315 return false;
316 case ETIMEDOUT:
318 return false;
319 case EALREADY:
321 return false;
322 case ECONNREFUSED:
324 return false;
325 case EBADF:
326 case EFAULT:
327 case ENOTSOCK:
328 setError( Socket::InternalError, strerr_cxx() ); // this can only happen if we screw up
329 return false;
330 case ENETUNREACH:
332 return false;
333 case EPROTOTYPE:
335 return false;
336 case EISCONN:
337 break;
338 }
339 return true;
340 }
341
342
344 {
345 std::visit( [ this, &ev ] ( const auto &currState ) {
346 using T = std::decay_t<decltype(currState)>;
347 if constexpr ( std::is_same<ConnectingState, T>() ) {
349 if ( this->_targetAddr->nativeSockAddr()->sa_family == AF_UNIX ) {
350 // for AF_UNIX sockets we just call connect again
351 this->connectToHost();
352 return;
353 } else {
354
355 // for others we check with getsockopt as mentioned in connect(2) if the conn was successful
356 int err = 0;
357 socklen_t errSize = sizeof ( err );
358 ::getsockopt( _socket, SOL_SOCKET, SO_ERROR, &err, &errSize );
359
360 if ( err == 0 || err == EISCONN ) {
362 } else {
363 if ( err == EINPROGRESS || err == EAGAIN || err == EALREADY )
364 return;
365 handleConnectError( err );
366 z_func()->abort();
367 }
368 }
369 }
370
371 } else if constexpr ( std::is_same<ConnectedState, T>() ) {
373 if ( !writePendingData() ) {
374 z_func()->abort();
375 return;
376 }
377 }
379 if ( !readRawBytesToBuffer() ) {
380 z_func()->abort();
381 return;
382 }
383 }
385 return;
386 }
387
388 } else if constexpr ( std::is_same<ClosingState, T>() ) {
389
391 if ( !writePendingData() ) {
392 z_func()->abort();
393 return;
394
395 }
396
397 if ( currState._writeBuffer.size() == 0 ) {
399 }
400 }
401
402 } else if constexpr ( std::is_same<ListeningState, T>() ) {
403
404 //signal that we have pending connections
405 _incomingConnection.emit();
406
407 } else {
408 DBG << "Unexpected state on socket activation" << std::endl;
409 }
410 },_state);
411 }
412
414 {
415 return std::visit([]( const auto &s ) constexpr { return s.type(); }, _state );
416 }
417
418 Socket::Ptr SocketPrivate::wrapSocket(int fd, int domain, int type, int protocol, Socket::SocketState state)
419 {
420 // from here on the Socket instance owns the fd, no need to manually close it
421 // in case of error
422 auto sptr = Socket::create( domain, type, protocol );
423 sptr->d_func()->_socket = fd;
424
425 // make sure the socket is non blocking
426 if ( !sptr->setBlocking( false ) ) {
427 DBG << "Failed to unblock socket." << std::endl;
428 return nullptr;
429 }
430
431 if( sptr->d_func()->transition( state ) )
432 return sptr;
433
434 return nullptr;
435 }
436
438
439 Socket::Socket( int domain, int type, int protocol )
440 : IODevice( *( new SocketPrivate( domain, type, protocol, *this )))
441 { }
442
443 int64_t Socket::rawBytesAvailable( uint channel ) const
444 {
445 if ( channel != 0 ) {
446 constexpr std::string_view msg("Socket does not support multiple read channels");
447 ERR << msg << std::endl;
448 throw std::logic_error( msg.data() );
449 }
450 return d_func()->rawBytesAvailable();
451 }
452
454 {
455 this->abort();
456 }
457
458 Socket::Ptr Socket::create( int domain, int type, int protocol )
459 {
460 return Ptr( new Socket( domain, type, protocol ) );
461 }
462
463 bool Socket::bind( const std::shared_ptr<SockAddr> &addr )
464 {
465 Z_D();
466 if ( !addr || !d->initSocket() )
467 return false;
468
469 int res = eintrSafeCall( ::bind, d->_socket, addr->nativeSockAddr(), addr->size() );
470 if ( res >= 0) return true;
471
472 switch ( errno ) {
473 case EACCES:
475 break;
476 case EADDRINUSE:
477 d->setError( Socket::AddressInUse, strerr_cxx() );
478 break;
479 case EBADF:
480 case ENOTSOCK:
481 case EFAULT:
482 d->setError( Socket::InternalError, strerr_cxx() ); // this can only happen if we screw up
483 break;
484 case EINVAL:
485 d->setError( Socket::SocketAlreadyBound, strerr_cxx() );
486 break;
487 case EADDRNOTAVAIL:
488 d->setError( Socket::AddressNotAvailable, strerr_cxx() );
489 break;
490 case ELOOP:
491 case ENAMETOOLONG:
492 case ENOENT:
493 case ENOTDIR:
494 case EROFS:
495 d->setError( Socket::AddressIssue, strerr_cxx() );
496 break;
497 case ENOMEM:
499 break;
500 default:
501 d->setError( Socket::UnknownSocketError, strerr_cxx() );
502 break;
503 }
504
505 abort();
506 return false;
507 }
508
509 bool Socket::listen(int backlog)
510 {
511 Z_D();
512 if ( !d->initSocket() )
513 return false;
514
515 int res = eintrSafeCall( ::listen, d->_socket, backlog );
516 if ( res >= 0 ) {
517 d->transition( Socket::ListeningState );
518 return true;
519 }
520
521 switch ( errno ) {
522
523 case EADDRINUSE:
524 d->setError( Socket::AddressInUse, strerr_cxx() );
525 break;
526 case EBADF:
527 case ENOTSOCK:
528 d->setError( Socket::InternalError, strerr_cxx() ); // this can only happen if we screw up
529 break;
530 case EOPNOTSUPP:
532 break;
533
534 }
535 return false;
536 }
537
539 {
540 Z_D();
541 if ( d->_socket == -1 )
542 return nullptr;
543
544 //accept new pending connections
545 const auto res = eintrSafeCall( ::accept4, d->_socket, (struct sockaddr*)nullptr, (socklen_t *)nullptr, SOCK_CLOEXEC );
546 if ( res < 0 ) {
547 switch ( errno ) {
548#if EAGAIN != EWOULDBLOCK
549 case EWOULDBLOCK:
550#endif
551 case EAGAIN:
552 case ECONNABORTED:
553 return nullptr;
554 break;
555 default:
556 d->setError( Socket::InternalError, strerr_cxx() );
557 return nullptr;
558 }
559 }
560
561 return SocketPrivate::wrapSocket( res, d->_domain, d->_type, d->_protocol, Socket::ConnectedState );
562 }
563
565 {
566
567 int domain = 0;
568 socklen_t optlen = sizeof(domain);
569 int res = getsockopt( fd, SOL_SOCKET, SO_DOMAIN, &domain, &optlen );
570 if ( res < 0 ) {
571 DBG << "Error querying socket domain: " << strerr_cxx() << std::endl;
572 ::close(fd);
573 return nullptr;
574 }
575
576 int protocol = 0;
577 optlen = sizeof(protocol);
578 res = getsockopt( fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen );
579 if ( res < 0 ) {
580 DBG << "Error querying socket protocol: " << strerr_cxx() << std::endl;
581 ::close(fd);
582 return nullptr;
583 }
584
585 int type = 0;
586 optlen = sizeof(type);
587 res = getsockopt( fd, SOL_SOCKET, SO_TYPE, &type, &optlen );
588 if ( res < 0 ) {
589 DBG << "Error querying socket type: " << strerr_cxx() << std::endl;
590 ::close(fd);
591 return nullptr;
592 }
593
594 return SocketPrivate::wrapSocket( fd, domain, type, protocol, state );
595 }
596
597 bool Socket::setBlocking( const bool set )
598 {
599 Z_D();
600
601 if ( !d->initSocket() )
602 return false;
603
604 const int oldFlags = fcntl( d->_socket, F_GETFL, 0 );
605 if (oldFlags == -1) return false;
606
607 const int flags = set ? ( oldFlags & ~(O_NONBLOCK) ) : ( oldFlags | O_NONBLOCK );
608
609 // no need to do a syscall if we do not change anything
610 if ( flags == oldFlags )
611 return true;
612
613 if ( fcntl( d->_socket, F_SETFL, flags ) != 0) {
614 return false;
615 }
616 return true;
617 }
618
619 bool Socket::connect( std::shared_ptr<SockAddr> addr )
620 {
621 Z_D();
622
623 if ( !addr || ( d->state() != Socket::InitialState && d->state() != Socket::ClosedState ) )
624 return false;
625
626 if ( !d->initSocket() )
627 return false;
628
629 d->_targetAddr = std::move(addr);
630 if ( !d->transition( Socket::ConnectingState ) ) {
631 abort();
632 return false;
633 }
634
635 return d->state() == Socket::ConnectedState;
636 }
637
639 {
640 Z_D();
641 return d->_socket;
642 }
643
645 {
646 Z_D();
647 auto sock = d->_socket;
648 d->_socket = -1;
649 d->transition( Socket::ClosedState );
650 return sock;
651 }
652
654 {
655 Z_D();
656 return d->_error;
657 }
658
660 {
661 Z_D();
662 d->transition( ClosedState );
663 }
664
666 {
667 disconnect();
668 }
669
671 {
672 Z_D();
673 std::visit([&d]( const auto &s ){
674 using Type = std::decay_t<decltype (s)>;
675 if constexpr ( std::is_same_v<Type, SocketPrivate::ConnectedState > ) {
676 // we still have pending data, we need to wait for it to be written
677 if ( s._writeBuffer.size() ) {
678 d->transition( Socket::ClosingState );
679 return;
680 }
681 }
682 d->transition( Socket::ClosedState );
683 }, d->_state );
684
685 }
686
687 int64_t Socket::writeData( const char *data, int64_t count )
688 {
689 Z_D();
690 if ( d->state() != SocketState::ConnectedState )
691 return 0;
692
693 auto &s = std::get<SocketPrivate::ConnectedState>( d->_state );
694
695 // if the write buffer has already data we need to append to it to keep the correct order
696 if ( s._writeBuffer.size() ) {
697 s._writeBuffer.append( data, count );
698 //lets try to write some of it
699 d->writePendingData();
700 return count;
701 }
702
703 auto written = eintrSafeCall( ::send, d->_socket, data, count, MSG_NOSIGNAL );
704 if ( written == -1 ) {
705 switch ( errno ) {
706#if EAGAIN != EWOULDBLOCK
707 case EWOULDBLOCK:
708#endif
709 case EAGAIN: {
710 written = 0;
711 break;
712 }
713 case EPIPE:
714 case ECONNRESET: {
715 d->setError( Socket::ConnectionClosedByRemote, strerr_cxx( errno ) );
716 return -1;
717 }
718 default: {
719 d->setError( Socket::UnknownSocketError, strerr_cxx( errno ) );
720 return -1;
721 }
722 }
723 }
724
725 if ( written >= 0 ) {
726 if ( written < count ) {
727 // append the rest of the data to the buffer, so we can return always the full count
728 s._writeBuffer.append( data + written, count - written );
729 s._socketNotifier->setMode( SocketNotifier::Read | SocketNotifier::Write | SocketNotifier::Error );
730 }
731 if ( written > 0 )
732 d->_sigBytesWritten.emit( written );
733 }
734
735 if ( s._writeBuffer.size() == 0 )
736 d->_sigAllBytesWritten.emit();
737
738 return count;
739 }
740
741 bool Socket::waitForConnected( int timeout )
742 {
743 Z_D();
744 if ( d->state() == Socket::ConnectedState )
745 return true;
746 // we can only wait if we are in connecting state
747 while ( d->state() == Socket::ConnectingState ) {
748 int rEvents = 0;
749 if ( EventDispatcher::waitForFdEvent( d->_socket, AbstractEventSource::Write, rEvents, timeout ) ) {
750 d->onSocketActivated( rEvents );
751 } else {
752 // timeout
753 return false;
754 }
755 }
756 return d->state() == Socket::ConnectedState;
757 }
758
760 {
761 Z_D();
762
763 bool canContinue = true;
764 bool bufferEmpty = false;
765
766 while ( canContinue && !bufferEmpty ) {
767
768 if ( d->state() != Socket::ConnectedState && d->state() != Socket::ClosingState)
769 return false;
770
771 std::visit([&]( const auto &s ){
772 using T = std::decay_t<decltype (s)>;
773 if constexpr ( std::is_same_v<T, SocketPrivate::ConnectedState> || std::is_same_v<T, SocketPrivate::ClosingState> ) {
774 if ( s._writeBuffer.size() > 0 ) {
775 int rEvents = 0;
776 canContinue = EventDispatcher::waitForFdEvent( d->_socket, AbstractEventSource::Write | AbstractEventSource::Read, rEvents, timeout );
777 if ( canContinue ) {
778 //this will trigger the bytesWritten signal, we check there if the buffer is empty
779 d->onSocketActivated( rEvents );
780 }
781 }
782 if ( s._writeBuffer.size() == 0 ){
783 canContinue = false;
784 bufferEmpty = true;
785 }
786 }
787 }, d->_state );
788 }
789 return bufferEmpty;
790 }
791
792 bool Socket::waitForReadyRead( uint channel, int timeout)
793 {
794 Z_D();
795 if ( d->state() != Socket::ConnectedState || channel != 0 )
796 return false;
797
798 // we can only wait if we are in connected state
799 while ( d->state() == Socket::ConnectedState && bytesAvailable() <= 0 ) {
800 int rEvents = 0;
802 d->onSocketActivated( rEvents );
803 } else {
804 //timeout
805 return false;
806 }
807 }
808 return bytesAvailable() > 0;
809 }
810
811 int64_t Socket::readData( uint channel, char *buffer, int64_t bufsize )
812 {
813 if ( channel != 0 ) {
814 constexpr std::string_view msg("Socket does not support multiple read channels");
815 ERR << msg << std::endl;
816 throw std::logic_error( msg.data() );
817 }
818
819 Z_D();
820 if ( d->state() != SocketState::ConnectedState )
821 return -1;
822
823 const auto read = eintrSafeCall( ::read, d->_socket, buffer, bufsize );
824
825 // special case for remote close
826 if ( read == 0 ) {
827 d->setError( ConnectionClosedByRemote, "The remote host closed the connection", false );
828 return 0;
829 } else if ( read < 0 ) {
830 switch ( errno ) {
831#if EAGAIN != EWOULDBLOCK
832 case EWOULDBLOCK:
833#endif
834 case EAGAIN: {
835 return -2;
836 }
837 default: {
838 d->setError( UnknownSocketError, strerr_cxx( errno ), false );
839 return -1;
840 }
841 }
842 }
843 return read;
844 }
845
846 void Socket::readChannelChanged ( uint channel )
847 {
848 if ( channel != 0 ) {
849 constexpr std::string_view msg("Changing the readChannel on a Socket is not supported");
850 ERR << msg << std::endl;
851 throw std::logic_error( msg.data() );
852 }
853 }
854
855 int64_t Socket::bytesPending() const
856 {
857 Z_D();
858 return std::visit([&]( const auto &s ) -> int64_t {
859 using T = std::decay_t<decltype (s)>;
860 if constexpr ( std::is_same_v<T, SocketPrivate::ConnectedState> || std::is_same_v<T, SocketPrivate::ClosingState> ) {
861 return s._writeBuffer.size();
862 }
863 return 0;
864 }, d->_state );
865 }
866
868 {
869 return d_func()->state();
870 }
871
873 {
874 return d_func()->_incomingConnection;
875 }
876
878 {
879 return d_func()->_connected;
880 }
881
883 {
884 return d_func()->_disconnected;
885 }
886
888 {
889 return d_func()->_sigError;
890 }
891
892}
static bool waitForFdEvent(const int fd, int events, int &revents, int &timeout)
Signal< void()> _sigAllBytesWritten
Definition iodevice_p.h:47
Signal< void(int64_t)> _sigBytesWritten
Definition iodevice_p.h:46
std::vector< IOBuffer > _readChannels
Definition iodevice_p.h:39
Signal< void() > _readyRead
Definition iodevice_p.h:44
Signal< void(uint) > _channelReadyRead
Definition iodevice_p.h:45
virtual int64_t bytesAvailable() const
Definition iodevice.cc:109
ByteArray read(int64_t maxSize)
Definition iodevice.cc:127
static Ptr create(int socket, int evTypes, bool enable=true)
SignalProxy< void(const SocketNotifier &sock, int evTypes)> sigActivated()
Socket::SocketState state() const
Definition socket.cc:413
static Socket::Ptr wrapSocket(int fd, int domain, int type, int protocol, Socket::SocketState state)
Definition socket.cc:418
std::string _errorDesc
Definition socket_p.h:68
std::variant< InitialState, ConnectingState, ConnectedState, ListeningState, ClosingState, ClosedState > _state
Definition socket_p.h:117
bool transition(Socket::SocketState newState)
Definition socket.cc:72
int64_t rawBytesAvailable() const
Definition socket.cc:202
bool readRawBytesToBuffer()
Definition socket.cc:210
bool handleConnectError(int error)
Definition socket.cc:300
Signal< void()> _disconnected
Definition socket_p.h:74
void onSocketActivated(int ev)
Definition socket.cc:343
std::shared_ptr< SockAddr > _targetAddr
Definition socket_p.h:60
Signal< void()> _connected
Definition socket_p.h:73
void setError(Socket::SocketError error, std::string &&err, bool emit=true)
Definition socket.cc:60
void onSocketActivatedSlot(const SocketNotifier &, int ev)
Definition socket_p.h:50
Signal< void()> _incomingConnection
Definition socket_p.h:72
Signal< void(Socket::SocketError)> _sigError
Definition socket_p.h:71
Socket::SocketError _error
Definition socket_p.h:67
SocketError lastError() const
Definition socket.cc:653
SignalProxy< void()> sigConnected()
Definition socket.cc:877
void abort()
Definition socket.cc:659
void close() override
Definition socket.cc:665
bool connect(std::shared_ptr< SockAddr > addr)
Definition socket.cc:619
static Ptr fromSocket(int fd, SocketState state)
Definition socket.cc:564
@ ConnectionDelayed
Definition socket.h:55
@ AddressNotAvailable
Definition socket.h:51
@ UnknownSocketError
Definition socket.h:42
@ OperationNotSupported
Definition socket.h:53
@ ConnectionRefused
Definition socket.h:56
@ UnsupportedSocketOptions
Definition socket.h:46
@ InsufficientRessources
Definition socket.h:45
@ InsufficientPermissions
Definition socket.h:43
@ InvalidSocketOptions
Definition socket.h:44
@ ConnectionTimeout
Definition socket.h:54
@ SocketAlreadyBound
Definition socket.h:48
@ NetworkUnreachable
Definition socket.h:58
@ FailedSocketOperation
Definition socket.h:47
@ ConnectionClosedByRemote
Definition socket.h:57
void readChannelChanged(uint channel) override
Definition socket.cc:846
@ ConnectingState
Definition socket.h:64
bool waitForReadyRead(uint channel, int timeout=-1) override
Definition socket.cc:792
int nativeSocket() const
Definition socket.cc:638
void disconnect()
Definition socket.cc:670
int releaseSocket()
Definition socket.cc:644
static Ptr create(int domain, int type, int protocol)
Definition socket.cc:458
SignalProxy< void()> sigDisconnected()
Definition socket.cc:882
SignalProxy< void()> sigIncomingConnection()
Definition socket.cc:872
bool waitForAllBytesWritten(int timeout=-1)
Definition socket.cc:759
bool listen(int backlog=50)
Definition socket.cc:509
SignalProxy< void(Socket::SocketError)> sigError()
Definition socket.cc:887
Socket(int domain, int type, int protocol)
Definition socket.cc:439
bool setBlocking(const bool set=true)
Definition socket.cc:597
int64_t writeData(const char *data, int64_t count) override
Definition socket.cc:687
int64_t bytesPending() const override
Definition socket.cc:855
~Socket() override
Definition socket.cc:453
bool waitForConnected(int timeout=-1)
Definition socket.cc:741
std::shared_ptr< Socket > Ptr
Definition socket.h:71
bool bind(const std::shared_ptr< SockAddr > &addr)
Definition socket.cc:463
int64_t readData(uint channel, char *buffer, int64_t bufsize) override
Definition socket.cc:811
int64_t rawBytesAvailable(uint channel=0) const override
Definition socket.cc:443
SocketState state() const
Definition socket.cc:867
static std::shared_ptr< Timer > create()
Creates a new Timer object, the timer is not started at this point.
Definition timer.cc:52
SignalProxy< void(Timer &t)> sigExpired()
This signal is always emitted when the timer expires.
Definition timer.cc:120
Definition Arch.h:364
typename decay< T >::type decay_t
Definition TypeTraits.h:42
auto eintrSafeCall(Fun &&function, Args &&... args)
int64_t bytesAvailableOnFD(int fd)
std::string strerr_cxx(const int err=-1)
ClosingState(IOBuffer &&writeBuffer)
Definition socket.cc:17
SocketNotifier::Ptr _socketNotifier
Definition socket_p.h:110
SocketNotifier::Ptr _socketNotifier
Definition socket_p.h:95
SocketNotifier::Ptr _socketNotifier
Definition socket_p.h:103
#define DBG
Definition Logger.h:99
#define ERR
Definition Logger.h:102
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:92
#define Z_D()
Definition zyppglobal.h:105
#define Z_Z()
Definition zyppglobal.h:106