| 931 | } |
| 932 | |
| 933 | U32 KNativeSocketObject::connect(KThread* thread, const KFileDescriptorPtr& fd, U32 address, U32 len) { |
| 934 | char buffer[1024] = {}; |
| 935 | U32 result = 0; |
| 936 | KMemory* memory = thread->memory; |
| 937 | |
| 938 | std::shared_ptr< KNativeSocketObject> t = std::dynamic_pointer_cast<KNativeSocketObject>(shared_from_this()); |
| 939 | #ifndef BOXEDWINE_MULTI_THREADED |
| 940 | if (this->connecting) { |
| 941 | if (this->isWriteReady()) { |
| 942 | this->error = 0; |
| 943 | this->connecting = 0; |
| 944 | this->connected = true; |
| 945 | removeWaitingSocket(this->nativeSocket); |
| 946 | return 0; |
| 947 | } |
| 948 | else { |
| 949 | int error = 0; |
| 950 | socklen_t errLen = 4; |
| 951 | if (::getsockopt(this->nativeSocket, SOL_SOCKET, SO_ERROR, (char*)&error, &errLen) < 0) { |
| 952 | return -K_EIO; |
| 953 | } |
| 954 | if (error) { |
| 955 | result = translateNativeSocketError(t, error); |
| 956 | if (result != (U32)(-K_EWOULDBLOCK)) { |
| 957 | return result; |
| 958 | } |
| 959 | } |
| 960 | } |
| 961 | addWaitingNativeSocket(t); |
| 962 | BOXEDWINE_CONDITION_LOCK(this->writingCond); |
| 963 | BOXEDWINE_CONDITION_WAIT(this->writingCond); |
| 964 | BOXEDWINE_CONDITION_UNLOCK(this->writingCond); |
| 965 | } |
| 966 | #endif |
| 967 | memory->memcpy(buffer, address, len); |
| 968 | |
| 969 | U16 family = memory->readw(address); |
| 970 | struct sockaddr* addr = nullptr; |
| 971 | sockaddr_in addr_in = {0}; |
| 972 | U32 addrLen = len; |
| 973 | if (family == K_AF_INET) { |
| 974 | readSockAddrIn(&addr_in, memory, address); |
| 975 | addr = (struct sockaddr*)&addr_in; |
| 976 | addrLen = sizeof(struct sockaddr_in); |
| 977 | if (memory->readb(address + 4) == 127 && memory->readb(address + 5) == 0 && memory->readb(address + 6) == 0 && memory->readb(address + 7) == 1) { |
| 978 | U16 port = memory->readb(address + 3) | (((U32)memory->readb(address + 2)) << 8); |
| 979 | if (port == 631) { |
| 980 | // wine seems to try and connect to a print server, if we are running on Linux it hangs while trying to read. That is probably a bug, for now just prevent the connection. |
| 981 | return -K_ECONNREFUSED; |
| 982 | } |
| 983 | } |
| 984 | } else { |
| 985 | addr = (struct sockaddr*)buffer; |
| 986 | } |
| 987 | |
| 988 | int r = ::connect(this->nativeSocket, addr, addrLen); |
| 989 | LOG_SOCK("native socket: %x connect %s result=%x", nativeSocket, socketAddressName(thread->memory, address, len).c_str(), r); |
| 990 | if (r == 0) { |
nothing calls this directly
no test coverage detected