static int file_make_mmap(apr_bucket *e, apr_size_t filelength, apr_off_t fileoffset, apr_pool_t *p) { apr_bucket_file *a = e->data; apr_mmap_t *mm; if (!a->can_mmap) { return 0; } if (filelength > APR_MMAP_LIMIT) { if (apr_mmap_create(&mm, a->fd, fileoffset, APR_MMAP_LIMIT, APR_MMAP_READ, p) != APR_SUCCESS) { return 0; } apr_bucket_split(e, APR_MMAP_LIMIT); filelength = APR_MMAP_LIMIT; } else if ((filelength < APR_MMAP_THRESHOLD) || (apr_mmap_create(&mm, a->fd, fileoffset, filelength, APR_MMAP_READ, p) != APR_SUCCESS)) { return 0; } apr_bucket_mmap_make(e, mm, 0, filelength); file_bucket_destroy(a); return 1; }
static void test_mmap_create(abts_case *tc, void *data) { apr_status_t rv; rv = apr_mmap_create(&themmap, thefile, 0, (apr_size_t) thisfinfo.size, APR_MMAP_READ, p); ABTS_PTR_NOTNULL(tc, themmap); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); }
int load( const char* filename ) { free( resource ); apr_file_t* newfile; apr_file_open( &newfile, filename, APR_READ, APR_OS_DEFAULT, mempool ); apr_finfo_t finfo; apr_file_info_get( &finfo, APR_FINFO_SIZE, newfile ); apr_mmap_t* mmap; apr_mmap_create( &mmap, newfile, 0, finfo.size, APR_MMAP_READ, mempool ); resource = (char*)malloc( finfo.size ); memcpy( resource, mmap->mm, finfo.size ); apr_mmap_delete( mmap ); }
static void cache_the_file(cmd_parms *cmd, const char *filename, int mmap) { a_server_config *sconf; a_file *new_file; a_file tmp; apr_file_t *fd = NULL; apr_status_t rc; const char *fspec; fspec = ap_server_root_relative(cmd->pool, filename); if (!fspec) { ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, APLOGNO(00794) "invalid file path " "%s, skipping", filename); return; } if ((rc = apr_stat(&tmp.finfo, fspec, APR_FINFO_MIN, cmd->temp_pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00795) "unable to stat(%s), skipping", fspec); return; } if (tmp.finfo.filetype != APR_REG) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00796) "%s isn't a regular file, skipping", fspec); return; } if (tmp.finfo.size > AP_MAX_SENDFILE) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00797) "%s is too large to cache, skipping", fspec); return; } rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD, APR_OS_DEFAULT, cmd->pool); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00798) "unable to open(%s, O_RDONLY), skipping", fspec); return; } apr_file_inherit_set(fd); /* WooHoo, we have a file to put in the cache */ new_file = apr_pcalloc(cmd->pool, sizeof(a_file)); new_file->finfo = tmp.finfo; #if APR_HAS_MMAP if (mmap) { /* MMAPFile directive. MMAP'ing the file * XXX: APR_HAS_LARGE_FILES issue; need to reject this request if * size is greater than MAX(apr_size_t) (perhaps greater than 1M?). */ if ((rc = apr_mmap_create(&new_file->mm, fd, 0, (apr_size_t)new_file->finfo.size, APR_MMAP_READ, cmd->pool)) != APR_SUCCESS) { apr_file_close(fd); ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00799) "unable to mmap %s, skipping", filename); return; } apr_file_close(fd); new_file->is_mmapped = TRUE; } #endif #if APR_HAS_SENDFILE if (!mmap) { /* CacheFile directive. Caching the file handle */ new_file->is_mmapped = FALSE; new_file->file = fd; } #endif new_file->filename = fspec; apr_rfc822_date(new_file->mtimestr, new_file->finfo.mtime); apr_snprintf(new_file->sizestr, sizeof new_file->sizestr, "%" APR_OFF_T_FMT, new_file->finfo.size); sconf = ap_get_module_config(cmd->server->module_config, &file_cache_module); apr_hash_set(sconf->fileht, new_file->filename, strlen(new_file->filename), new_file); }
svn_error_t * svn_atomic_namespace__create(svn_atomic_namespace__t **ns, const char *name, apr_pool_t *result_pool) { apr_status_t apr_err; svn_error_t *err; apr_file_t *file; apr_mmap_t *mmap; const char *shm_name, *lock_name; apr_finfo_t finfo; apr_pool_t *subpool = svn_pool_create(result_pool); /* allocate the namespace data structure */ svn_atomic_namespace__t *new_ns = apr_pcalloc(result_pool, sizeof(**ns)); /* construct the names of the system objects that we need */ shm_name = apr_pstrcat(subpool, name, SHM_NAME_SUFFIX, NULL); lock_name = apr_pstrcat(subpool, name, MUTEX_NAME_SUFFIX, NULL); /* initialize the lock objects */ SVN_ERR(svn_atomic__init_once(&mutex_initialized, init_thread_mutex, NULL, result_pool)); new_ns->mutex.pool = result_pool; SVN_ERR(svn_io_file_open(&new_ns->mutex.lock_file, lock_name, APR_READ | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, result_pool)); /* Make sure the last user of our lock file will actually remove it. * Please note that only the last file handle begin closed will actually * remove the underlying file (see docstring for apr_file_remove). */ apr_pool_cleanup_register(result_pool, &new_ns->mutex, delete_lock_file, apr_pool_cleanup_null); /* Prevent concurrent initialization. */ SVN_ERR(lock(&new_ns->mutex)); /* First, make sure that the underlying file exists. If it doesn't * exist, create one and initialize its content. */ err = svn_io_file_open(&file, shm_name, APR_READ | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, result_pool); if (!err) { err = svn_io_stat(&finfo, shm_name, APR_FINFO_SIZE, subpool); if (!err && finfo.size < sizeof(struct shared_data_t)) { /* Zero all counters, values and names. */ struct shared_data_t initial_data; memset(&initial_data, 0, sizeof(initial_data)); err = svn_io_file_write_full(file, &initial_data, sizeof(initial_data), NULL, subpool); } } /* Now, map it into memory. */ if (!err) { apr_err = apr_mmap_create(&mmap, file, 0, sizeof(*new_ns->data), APR_MMAP_READ | APR_MMAP_WRITE , result_pool); if (!apr_err) new_ns->data = mmap->mm; else err = svn_error_createf(apr_err, NULL, _("MMAP failed for file '%s'"), shm_name); } svn_pool_destroy(subpool); if (!err && new_ns->data) { /* Detect severe cases of corruption (i.e. when some outsider messed * with our data file) */ if (new_ns->data->count > MAX_ATOMIC_COUNT) return svn_error_create(SVN_ERR_CORRUPTED_ATOMIC_STORAGE, 0, _("Number of atomics in namespace is too large.")); /* Cache the number of existing, complete entries. There can't be * incomplete ones from other processes because we hold the mutex. * Our process will also not access this information since we are * either being called from within svn_atomic__init_once or by * svn_atomic_namespace__create for a new object. */ new_ns->min_used = new_ns->data->count; *ns = new_ns; } /* Unlock to allow other processes may access the shared memory as well. */ return unlock(&new_ns->mutex, err); }
static int jk2_shm_create(jk_env_t *env, jk_shm_t *shm) { int rc; apr_file_t *file; apr_finfo_t finfo; apr_mmap_t *aprMmap; apr_pool_t *globalShmPool; globalShmPool= (apr_pool_t *)env->getAprPool( env ); if( globalShmPool==NULL ) return JK_FALSE; /* Check if the scoreboard is in a note. That's the only way we can get HP-UX to work */ apr_pool_userdata_get( & shm->image, "mod_jk_shm",globalShmPool ); if( shm->image!=NULL ) { shm->head = (jk_shm_head_t *)shm->image; if( shm->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "shm.create(): GLOBAL_SHM %#lx\n", shm->image ); return JK_OK; } else { if( shm->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "shm.create(): NO GLOBAL_SHM %#lx\n", shm->image ); } /* First make sure the file exists and is big enough */ rc=apr_file_open( &file, shm->fname, APR_READ | APR_WRITE | APR_CREATE | APR_BINARY, APR_OS_DEFAULT, globalShmPool); if (rc!=JK_OK) { char error[256]; apr_strerror( rc, error, 256 ); env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.create(): error opening file %s %d %s\n", shm->fname, rc, error ); shm->privateData=NULL; return rc; } rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file); if( shm->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "shm.create(): file open %s %d %d\n", shm->fname, shm->size, finfo.size ); if( finfo.size < shm->size ) { char bytes[1024]; apr_size_t toWrite = (apr_size_t)(shm->size-finfo.size); apr_off_t off=0; memset( bytes, 0, 1024 ); apr_file_seek( file, APR_END, &off); while( toWrite > 0 ) { apr_size_t written; rc=apr_file_write_full(file, bytes, 1024, &written); if( rc!=APR_SUCCESS ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.create(): Can't write %s %d %s\n", shm->fname, errno, strerror( errno )); return JK_ERR; } if( toWrite < written ){ toWrite=0; }else{ toWrite-=written; } } rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file); } /* Now mmap it */ rc=apr_mmap_create( &aprMmap, file, (apr_off_t)0, (apr_size_t)finfo.size, APR_MMAP_READ | APR_MMAP_WRITE, globalShmPool ); if( rc!=JK_OK ) { char error[256]; apr_strerror( rc, error, 256 ); env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.create(): error creating %s %d %d %#lx %s\n", shm->fname, finfo.size, rc, globalShmPool, error ); shm->privateData=NULL; return rc; } shm->privateData=aprMmap; apr_mmap_offset(& shm->image, aprMmap, (apr_off_t)0); apr_pool_userdata_set( shm->image, "mod_jk_shm", NULL, globalShmPool ); shm->head = (jk_shm_head_t *)shm->image; if( shm->image==NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.create(): No base memory %s\n", shm->fname); return JK_ERR; } return JK_OK; }
/** * \brief get file content of given tile * * fills the mapcache_tile::data of the given tile with content stored in the file * \private \memberof mapcache_cache_disk * \sa mapcache_cache::tile_get() */ static int _mapcache_cache_disk_get(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { char *filename; apr_file_t *f; apr_finfo_t finfo; apr_status_t rv; apr_size_t size; apr_mmap_t *tilemmap; mapcache_cache_disk *cache = (mapcache_cache_disk*)pcache; cache->tile_key(ctx, cache, tile, &filename); if(GC_HAS_ERROR(ctx)) { return MAPCACHE_FAILURE; } ctx->log(ctx,MAPCACHE_DEBUG,"checking for tile %s",filename); if((rv=apr_file_open(&f, filename, #ifndef NOMMAP APR_FOPEN_READ, APR_UREAD | APR_GREAD, #else APR_FOPEN_READ|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,APR_OS_DEFAULT, #endif ctx->pool)) == APR_SUCCESS) { rv = apr_file_info_get(&finfo, APR_FINFO_SIZE|APR_FINFO_MTIME, f); if(!finfo.size) { ctx->set_error(ctx, 500, "tile %s has no data",filename); return MAPCACHE_FAILURE; } size = finfo.size; /* * at this stage, we have a handle to an open file that contains data. * idealy, we should aquire a read lock, in case the data contained inside the file * is incomplete (i.e. if another process is currently writing to the tile). * currently such a lock is not set, as we don't want to loose performance on tile accesses. * any error that might happen at this stage should only occur if the tile isn't already cached, * i.e. normally only once. */ tile->mtime = finfo.mtime; tile->encoded_data = mapcache_buffer_create(size,ctx->pool); #ifndef NOMMAP rv = apr_mmap_create(&tilemmap,f,0,finfo.size,APR_MMAP_READ,ctx->pool); if(rv != APR_SUCCESS) { char errmsg[120]; ctx->set_error(ctx, 500, "mmap error: %s",apr_strerror(rv,errmsg,120)); return MAPCACHE_FAILURE; } tile->encoded_data->buf = tilemmap->mm; tile->encoded_data->size = tile->encoded_data->avail = finfo.size; #else //manually add the data to our buffer apr_file_read(f,(void*)tile->encoded_data->buf,&size); tile->encoded_data->size = size; tile->encoded_data->avail = size; #endif apr_file_close(f); if(tile->encoded_data->size != finfo.size) { ctx->set_error(ctx, 500, "failed to copy image data, got %d of %d bytes",(int)size, (int)finfo.size); return MAPCACHE_FAILURE; } return MAPCACHE_SUCCESS; } else { if(APR_STATUS_IS_ENOENT(rv)) { /* the file doesn't exist on the disk */ return MAPCACHE_CACHE_MISS; } else { char *error = strerror(rv); ctx->set_error(ctx, 500, "failed to open file %s: %s",filename, error); return MAPCACHE_FAILURE; } } }
apr_status_t kahanaUtilChecksum( apr_pool_t *p, kCheckSumType_e type, const char **hex_digest, const char *msg, ... ) { apr_status_t rc = APR_SUCCESS; char *keys = NULL; if( !( keys = calloc( 0, sizeof( char ) ) ) ){ rc = APR_ENOMEM; } else { va_list args; char *key; int i, len = 0; va_start( args, msg ); while( ( key = va_arg( args, char* ) ) ) { if( ( i = strlen( key ) ) ) { if( !( keys = realloc( keys, len + i + 1 ) ) ){ rc = APR_ENOMEM; len = 0; break; } memcpy( keys + len, key, i ); len += i; keys[len] = '\0'; } } va_end( args ); if( len ) { rc = APR_SUCCESS; if( type == CHKSUM_STR ) { char *m = NULL; if( asprintf( &m, "%s", msg ) == -1 ){ rc = APR_ENOMEM; } else { *hex_digest = kahanaUtilHMACSHA1( p, (unsigned char*)keys, len, (const unsigned char*)m, strlen( m ) ); free( m ); } } else if( type == CHKSUM_FILE ) { apr_file_t *fp = NULL; if( ( rc = apr_file_open( &fp, msg, APR_READ|APR_BINARY, APR_OS_DEFAULT, p ) ) == APR_SUCCESS ) { apr_finfo_t finfo; apr_mmap_t *mm = NULL; if( ( rc = apr_file_info_get( &finfo, APR_FINFO_SIZE, fp ) ) == APR_SUCCESS && ( rc = apr_mmap_create( &mm, fp, 0, finfo.size, APR_MMAP_READ, p ) ) != APR_SUCCESS ){ mm = NULL; } apr_file_close( fp ); if( mm ){ *hex_digest = kahanaUtilHMACSHA1( p, (unsigned char*)keys, len, mm->mm, finfo.size ); rc = apr_mmap_delete( mm ); } } } else { rc = APR_BADARG; } } free( keys ); } return rc; }