void LLSocket::setOptions() { LLMemType m1(LLMemType::MTYPE_IO_TCP); // set up the socket options ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); }
void LLSocket::setNonBlocking() { // set up the socket options ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 1)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); }
//static S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) { apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (offset < 0) { flags |= APR_APPEND; offset = 0; } apr_file_t* file_handle; LLScopedVolatileAPRFilePool pool; apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) { ll_apr_warn_status(s); LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; return 0; } if (offset > 0) { offset = LLAPRFile::seek(file_handle, APR_SET, offset); } apr_size_t bytes_written; if (offset < 0) { bytes_written = 0; } else { bytes_written = nbytes ; apr_status_t s = apr_file_write(file_handle, buf, &bytes_written); if (s != APR_SUCCESS) { LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; ll_apr_warn_status(s); bytes_written = 0; } else { llassert_always(bytes_written <= 0x7fffffff); } } apr_file_close(file_handle); return (S32)bytes_written; }
bool LLPluginProcessParent::accept() { bool result = false; apr_status_t status = APR_EGENERAL; mSocket = LLSocket::create(status, mListenSocket); if(status == APR_SUCCESS) { // llinfos << "SUCCESS" << llendl; // Success. Create a message pipe on the new socket new LLPluginMessagePipe(this, mSocket); result = true; } else { mSocket.reset(); // EAGAIN means "No incoming connections". This is not an error. if (!APR_STATUS_IS_EAGAIN(status)) { // Some other error. ll_apr_warn_status(status); errorState(); } } return result; }
//static S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) { if(!file_handle) { return -1 ; } apr_status_t s; apr_off_t apr_offset; if (offset >= 0) { apr_offset = (apr_off_t)offset; s = apr_file_seek(file_handle, where, &apr_offset); } else { apr_offset = 0; s = apr_file_seek(file_handle, APR_END, &apr_offset); } if (s != APR_SUCCESS) { ll_apr_warn_status(s); return -1; } else { llassert_always(apr_offset <= 0x7fffffff); return (S32)apr_offset; } }
// static void LLMail::init(const std::string& hostname, apr_pool_t* pool) { gMailSocket = NULL; if(hostname.empty() || !pool) { gMailPool = NULL; gSockAddr = NULL; } else { gMailPool = pool; // collect all the information into a socaddr sturcture. the // documentation is a bit unclear, but I either have to // specify APR_UNSPEC or not specify any flags. I am not sure // which option is better. apr_status_t status = apr_sockaddr_info_get( &gSockAddr, hostname.c_str(), APR_UNSPEC, 25, APR_IPV4_ADDR_OK, gMailPool); ll_apr_warn_status(status); } }
void disconnect_smtp() { if(gMailSocket) { apr_status_t status = apr_socket_close(gMailSocket); ll_apr_warn_status(status); gMailSocket = NULL; } }
void LLThreadLocalPointerBase::initStorage( ) { apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); if (result != APR_SUCCESS) { ll_apr_warn_status(result); LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL; } }
/** * @brief Send one TCP packet and receive one in return. * * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking * operation would impact the operation of the viewer. * * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. * @param dataout Data to send. * @param outlen Length of dataout. * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. * @param maxinlen Maximum possible length of received data. Short reads are allowed. * @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received. */ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen) { apr_socket_t* apr_socket = handle->getSocket(); apr_status_t rv = APR_SUCCESS; apr_size_t expected_len = outlen; handle->setBlocking(1000); rv = apr_socket_send(apr_socket, dataout, &outlen); if (APR_SUCCESS != rv) { LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL; ll_apr_warn_status(rv); } else if (expected_len != outlen) { LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len << " Sent: " << outlen << LL_ENDL; rv = -1; } if (APR_SUCCESS == rv) { expected_len = maxinlen; rv = apr_socket_recv(apr_socket, datain, &maxinlen); if (rv != APR_SUCCESS) { LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL; ll_apr_warn_status(rv); } else if (expected_len < maxinlen) { LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len << " Received: " << maxinlen << LL_ENDL; rv = -1; } } handle->setNonBlocking(); return rv; }
void LLScopedLock::unlock() { if(mLocked) { if(!ll_apr_warn_status(apr_thread_mutex_unlock(mMutex))) { mLocked = false; } } }
//static S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) { apr_file_t* file_handle; LLScopedVolatileAPRFilePool pool; apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) { ll_apr_warn_status(s); LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; return 0; } S32 off; if (offset < 0) off = LLAPRFile::seek(file_handle, APR_END, 0); else off = LLAPRFile::seek(file_handle, APR_SET, offset); apr_size_t bytes_read; if (off < 0) { bytes_read = 0; } else { bytes_read = nbytes ; apr_status_t s = apr_file_read(file_handle, buf, &bytes_read); if (s != APR_SUCCESS) { LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL; ll_apr_warn_status(s); bytes_read = 0; } else { llassert_always(bytes_read <= 0x7fffffff); } } apr_file_close(file_handle); return (S32)bytes_read; }
bool connect_smtp() { // Prepare an soket to talk smtp apr_status_t status; status = apr_socket_create( &gMailSocket, gSockAddr->sa.sin.sin_family, SOCK_STREAM, APR_PROTO_TCP, gMailPool); if(ll_apr_warn_status(status)) return false; status = apr_socket_connect(gMailSocket, gSockAddr); if(ll_apr_warn_status(status)) { status = apr_socket_close(gMailSocket); ll_apr_warn_status(status); return false; } return true; }
void LLThreadLocalPointerBase::set( void* value ) { llassert(sInitialized && mThreadKey); apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); if (result != APR_SUCCESS) { ll_apr_warn_status(result); LL_ERRS() << "Failed to set thread local data" << LL_ENDL; } }
bool ll_apr_warn_status(apr_status_t status, apr_dso_handle_t *handle) { bool result = ll_apr_warn_status(status); // Despite observed truncation of actual Mac dylib load errors, increasing // this buffer to more than MAX_STRING doesn't help: it appears that APR // stores the output in a fixed 255-character internal buffer. (*sigh*) char buf[MAX_STRING]; /* Flawfinder: ignore */ apr_dso_error(handle, buf, sizeof(buf)); LL_WARNS("APR") << "APR: " << buf << LL_ENDL; return result; }
void* LLThreadLocalPointerBase::get() const { // llassert(sInitialized); void* ptr; apr_status_t result = apr_threadkey_private_get(&ptr, mThreadKey); if (result != APR_SUCCESS) { ll_apr_warn_status(result); LL_ERRS() << "Failed to get thread local data" << LL_ENDL; } return ptr; }
bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool) { apr_status_t s; if (pool == NULL) pool = gAPRPoolp; s = apr_file_remove(dirname.c_str(), pool); if (s != APR_SUCCESS) { LL_DEBUGS("APR") << "ll_apr_dir_remove failed on file: " << dirname << LL_ENDL; ll_apr_warn_status(s); return false; } return true; }
bool LLSocket::blockingConnect(const LLHost& host) { if(!mSocket) return false; apr_sockaddr_t* sa = NULL; std::string ip_address; ip_address = host.getIPString(); if(ll_apr_warn_status(apr_sockaddr_info_get( &sa, ip_address.c_str(), APR_UNSPEC, host.getPort(), 0, mPool()))) { return false; } setBlocking(1000); ll_debug_socket("Blocking connect", mSocket); if(ll_apr_warn_status(apr_socket_connect(mSocket, sa))) return false; setNonBlocking(); return true; }
void LLPumpIO::rebuildPollset() { LLMemType m1(LLMemType::MTYPE_IO_PUMP); // lldebugs << "LLPumpIO::rebuildPollset()" << llendl; if(mPollset) { //lldebugs << "destroying pollset" << llendl; apr_pollset_destroy(mPollset); mPollset = NULL; } U32 size = 0; running_chains_t::iterator run_it = mRunningChains.begin(); running_chains_t::iterator run_end = mRunningChains.end(); for(; run_it != run_end; ++run_it) { size += (*run_it).mDescriptors.size(); } //lldebugs << "found " << size << " descriptors." << llendl; if(size) { // Recycle the memory pool const S32 POLLSET_POOL_RECYCLE_COUNT = 100; if(mCurrentPool && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) { apr_pool_destroy(mCurrentPool); mCurrentPool = NULL; mCurrentPoolReallocCount = 0; } if(!mCurrentPool) { apr_status_t status = apr_pool_create(&mCurrentPool, mPool); (void)ll_apr_warn_status(status); } // add all of the file descriptors run_it = mRunningChains.begin(); LLChainInfo::conditionals_t::iterator fd_it; LLChainInfo::conditionals_t::iterator fd_end; apr_pollset_create(&mPollset, size, mCurrentPool, 0); for(; run_it != run_end; ++run_it) { fd_it = (*run_it).mDescriptors.begin(); fd_end = (*run_it).mDescriptors.end(); for(; fd_it != fd_end; ++fd_it) { apr_pollset_add(mPollset, &((*fd_it).second)); } } } }
bool LLPluginSharedMemory::detach(void) { if(mImpl->mAprSharedMemory) { apr_status_t status = apr_shm_detach(mImpl->mAprSharedMemory); if(ll_apr_warn_status(status)) { // TODO: Is this a fatal error? I think not... } mImpl->mAprSharedMemory = NULL; } return true; }
bool LLPluginSharedMemory::attach(const std::string &name, size_t size) { mName = name; mSize = size; apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); if(ll_apr_warn_status(status)) { return false; } return map(); }
//static S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) { apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (offset < 0) { flags |= APR_APPEND; offset = 0; } //***************************************** apr_file_t* file_handle = open(filename, pool, flags); //***************************************** if (!file_handle) { return 0; } if (offset > 0) { offset = LLAPRFile::seek(file_handle, APR_SET, offset); } apr_size_t bytes_written; if (offset < 0) { bytes_written = 0; } else { bytes_written = nbytes ; apr_status_t s = apr_file_write(file_handle, buf, &bytes_written); if (s != APR_SUCCESS) { LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; ll_apr_warn_status(s); bytes_written = 0; } else { llassert_always(bytes_written <= 0x7fffffff); } } //***************************************** LLAPRFile::close(file_handle, pool); //***************************************** return (S32)bytes_written; }
//static bool LLAPRFile::removeDir(const std::string& dirname) { apr_status_t s; LLScopedVolatileAPRFilePool pool; s = apr_file_remove(dirname.c_str(), pool); if (s != APR_SUCCESS) { ll_apr_warn_status(s); LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL; return false; } return true; }
//static bool LLAPRFile::makeDir(const std::string& dirname) { apr_status_t s; LLScopedVolatileAPRFilePool pool; s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); if (s != APR_SUCCESS) { ll_apr_warn_status(s); LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL; return false; } return true; }
//static bool LLAPRFile::rename(const std::string& filename, const std::string& newname) { apr_status_t s; LLScopedVolatileAPRFilePool pool; s = apr_file_rename(filename.c_str(), newname.c_str(), pool); if (s != APR_SUCCESS) { ll_apr_warn_status(s); LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL; return false; } return true; }
void LLThreadLocalPointerBase::destroyStorage() { if (sInitialized) { if (mThreadKey) { apr_status_t result = apr_threadkey_private_delete(mThreadKey); if (result != APR_SUCCESS) { ll_apr_warn_status(result); LL_ERRS() << "Failed to delete thread local data" << LL_ENDL; } } } }
//static bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool) { apr_status_t s; pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool()); pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { ll_apr_warn_status(s); LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL; return false; } return true; }
//static bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool) { apr_status_t s; pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool()); pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL; ll_apr_warn_status(s); return false; } return true; }
bool LLPluginSharedMemory::create(size_t size) { mName = APR_SHARED_MEMORY_PREFIX_STRING; mName += createName(); mSize = size; apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); if(ll_apr_warn_status(status)) { return false; } mNeedsDestroy = true; return map(); }
S32 LLAPRFile::write(const void *buf, S32 nbytes) { llassert_always(mFile) ; apr_size_t sz = nbytes; apr_status_t s = apr_file_write(mFile, buf, &sz); if (s != APR_SUCCESS) { ll_apr_warn_status(s); return 0; } else { llassert_always(sz <= 0x7fffffff); return (S32)sz; } }
bool LLPluginProcessParent::accept() { bool result = false; apr_status_t status = APR_EGENERAL; apr_socket_t *new_socket = NULL; status = apr_socket_accept( &new_socket, mListenSocket->getSocket(), gAPRPoolp); if(status == APR_SUCCESS) { // llinfos << "SUCCESS" << llendl; // Success. Create a message pipe on the new socket // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! apr_pool_t* new_pool = NULL; status = apr_pool_create(&new_pool, gAPRPoolp); mSocket = LLSocket::create(new_socket, new_pool); new LLPluginMessagePipe(this, mSocket); result = true; } else if(APR_STATUS_IS_EAGAIN(status)) { // llinfos << "EAGAIN" << llendl; // No incoming connections. This is not an error. status = APR_SUCCESS; } else { // llinfos << "Error:" << llendl; ll_apr_warn_status(status); // Some other error. errorState(); } return result; }