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