bool sepstream::GetToken(Flux::string &token) { Flux::string::iterator lsp = last_starting_position; while (n != tokens.end()) { if (*n == sep || n + 1 == tokens.end()) { last_starting_position = n + 1; token = Flux::string(lsp, n + 1 == tokens.end() ? n + 1 : n); while (token.length() && token.rfind(sep) == token.length() - 1) token.erase(token.end() - 1); ++n; return true; } ++n; } token.clear(); return false; }
void SocketIO::Process() { SET_SEGV_LOCATION(); timeval timeout; timeout.tv_sec = Config->SockWait; timeout.tv_usec = 0; //this timeout keeps the bot from being a CPU hog for no reason :) fd_set read = ReadFD, write = WriteFD, except = ExceptFD; FD_ZERO(&read); FD_SET(this->GetFD(), &read); int sres = select(this->GetFD() + 1, &read, &write, &except, &timeout); if(sres == -1 && errno != EINTR) { Log(LOG_DEBUG) << "Select() error: " << strerror(errno); return; } if(throwex) //throw a socket exception if we want to. mainly used for ping timeouts. throw SocketException(throwmsg); bool has_read = FD_ISSET(this->GetFD(), &read); bool has_write = FD_ISSET(this->GetFD(), &write); bool has_error = FD_ISSET(this->GetFD(), &except); if(has_error) { int optval = 0; socklen_t optlen = sizeof(optval); getsockopt(this->GetFD(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&optval), &optlen); errno = optval; FOREACH_MOD(I_OnSocketError, OnSocketError(optval ? strerror(errno) : "Unknown socket error")); throw SocketException("Socket error"); } if(has_read) { char tbuf[BUFSIZE + 1] = "\0"; size_t i = recv(this->GetFD(), tbuf, BUFSIZE, 0); if(i <= 0) throw SocketException(printfify("Socket Error: %s", strerror(errno))); sepstream sep(tbuf, '\n'); Flux::string buf; while(sep.GetToken(buf)) { this->LastBuf.clear(); this->LastBuf = buf; if(!this->Read(buf)) throw SocketException("Error reading socket"); } FD_CLR(this->GetFD(), &ReadFD); } if(has_write) { Flux::string buf; while(!this->WriteBuffer.empty()) { buf = this->WriteBuffer.front(); this->WriteBuffer.pop(); int i = ::send(this->GetFD(), buf.c_str(), buf.size(), MSG_NOSIGNAL); if(i <= -1 && !quitting) throw SocketException(printfify("Error writing \"%s\" to socket: %s", buf.c_str(), strerror(errno))); Log(LOG_RAWIO) << "Sent: " << buf << " | " << buf.size() << " bytes"; this->LastBuf.clear(); this->LastBuf = buf; buf.clear(); } FD_CLR(this->GetFD(), &WriteFD); } }
void SetQuery(unsigned n, const Flux::vector ¶ms) { query.clear(); if (n < params.size()) for(unsigned i=n; i < params.size(); ++i) query += params[i]+' '; }