/*! \internal Creates and returns a new socket descriptor of type \a socketType and \a socketProtocol. Returns -1 on failure. */ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) { int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET; int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; int socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK); if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { protocol = AF_INET; socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK); socketProtocol = QAbstractSocket::IPv4Protocol; } if (socket < 0) { int ecopy = errno; switch (ecopy) { case EPROTONOSUPPORT: case EAFNOSUPPORT: case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString); break; case ENFILE: case EMFILE: case ENOBUFS: case ENOMEM: setError(QAbstractSocket::SocketResourceError, ResourceErrorString); break; case EACCES: setError(QAbstractSocket::SocketAccessError, AccessErrorString); break; default: break; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == false (%s)", socketType, socketProtocol, strerror(ecopy)); #endif return false; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == true", socketType, socketProtocol); #endif socketDescriptor = socket; if (socket != -1) { this->socketProtocol = socketProtocol; this->socketType = socketType; } return true; }
/*! \internal Creates and returns a new socket descriptor of type \a socketType and \a socketProtocol. Returns -1 on failure. */ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol socketProtocol) { int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET; int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; int socket = qt_safe_socket(protocol, type, 0); if (socket <= 0) { switch (errno) { case EPROTONOSUPPORT: case EAFNOSUPPORT: case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString); break; case ENFILE: case EMFILE: case ENOBUFS: case ENOMEM: setError(QAbstractSocket::SocketResourceError, ResourceErrorString); break; case EACCES: setError(QAbstractSocket::SocketAccessError, AccessErrorString); break; default: break; } return false; } socketDescriptor = socket; return true; }
// test only for posix void tst_QSocketNotifier::posixSockets() { QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_addr.s_addr = htonl(0x7f000001); addr.sin_family = AF_INET; addr.sin_port = htons(server.serverPort()); qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); QVERIFY(server.waitForNewConnection(5000)); QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); { QSocketNotifier rn(posixSocket, QSocketNotifier::Read); connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy readSpy(&rn, SIGNAL(activated(int))); QVERIFY(readSpy.isValid()); // No write notifier, some systems trigger write notification on socket creation, but not all QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy errorSpy(&en, SIGNAL(activated(int))); QVERIFY(errorSpy.isValid()); passive->write("hello",6); passive->waitForBytesWritten(5000); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); char buffer[100]; int r = qt_safe_read(posixSocket, buffer, 100); QCOMPARE(r, 6); QCOMPARE(buffer, "hello"); QSocketNotifier wn(posixSocket, QSocketNotifier::Write); connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); QVERIFY(writeSpy.isValid()); qt_safe_write(posixSocket, "goodbye", 8); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(writeSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); // Write notifier may have fired before the read notifier inside // QTcpSocket, give QTcpSocket a chance to see the incoming data passive->waitForReadyRead(100); QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); } qt_safe_close(posixSocket); }
void tst_QSocketNotifier::posixSockets() { #ifndef Q_OS_UNIX QSKIP("test only for posix", SkipAll); #else QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_addr.s_addr = htonl(0x7f000001); addr.sin_family = AF_INET; addr.sin_port = htons(server.serverPort()); qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); QVERIFY(server.waitForNewConnection(5000)); QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); { QSocketNotifier rn(posixSocket, QSocketNotifier::Read); connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy readSpy(&rn, SIGNAL(activated(int))); QSocketNotifier wn(posixSocket, QSocketNotifier::Write); connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy errorSpy(&en, SIGNAL(activated(int))); passive->write("hello",6); passive->waitForBytesWritten(5000); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); writeSpy.clear(); //depending on OS, write notifier triggers on creation or not. QCOMPARE(errorSpy.count(), 0); char buffer[100]; qt_safe_read(posixSocket, buffer, 100); QCOMPARE(buffer, "hello"); qt_safe_write(posixSocket, "goodbye", 8); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(writeSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); } qt_safe_close(posixSocket); #endif }
static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; int socket; if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error ifaddrs *interfaceListing; if (getifaddrs(&interfaceListing) == -1) { // error ::close(socket); return interfaces; } interfaces = createInterfaces(interfaceListing); for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) { // Get the interface index int ifindex = if_nametoindex(ptr->ifa_name); QNetworkInterfacePrivate *iface = 0; QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) if ((*if_it)->index == ifindex) { // found this interface already iface = *if_it; break; } if (!iface) { // skip all non-IP interfaces continue; } QNetworkAddressEntry entry; entry.setIp(addressFromSockaddr(ptr->ifa_addr)); if (entry.ip().isNull()) // could not parse the address continue; entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask)); if (iface->flags & QNetworkInterface::CanBroadcast) entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr)); iface->addressEntries << entry; } freeifaddrs(interfaceListing); ::close(socket); return interfaces; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; int socket; if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error QSet<QByteArray> names = interfaceNames(socket); QSet<QByteArray>::ConstIterator it = names.constBegin(); for ( ; it != names.constEnd(); ++it) { ifreq req; memset(&req, 0, sizeof(ifreq)); memcpy(req.ifr_name, *it, qMin<int>(it->length() + 1, sizeof(req.ifr_name) - 1)); QNetworkInterfacePrivate *iface = findInterface(socket, interfaces, req); // Get the interface broadcast address QNetworkAddressEntry entry; if (iface->flags & QNetworkInterface::CanBroadcast) { if (qt_safe_ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; if (sa->sa_family == AF_INET) entry.setBroadcast(addressFromSockaddr(sa)); } } // Get the interface netmask if (qt_safe_ioctl(socket, SIOCGIFNETMASK, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setNetmask(addressFromSockaddr(sa)); } // Get the address of the interface if (qt_safe_ioctl(socket, SIOCGIFADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setIp(addressFromSockaddr(sa)); } iface->addressEntries << entry; } ::close(socket); return interfaces; }
/*! \internal Creates and returns a new socket descriptor of type \a socketType and \a socketProtocol. Returns -1 on failure. */ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol socketProtocol) { #ifndef QT_NO_IPV6 int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol) ? AF_INET6 : AF_INET; #else Q_UNUSED(socketProtocol); int protocol = AF_INET; #endif int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; #ifdef Q_OS_SYMBIAN int socket = ::socket(protocol, type, 0); #else int socket = qt_safe_socket(protocol, type, 0); #endif if (socket <= 0) { switch (errno) { case EPROTONOSUPPORT: case EAFNOSUPPORT: case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString); break; case ENFILE: case EMFILE: case ENOBUFS: case ENOMEM: setError(QAbstractSocket::SocketResourceError, ResourceErrorString); break; case EACCES: setError(QAbstractSocket::SocketAccessError, AccessErrorString); break; default: break; } return false; } // Ensure that the socket is closed on exec*(). ::fcntl(socket, F_SETFD, FD_CLOEXEC); socketDescriptor = socket; return true; }