| 170 | } |
| 171 | |
| 172 | U32 KNetLinkObject::read(KThread* thread, U32 buffer, U32 len) { |
| 173 | U32 count = 0; |
| 174 | KMemory* memory = thread->memory; |
| 175 | |
| 176 | if (!memory->canWrite(buffer, len)) { |
| 177 | return -K_EFAULT; |
| 178 | } |
| 179 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(this->lockCond); |
| 180 | while (this->recvBuffer.size() == 0) { |
| 181 | if (this->inClosed) { |
| 182 | return 0; |
| 183 | } |
| 184 | if (!this->blocking) { |
| 185 | return -K_EWOULDBLOCK; |
| 186 | } |
| 187 | BOXEDWINE_CONDITION_WAIT(this->lockCond); |
| 188 | #ifdef BOXEDWINE_MULTI_THREADED |
| 189 | if (thread->terminating) { |
| 190 | return -K_EINTR; |
| 191 | } |
| 192 | if (thread->startSignal) { |
| 193 | thread->startSignal = false; |
| 194 | return -K_CONTINUE; |
| 195 | } |
| 196 | #endif |
| 197 | } |
| 198 | count = std::min(len, (U32)this->recvBuffer.size()); |
| 199 | memory->performOnMemory(buffer, count, false, [this](U8* ram, U32 len) { |
| 200 | std::copy(this->recvBuffer.begin(), this->recvBuffer.begin() + len, ram); |
| 201 | this->recvBuffer.erase(this->recvBuffer.begin(), this->recvBuffer.begin() + len); |
| 202 | return true; |
| 203 | }); |
| 204 | |
| 205 | BOXEDWINE_CONDITION_SIGNAL_ALL(this->lockCond); |
| 206 | return count; |
| 207 | } |
| 208 | |
| 209 | U32 KNetLinkObject::stat(KProcess* process, U32 address, bool is64) { |
| 210 | KSystem::writeStat(process, B(""), address, is64, true, 0, K_S_IFSOCK | K__S_IWRITE | K__S_IREAD, 0, 0, 4096, 0, this->lastModifiedTime, 1); |