KSocketAddress KSocketDevice::peerAddress() const { if (m_sockfd == -1) return KSocketAddress(); // not open, empty value if (d->peer.family() != AF_UNSPEC) return d->peer; socklen_t len; KSocketAddress peerAddress; peerAddress.setLength(len = 32); // arbitrary value if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) // error! return d->peer = KSocketAddress(); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN len = peerAddress.address()->sa_len; #endif if (len <= peerAddress.length()) { // it has fit already peerAddress.setLength(len); return d->peer = peerAddress; } // no, the socket address is actually larger than we had anticipated // call again peerAddress.setLength(len); if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) // error! return d->peer = KSocketAddress(); return d->peer = peerAddress; }
bool KSocketDevice::disconnect() { resetError(); if (m_sockfd == -1) return false; // can't create KSocketAddress address; address.setFamily(AF_UNSPEC); if (kde_connect(m_sockfd, address.address(), address.length()) == -1) { if (errno == EALREADY || errno == EINPROGRESS) { setError(IO_ConnectError, InProgress); return false; } else if (errno == ECONNREFUSED) setError(IO_ConnectError, ConnectionRefused); else if (errno == ENETDOWN || errno == ENETUNREACH || errno == ENETRESET || errno == ECONNABORTED || errno == ECONNRESET || errno == EHOSTDOWN || errno == EHOSTUNREACH) setError(IO_ConnectError, NetFailure); else setError(IO_ConnectError, NotSupported); return false; } setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); setState(IO_Open); return true; // all is well }
Q_LONG KSocketDevice::writeBlock(const char *data, Q_ULONG len, const KSocketAddress& to) { resetError(); if (m_sockfd == -1) return -1; // can't write to unopen socket if (data == 0L || len == 0) return 0; // nothing to be written ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length()); if (retval == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) setError(IO_WriteError, WouldBlock); else setError(IO_WriteError, UnknownError); return -1; // nothing written } else if (retval == 0) setError(IO_WriteError, RemotelyDisconnected); return retval; }