libzypp  17.35.12
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 = 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  }
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 ( 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 ) {
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  }
378  if ( (ev & SocketNotifier::Read) == SocketNotifier::Read ) {
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:
498  d->setError( Socket::InsufficientRessources, strerr_cxx() );
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:
531  d->setError( Socket::OperationNotSupported, strerr_cxx() );
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 
759  bool Socket::waitForAllBytesWritten( int timeout )
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 }
void close() override
Definition: socket.cc:665
std::shared_ptr< SockAddr > _targetAddr
Definition: socket_p.h:60
static Ptr create(int domain, int type, int protocol)
Definition: socket.cc:458
std::string _errorDesc
Definition: socket_p.h:68
bool listen(int backlog=50)
Definition: socket.cc:509
Signal< void(Socket::SocketError)> _sigError
Definition: socket_p.h:71
bool setBlocking(const bool set=true)
Definition: socket.cc:597
Socket::SocketState state() const
Definition: socket.cc:413
bool bind(const std::shared_ptr< SockAddr > &addr)
Definition: socket.cc:463
SignalProxy< void()> sigIncomingConnection()
Definition: socket.cc:872
Definition: Arch.h:363
SocketNotifier::Ptr _socketNotifier
Definition: socket_p.h:110
void abort()
Definition: socket.cc:659
static Ptr create(int socket, int evTypes, bool enable=true)
~Socket() override
Definition: socket.cc:453
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:105
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:759
void onSocketActivated(int ev)
Definition: socket.cc:343
bool readRawBytesToBuffer()
Definition: socket.cc:210
Ptr accept()
Definition: socket.cc:538
Signal< void()> _connected
Definition: socket_p.h:73
int nativeSocket() const
Definition: socket.cc:638
#define Z_Z()
Definition: zyppglobal.h:106
SignalProxy< void()> sigConnected()
Definition: socket.cc:877
SocketNotifier::Ptr _socketNotifier
Definition: socket_p.h:103
ClosingState(IOBuffer &&writeBuffer)
Definition: socket.cc:17
int64_t rawBytesAvailable() const
Definition: socket.cc:202
int64_t readData(uint channel, char *buffer, int64_t bufsize) override
Definition: socket.cc:811
void readChannelChanged(uint channel) override
Definition: socket.cc:846
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:670
static Socket::Ptr wrapSocket(int fd, int domain, int type, int protocol, Socket::SocketState state)
Definition: socket.cc:418
SocketState state() const
Definition: socket.cc:867
std::string strerr_cxx(const int err=-1)
static Ptr fromSocket(int fd, SocketState state)
Definition: socket.cc:564
int64_t writeData(const char *data, int64_t count) override
Definition: socket.cc:687
void setError(Socket::SocketError error, std::string &&err, bool emit=true)
Definition: socket.cc:60
int64_t bytesPending() const override
Definition: socket.cc:855
auto eintrSafeCall(Fun &&function, Args &&... args)
bool connect(std::shared_ptr< SockAddr > addr)
Definition: socket.cc:619
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:887
bool waitForConnected(int timeout=-1)
Definition: socket.cc:741
Socket::SocketError _error
Definition: socket_p.h:67
SignalProxy< void(const SocketNotifier &sock, int evTypes)> sigActivated()
typename decay< T >::type decay_t
Definition: TypeTraits.h:42
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:443
Signal< void()> _disconnected
Definition: socket_p.h:74
Signal< void(uint) > _channelReadyRead
Definition: iodevice_p.h:45
SocketError lastError() const
Definition: socket.cc:653
Signal< void() > _readyRead
Definition: iodevice_p.h:44
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:300
int64_t bytesAvailableOnFD(int fd)
Definition: linuxhelpers.cc:62
bool waitForReadyRead(uint channel, int timeout=-1) override
Definition: socket.cc:792
bool writePendingData()
Definition: socket.cc:253
int releaseSocket()
Definition: socket.cc:644
SignalProxy< void()> sigDisconnected()
Definition: socket.cc:882
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