From 152f7157091e8f38d6f7ce0f252aa549f389eb00 Mon Sep 17 00:00:00 2001 From: Bill Stoddard Date: Wed, 13 Feb 2002 18:46:13 +0000 Subject: [PATCH] APR'ize some codepaths. Implement mkdir_structure. General cleanup... It's getting closer to working but still a ways off. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93394 13f79535-47bb-0310-9956-ffa450edef68 --- modules/experimental/mod_disk_cache.c | 95 ++++++++++++++++----------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/modules/experimental/mod_disk_cache.c b/modules/experimental/mod_disk_cache.c index 3e0e8e52bd..0f48b7b2d1 100644 --- a/modules/experimental/mod_disk_cache.c +++ b/modules/experimental/mod_disk_cache.c @@ -96,6 +96,7 @@ typedef struct disk_cache_object { typedef struct { const char* cache_root; + apr_size_t cache_root_len; off_t space; /* Maximum cache size (in 1024 bytes) */ apr_time_t maxexpire; /* Maximum time to keep cached files in msecs */ apr_time_t defaultexpire; /* default time to keep cached file in msecs */ @@ -143,15 +144,30 @@ static char *data_file(apr_pool_t *p, int dirlevels, int dirlength, return apr_pstrcat(p, root, "/", hashfile, CACHE_DATA_SUFFIX, NULL); } -static int mkdir_structure(char *file, const char *root) +static void mkdir_structure(disk_cache_conf *conf, const char *file, apr_pool_t *pool) { - - /* XXX TODO: Use APR to make a root directory. Do some sanity checking... */ - return 0; + apr_status_t rv; + char *p; + + for (p = file + conf->cache_root_len + 1;;) { + p = strchr(p, '/'); + if (!p) + break; + *p = '\0'; + + rv = apr_dir_make(file, + APR_UREAD|APR_UWRITE|APR_UEXECUTE, pool); + if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) { + /* XXX */ + } + *p = '/'; + ++p; + } } -static apr_status_t file_cache_el_final(cache_info *info, cache_handle_t *h, request_rec *r) +static apr_status_t file_cache_el_final(cache_handle_t *h, request_rec *r) { + apr_status_t rv; disk_cache_conf *conf = ap_get_module_config(r->server->module_config, &disk_cache_module); disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj; @@ -159,35 +175,31 @@ static apr_status_t file_cache_el_final(cache_info *info, cache_handle_t *h, req /* move the data over */ if (dobj->fd) { apr_file_flush(dobj->fd); - if (!dobj->datafile) dobj->datafile = data_file(r->pool, conf->dirlevels, conf->dirlength, - conf->cache_root, h->cache_obj->key); - if (unlink(dobj->datafile)) { - mkdir_structure(dobj->datafile, conf->cache_root); + if (!dobj->datafile) { + dobj->datafile = data_file(r->pool, conf->dirlevels, conf->dirlength, + conf->cache_root, h->cache_obj->key); } - else { - /* XXX log */ + /* Remove old file with the same name. If remove fails, then + * perhaps we need to create the directory tree where we are + * about to write the new file. + */ + rv = apr_file_remove(dobj->datafile, r->pool); + if (rv != APR_SUCCESS) { + mkdir_structure(conf, dobj->datafile, r->pool); } -#ifdef WIN32 - /* XXX: win32 doesn't have a link */ - if (apr_file_copy(dobj->tempfile, dobj->datafile, APR_FILE_SOURCE_PERMS, r->pool) != APR_SUCCESS) { -#else - if (link(dobj->tempfile, dobj->datafile) == -1) { -#endif + + /* + * This assumes that the tempfile is on the same file system + * as the cache_root. If not, then we need a file copy/move + * rather than a rename. + */ + rv = apr_file_rename(dobj->tempfile, dobj->datafile, r->pool); + if (rv != APR_SUCCESS) { /* XXX log */ } - else { - /* XXX log message */ - } - if (unlink(dobj->tempfile) == -1) { - /* XXX log message */ - } - else { - /* XXX log message */ - } - } - if (dobj->fd) { - apr_file_close(dobj->fd); /* if you finalize, you are done writing, so close it */ - dobj->fd = 0; + + apr_file_close(dobj->fd); + dobj->fd = NULL; /* XXX log */ } @@ -542,13 +554,15 @@ static int write_headers(cache_handle_t *h, request_rec *r, cache_info *info) disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj; if (!dobj->fd) { - if(!dobj->hdrsfile) dobj->hdrsfile = header_file(r->pool, - conf->dirlevels, - conf->dirlength, - conf->cache_root, - h->cache_obj->key); + if (!dobj->hdrsfile) { + dobj->hdrsfile = header_file(r->pool, + conf->dirlevels, + conf->dirlength, + conf->cache_root, + h->cache_obj->key); + } if(unlink(dobj->hdrsfile)) /* if we can remove it, we clearly don't have to build the dirs */ - mkdir_structure(dobj->hdrsfile, conf->cache_root); + mkdir_structure(conf, dobj->hdrsfile, r->pool); else { /* XXX log message */ } @@ -612,7 +626,7 @@ static int write_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b) apr_file_write(dobj->fd, str, &length); } if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(b))) { - file_cache_el_final(info, h, r); /* Link to the perm file, and close the descriptor */ + file_cache_el_final(h, r); /* Link to the perm file, and close the descriptor */ } return OK; } @@ -627,7 +641,10 @@ static void *create_config(apr_pool_t *p, server_rec *s) conf->space = MAX_CACHE_SIZE; conf->maxfs = MAX_FILE_SIZE; conf->minfs = MIN_FILE_SIZE; - + + conf->cache_root = NULL; + conf->cache_root_len = 0; + return conf; } @@ -640,6 +657,8 @@ static const char disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->cache_root = arg; + conf->cache_root_len = strlen(arg); + return NULL; } static const char -- 2.40.0