/** Handler for fatal errors. Generate a fatal error * message to surelog, stdout, or stderr depending on * whether our controlling terminal is a tty or not. * * @param message Arbitrary text describing the * fatal condition * @note Exits with status 1 */ static void __attribute__((noreturn)) fatal(const char *message) { int haveTTY; #if defined(HAVE_APR) apr_os_file_t currentStderrFileno; if (!apr_stderr || (apr_os_file_get(¤tStderrFileno, apr_stderr) != APR_SUCCESS)) #else int currentStderrFileno; #endif currentStderrFileno = STDERR_FILENO; haveTTY = isatty(currentStderrFileno); if (!message) message = "UNDEFINED MESSAGE - OUT OF MEMORY?"; if (haveTTY) { fprintf(stderr, "\007Fatal Error in " PRODUCT_SHORTNAME ": %s\n", message); } else gpsee_log(NULL, GLOG_EMERG, "Fatal Error: %s", message); exit(1); }
static int file_fd_get(lua_State *L) { apr_status_t status; lua_apr_file *file; apr_os_file_t fd; file = file_check(L, 1, 1); status = apr_os_file_get(&fd, file->handle); if (status != APR_SUCCESS) return push_error_status(L, status); lua_pushinteger(L, fd); return 1; }
// // local functions // void ll_debug_poll_fd(const char* msg, const apr_pollfd_t* poll) { #if LL_DEBUG_POLL_FILE_DESCRIPTORS if(!poll) { lldebugs << "Poll -- " << (msg?msg:"") << ": no pollfd." << llendl; return; } if(poll->desc.s) { apr_os_sock_t os_sock; if(APR_SUCCESS == apr_os_sock_get(&os_sock, poll->desc.s)) { lldebugs << "Poll -- " << (msg?msg:"") << " on fd " << os_sock << " at " << poll->desc.s << llendl; } else { lldebugs << "Poll -- " << (msg?msg:"") << " no fd " << " at " << poll->desc.s << llendl; } } else if(poll->desc.f) { apr_os_file_t os_file; if(APR_SUCCESS == apr_os_file_get(&os_file, poll->desc.f)) { lldebugs << "Poll -- " << (msg?msg:"") << " on fd " << os_file << " at " << poll->desc.f << llendl; } else { lldebugs << "Poll -- " << (msg?msg:"") << " no fd " << " at " << poll->desc.f << llendl; } } else { lldebugs << "Poll -- " << (msg?msg:"") << ": no descriptor." << llendl; } #endif }
AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod) { char c; apr_os_file_t fd; int rc; /* we need to surface EINTR so we'll have to grab the * native file descriptor and do the OS read() ourselves */ apr_os_file_get(&fd, pod->pod_in); rc = read(fd, &c, 1); if (rc == 1) { switch(c) { case RESTART_CHAR: return AP_RESTART; case GRACEFUL_CHAR: return AP_GRACEFUL; } } return AP_NORESTART; }
zktool_set_logfile(const char *filename, apr_pool_t *p) { apr_status_t st; apr_file_t *f = NULL; apr_pool_t *pool; FILE *fp; apr_os_file_t fd; if(filename == NULL) { if(log_pool != NULL) apr_pool_destroy(log_pool); else zoo_set_log_stream(NULL); return APR_SUCCESS; } if(p == NULL) pool = zeke_root_subpool_create(); else assert(apr_pool_create(&pool,p) == APR_SUCCESS); st = apr_file_open(&f, filename, ZOO_LOG_FLAGS, APR_OS_DEFAULT, pool); if(st == APR_SUCCESS) { apr_file_inherit_unset(f); if((st = apr_os_file_get(&fd,f)) == APR_SUCCESS) { fp = fdopen(fd,"a"); if(fp == NULL) { st = apr_get_os_error(); } else { zoo_set_log_stream(fp); log_pool = pool; apr_pool_cleanup_register(pool,f,close_zookeeper_logfile,close_zookeeper_logfile); } } } if(st != APR_SUCCESS && f != NULL) apr_file_close(f); return st; }
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, apr_size_t reqsize, const char *file, apr_pool_t *pool) { static apr_size_t memblock = 0; HANDLE hMap, hFile; apr_status_t rv; apr_size_t size; apr_file_t *f; void *base; void *mapkey; DWORD err, sizelo, sizehi; reqsize += sizeof(memblock_t); if (!memblock) { SYSTEM_INFO si; GetSystemInfo(&si); memblock = si.dwAllocationGranularity; } /* Compute the granualar multiple of the pagesize */ size = memblock * (1 + (reqsize - 1) / memblock); sizelo = (DWORD)size; #ifdef _WIN64 sizehi = (DWORD)(size >> 32); #else sizehi = 0; #endif if (!file) { /* Do Anonymous, which must be passed as a duplicated handle */ #ifndef _WIN32_WCE hFile = INVALID_HANDLE_VALUE; #endif mapkey = NULL; } else { /* Do file backed, which is not an inherited handle * While we could open APR_EXCL, it doesn't seem that Unix * ever did. Ignore that error here, but fail later when * we discover we aren't the creator of the file map object. */ rv = apr_file_open(&f, file, APR_READ | APR_WRITE | APR_BINARY | APR_CREATE, APR_UREAD | APR_UWRITE, pool); if ((rv != APR_SUCCESS) || ((rv = apr_os_file_get(&hFile, f)) != APR_SUCCESS)) { return rv; } rv = apr_file_trunc(f, size); /* res_name_from_filename turns file into a pseudo-name * without slashes or backslashes, and prepends the \global * prefix on Win2K and later */ mapkey = res_name_from_filename(file, 1, pool); } #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { hMap = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, sizehi, sizelo, mapkey); } #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { hMap = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, sizehi, sizelo, mapkey); } #endif err = apr_get_os_error(); if (file) { apr_file_close(f); } if (hMap && APR_STATUS_IS_EEXIST(err)) { CloseHandle(hMap); return APR_EEXIST; } if (!hMap) { return err; } base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size); if (!base) { CloseHandle(hMap); return apr_get_os_error(); } *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t)); (*m)->pool = pool; (*m)->hMap = hMap; (*m)->memblk = base; (*m)->size = size; (*m)->usrmem = (char*)base + sizeof(memblock_t); (*m)->length = reqsize - sizeof(memblock_t);; (*m)->memblk->length = (*m)->length; (*m)->memblk->size = (*m)->size; (*m)->filename = file ? apr_pstrdup(pool, file) : NULL; apr_pool_cleanup_register((*m)->pool, *m, shm_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, const char *filename, apr_pool_t *pool) { if (filename == NULL) { /* It doesn't make sense to attach to a segment if you don't know * the filename. */ return APR_EINVAL; } else { #if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM apr_shm_t *new_m; apr_status_t status; int tmpfd; apr_file_t *file; /* file where metadata is stored */ apr_size_t nbytes; new_m = apr_palloc(pool, sizeof(apr_shm_t)); new_m->pool = pool; new_m->filename = apr_pstrdup(pool, filename); #if APR_USE_SHMEM_MMAP_SHM const char *shm_name = make_shm_open_safe_name(filename, pool); /* FIXME: SysV uses 0600... should we? */ tmpfd = shm_open(shm_name, O_RDWR, 0644); if (tmpfd == -1) { return errno; } status = apr_os_file_put(&file, &tmpfd, APR_READ | APR_WRITE, pool); if (status != APR_SUCCESS) { return status; } #elif APR_USE_SHMEM_MMAP_TMP status = apr_file_open(&file, filename, APR_READ | APR_WRITE, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { return status; } status = apr_os_file_get(&tmpfd, file); if (status != APR_SUCCESS) { return status; } #else return APR_ENOTIMPL; #endif nbytes = sizeof(new_m->realsize); status = apr_file_read(file, (void *)&(new_m->realsize), &nbytes); if (status != APR_SUCCESS) { return status; } status = apr_os_file_get(&tmpfd, file); if (status != APR_SUCCESS) { apr_file_close(file); /* ignore errors, we're failing */ apr_file_remove(new_m->filename, new_m->pool); return status; } new_m->reqsize = new_m->realsize - sizeof(apr_size_t); new_m->base = mmap(NULL, new_m->realsize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpfd, 0); /* FIXME: check for errors */ status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } /* metadata isn't part of the usable segment */ new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_attach, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #elif APR_USE_SHMEM_SHMGET apr_shm_t *new_m; apr_status_t status; apr_file_t *file; /* file where metadata is stored */ apr_size_t nbytes; new_m = apr_palloc(pool, sizeof(apr_shm_t)); status = apr_file_open(&file, filename, APR_FOPEN_READ, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { return status; } nbytes = sizeof(new_m->reqsize); status = apr_file_read(file, (void *)&(new_m->reqsize), &nbytes); if (status != APR_SUCCESS) { return status; } status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } new_m->filename = apr_pstrdup(pool, filename); new_m->pool = pool; new_m->shmkey = our_ftok(filename); if (new_m->shmkey == (key_t)-1) { return errno; } if ((new_m->shmid = shmget(new_m->shmkey, 0, SHM_R | SHM_W)) == -1) { return errno; } if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) { return errno; } new_m->usable = new_m->base; new_m->realsize = new_m->reqsize; apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_attach, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #else return APR_ENOTIMPL; #endif } }
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, apr_size_t reqsize, const char *filename, apr_pool_t *pool) { apr_shm_t *new_m; apr_status_t status; #if APR_USE_SHMEM_SHMGET || APR_USE_SHMEM_SHMGET_ANON struct shmid_ds shmbuf; apr_uid_t uid; apr_gid_t gid; #endif #if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM || \ APR_USE_SHMEM_MMAP_ZERO int tmpfd; #endif #if APR_USE_SHMEM_SHMGET apr_size_t nbytes; #endif #if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_SHMGET || \ APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM apr_file_t *file; /* file where metadata is stored */ #endif /* Check if they want anonymous or name-based shared memory */ if (filename == NULL) { #if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON new_m = apr_palloc(pool, sizeof(apr_shm_t)); new_m->pool = pool; new_m->reqsize = reqsize; new_m->realsize = reqsize + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); /* room for metadata */ new_m->filename = NULL; #if APR_USE_SHMEM_MMAP_ZERO status = apr_file_open(&file, "/dev/zero", APR_READ | APR_WRITE, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { return status; } status = apr_os_file_get(&tmpfd, file); if (status != APR_SUCCESS) { return status; } new_m->base = mmap(NULL, new_m->realsize, PROT_READ|PROT_WRITE, MAP_SHARED, tmpfd, 0); if (new_m->base == (void *)MAP_FAILED) { return errno; } status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } /* store the real size in the metadata */ *(apr_size_t*)(new_m->base) = new_m->realsize; /* metadata isn't usable */ new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #elif APR_USE_SHMEM_MMAP_ANON new_m->base = mmap(NULL, new_m->realsize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); if (new_m->base == (void *)MAP_FAILED) { return errno; } /* store the real size in the metadata */ *(apr_size_t*)(new_m->base) = new_m->realsize; /* metadata isn't usable */ new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #endif /* APR_USE_SHMEM_MMAP_ZERO */ #elif APR_USE_SHMEM_SHMGET_ANON new_m = apr_palloc(pool, sizeof(apr_shm_t)); new_m->pool = pool; new_m->reqsize = reqsize; new_m->realsize = reqsize; new_m->filename = NULL; new_m->shmkey = IPC_PRIVATE; if ((new_m->shmid = shmget(new_m->shmkey, new_m->realsize, SHM_R | SHM_W | IPC_CREAT)) < 0) { return errno; } if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) { return errno; } new_m->usable = new_m->base; if (shmctl(new_m->shmid, IPC_STAT, &shmbuf) == -1) { return errno; } apr_uid_current(&uid, &gid, pool); shmbuf.shm_perm.uid = uid; shmbuf.shm_perm.gid = gid; if (shmctl(new_m->shmid, IPC_SET, &shmbuf) == -1) { return errno; } /* Remove the segment once use count hits zero. * We will not attach to this segment again, since it is * anonymous memory, so it is ok to mark it for deletion. */ if (shmctl(new_m->shmid, IPC_RMID, NULL) == -1) { return errno; } apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #else /* It is an error if they want anonymous memory but we don't have it. */ return APR_ENOTIMPL; /* requested anonymous but we don't have it */ #endif } /* Name-based shared memory */ else { new_m = apr_palloc(pool, sizeof(apr_shm_t)); new_m->pool = pool; new_m->reqsize = reqsize; new_m->filename = apr_pstrdup(pool, filename); #if APR_USE_SHMEM_MMAP_SHM const char *shm_name = make_shm_open_safe_name(filename, pool); #endif #if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM new_m->realsize = reqsize + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); /* room for metadata */ /* FIXME: Ignore error for now. * * status = apr_file_remove(file, pool);*/ status = APR_SUCCESS; #if APR_USE_SHMEM_MMAP_TMP /* FIXME: Is APR_OS_DEFAULT sufficient? */ status = apr_file_open(&file, filename, APR_READ | APR_WRITE | APR_CREATE | APR_EXCL, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { return status; } status = apr_os_file_get(&tmpfd, file); if (status != APR_SUCCESS) { apr_file_close(file); /* ignore errors, we're failing */ apr_file_remove(new_m->filename, new_m->pool); return status; } status = apr_file_trunc(file, new_m->realsize); if (status != APR_SUCCESS && status != APR_ESPIPE) { apr_file_close(file); /* ignore errors, we're failing */ apr_file_remove(new_m->filename, new_m->pool); return status; } new_m->base = mmap(NULL, new_m->realsize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpfd, 0); /* FIXME: check for errors */ status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } #endif /* APR_USE_SHMEM_MMAP_TMP */ #if APR_USE_SHMEM_MMAP_SHM /* FIXME: SysV uses 0600... should we? */ tmpfd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, 0644); if (tmpfd == -1) { return errno; } status = apr_os_file_put(&file, &tmpfd, APR_READ | APR_WRITE | APR_CREATE | APR_EXCL, pool); if (status != APR_SUCCESS) { return status; } status = apr_file_trunc(file, new_m->realsize); if (status != APR_SUCCESS && status != APR_ESPIPE) { shm_unlink(shm_name); /* we're failing, remove the object */ return status; } new_m->base = mmap(NULL, new_m->realsize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpfd, 0); /* FIXME: check for errors */ status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } #endif /* APR_USE_SHMEM_MMAP_SHM */ /* store the real size in the metadata */ *(apr_size_t*)(new_m->base) = new_m->realsize; /* metadata isn't usable */ new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #elif APR_USE_SHMEM_SHMGET new_m->realsize = reqsize; /* FIXME: APR_OS_DEFAULT is too permissive, switch to 600 I think. */ status = apr_file_open(&file, filename, APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { return status; } /* ftok() (on solaris at least) requires that the file actually * exist before calling ftok(). */ new_m->shmkey = our_ftok(filename); if (new_m->shmkey == (key_t)-1) { apr_file_close(file); return errno; } if ((new_m->shmid = shmget(new_m->shmkey, new_m->realsize, SHM_R | SHM_W | IPC_CREAT | IPC_EXCL)) < 0) { apr_file_close(file); return errno; } if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) { apr_file_close(file); return errno; } new_m->usable = new_m->base; if (shmctl(new_m->shmid, IPC_STAT, &shmbuf) == -1) { apr_file_close(file); return errno; } apr_uid_current(&uid, &gid, pool); shmbuf.shm_perm.uid = uid; shmbuf.shm_perm.gid = gid; if (shmctl(new_m->shmid, IPC_SET, &shmbuf) == -1) { apr_file_close(file); return errno; } nbytes = sizeof(reqsize); status = apr_file_write(file, (const void *)&reqsize, &nbytes); if (status != APR_SUCCESS) { apr_file_close(file); return status; } status = apr_file_close(file); if (status != APR_SUCCESS) { return status; } apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #else return APR_ENOTIMPL; #endif } }
static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b) { apr_status_t rv; cache_object_t *obj = h->cache_obj; cache_object_t *tobj = NULL; mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj; apr_read_type_e eblock = APR_BLOCK_READ; apr_bucket *e; char *cur; int eos = 0; if (mobj->type == CACHE_TYPE_FILE) { apr_file_t *file = NULL; int fd = 0; int other = 0; /* We can cache an open file descriptor if: * - the brigade contains one and only one file_bucket && * - the brigade is complete && * - the file_bucket is the last data bucket in the brigade */ for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { if (APR_BUCKET_IS_EOS(e)) { eos = 1; } else if (APR_BUCKET_IS_FILE(e)) { apr_bucket_file *a = e->data; fd++; file = a->fd; } else { other++; } } if (fd == 1 && !other && eos) { apr_file_t *tmpfile; const char *name; /* Open a new XTHREAD handle to the file */ apr_file_name_get(&name, file); mobj->flags = ((APR_SENDFILE_ENABLED & apr_file_flags_get(file)) | APR_READ | APR_BINARY | APR_XTHREAD | APR_FILE_NOCLEANUP); rv = apr_file_open(&tmpfile, name, mobj->flags, APR_OS_DEFAULT, r->pool); if (rv != APR_SUCCESS) { return rv; } apr_file_inherit_unset(tmpfile); apr_os_file_get(&(mobj->fd), tmpfile); /* Open for business */ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "mem_cache: Cached file: %s with key: %s", name, obj->key); obj->complete = 1; return APR_SUCCESS; } /* Content not suitable for fd caching. Cache in-memory instead. */ mobj->type = CACHE_TYPE_HEAP; } /* * FD cacheing is not enabled or the content was not * suitable for fd caching. */ if (mobj->m == NULL) { mobj->m = malloc(mobj->m_len); if (mobj->m == NULL) { return APR_ENOMEM; } obj->count = 0; } cur = (char*) mobj->m + obj->count; /* Iterate accross the brigade and populate the cache storage */ for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { const char *s; apr_size_t len; if (APR_BUCKET_IS_EOS(e)) { const char *cl_header = apr_table_get(r->headers_out, "Content-Length"); if (cl_header) { apr_int64_t cl = apr_atoi64(cl_header); if ((errno == 0) && (obj->count != cl)) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mem_cache: URL %s didn't receive complete response, not caching", h->cache_obj->key); return APR_EGENERAL; } } if (mobj->m_len > obj->count) { /* Caching a streamed response. Reallocate a buffer of the * correct size and copy the streamed response into that * buffer */ mobj->m = realloc(mobj->m, obj->count); if (!mobj->m) { return APR_ENOMEM; } /* Now comes the crufty part... there is no way to tell the * cache that the size of the object has changed. We need * to remove the object, update the size and re-add the * object, all under protection of the lock. */ if (sconf->lock) { apr_thread_mutex_lock(sconf->lock); } /* Has the object been ejected from the cache? */ tobj = (cache_object_t *) cache_find(sconf->cache_cache, obj->key); if (tobj == obj) { /* Object is still in the cache, remove it, update the len field then * replace it under protection of sconf->lock. */ cache_remove(sconf->cache_cache, obj); /* For illustration, cache no longer has reference to the object * so decrement the refcount * apr_atomic_dec32(&obj->refcount); */ mobj->m_len = obj->count; cache_insert(sconf->cache_cache, obj); /* For illustration, cache now has reference to the object, so * increment the refcount * apr_atomic_inc32(&obj->refcount); */ } else if (tobj) { /* Different object with the same key found in the cache. Doing nothing * here will cause the object refcount to drop to 0 in decrement_refcount * and the object will be cleaned up. */ } else { /* Object has been ejected from the cache, add it back to the cache */ mobj->m_len = obj->count; cache_insert(sconf->cache_cache, obj); apr_atomic_inc32(&obj->refcount); } if (sconf->lock) { apr_thread_mutex_unlock(sconf->lock); } } /* Open for business */ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "mem_cache: Cached url: %s", obj->key); obj->complete = 1; break; } rv = apr_bucket_read(e, &s, &len, eblock); if (rv != APR_SUCCESS) { return rv; } if (len) { /* Check for buffer (max_streaming_buffer_size) overflow */ if ((obj->count + len) > mobj->m_len) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "mem_cache: URL %s exceeds the MCacheMaxStreamingBuffer (%" APR_SIZE_T_FMT ") limit and will not be cached.", obj->key, mobj->m_len); return APR_ENOMEM; } else { memcpy(cur, s, len); cur+=len; obj->count+=len; } } /* This should not fail, but if it does, we are in BIG trouble * cause we just stomped all over the heap. */ AP_DEBUG_ASSERT(obj->count <= mobj->m_len); } return APR_SUCCESS; }