diff options
author | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-08-24 21:36:30 +0200 |
---|---|---|
committer | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-08-24 21:36:30 +0200 |
commit | 82e095124dac524b28dff9d99bafa05a821ae732 (patch) | |
tree | a418d227c5c58ee8eda43c9cd0390dbe8eb08d3c | |
parent | c44b9d201765ab71ae0a7a741a396b28f289dce0 (diff) |
feat(rss,atom): mmap on demand like in blog_index
* entry * add entry_unget_text: implements unmmaping * free_entry: now expects pointer * index: adjust for entry changes * main * adjust for entry changes * use on demand mmaping in blog_atom and blog_rss * shell.nix * add strace for mmap debugging
-rw-r--r-- | entry.c | 25 | ||||
-rw-r--r-- | entry.h | 24 | ||||
-rw-r--r-- | index.c | 4 | ||||
-rw-r--r-- | main.c | 137 | ||||
-rw-r--r-- | shell.nix | 2 |
5 files changed, 105 insertions, 87 deletions
diff --git a/entry.c b/entry.c index 5714978..756a62e 100644 --- a/entry.c +++ b/entry.c @@ -190,21 +190,26 @@ int entry_get_text(struct entry *entry) { return 0; } -void free_entry(struct entry entry) { - if(entry.path != NULL) { - free(entry.path); +void entry_unget_text(struct entry *entry) { + if(entry->text_size > 0 && entry->text != NULL && + munmap(entry->text, entry->text_size) != -1) { + entry->text_size = -1; + entry->text = NULL; } +} - if(entry.link != NULL) { - free(entry.link); +void free_entry(struct entry *entry) { + if(entry->path != NULL) { + free(entry->path); } - if(entry.title != NULL) { - free(entry.title); + if(entry->link != NULL) { + free(entry->link); } - if(entry.text != NULL) { - // TODO return value - munmap(entry.text, entry.text_size); + if(entry->title != NULL) { + free(entry->title); } + + entry_get_text(entry); } diff --git a/entry.h b/entry.h index 669e7a9..de8d868 100644 --- a/entry.h +++ b/entry.h @@ -73,12 +73,25 @@ int make_entry(const char *blog_dir, char *script_name, char *path_info, struct * * @return 0 on success, -1 on error, currently errno is not set correctly * + * @see entry_unget_text * @see make_entry * @see free_entry */ int entry_get_text(struct entry *entry); /*! + * @brief Unmap the file referenced in a `struct entry` + * + * Tries to `munmap()` the file pointed to by `entry->text` + * if present, and updates `entry->text_size` accordingly. + * + * The rest of the struct is left untouched. + * + * @see free_entry + */ +void entry_unget_text(struct entry *entry); + +/*! * @brief Free dynamically allocated parts on an `entry` * * Frees any non `NULL` pointers in the given `entry` structure. @@ -86,8 +99,11 @@ int entry_get_text(struct entry *entry); * after being called, so you can always call `free_entry()` after * `make_entry()`. * - * It also unmaps the mapped file in `text` if it is not `NULL`. - * For this `text_size` is needed which is set correctly - * by `entry_get_text()`. + * It also unmaps the mapped file in `text` if it is not `NULL` + * using `entry_unget_text()`. + * + * Warning: It won't call `free()` on the entire entry structure. + * + * @see entry_unget_text */ -void free_entry(struct entry entry); +void free_entry(struct entry *entry); diff --git a/index.c b/index.c index 0a0ee67..bb94bb9 100644 --- a/index.c +++ b/index.c @@ -107,7 +107,7 @@ int make_index(const char *blog_dir, char *script_name, bool get_text, struct en index_count++; } else { - free_entry(tmp_entry); + free_entry(&tmp_entry); } } } @@ -125,7 +125,7 @@ int make_index(const char *blog_dir, char *script_name, bool get_text, struct en void free_index(struct entry *entries[], int count) { if(count > 0) { for(int i = 0; i < count; i++) { - free_entry(*(*entries + i)); + free_entry(*entries + i); } } diff --git a/main.c b/main.c index 55d8000..21ab753 100644 --- a/main.c +++ b/main.c @@ -95,11 +95,6 @@ #include "template.h" #include "xml.h" -// TODO sandbox -// caching -// reduce memory usage by only using get_text in the inner loop -// and unmapping the file directly afterwards - void send_standard_headers(int status, char content_type[]); /*! @@ -166,7 +161,6 @@ int main(void) { template_error(500); template_footer(); - // TODO exit failure on error? return EXIT_SUCCESS; } @@ -217,12 +211,7 @@ void blog_index(char script_name[]) { for(int i = 0; i < count; i++) { if(entry_get_text(&entries[i]) != -1) { template_index_entry(entries[i]); - - // unmap file - if(munmap(entries[i].text, entries[i].text_size) != -1) { - entries[i].text_size = -1; - entries[i].text = NULL; - } + entry_unget_text(&entries[i]); } } @@ -252,14 +241,14 @@ void blog_entry(char script_name[], char path_info[]) { template_footer(); } - free_entry(entry); + free_entry(&entry); } void blog_rss(char script_name[]) { // index struct entry *entries = NULL; - int count = make_index(BLOG_DIR, script_name, 1, &entries); + int count = make_index(BLOG_DIR, script_name, 0, &entries); if(count < 0) { send_standard_headers(500, "text/plain"); @@ -315,38 +304,42 @@ void blog_rss(char script_name[]) { } for(int i = 0; i < count; i++) { - xml_open_tag(&ctx, "item"); - xml_open_tag(&ctx, "title"); - xml_escaped(&ctx, entries[i].title); - xml_close_tag(&ctx, "title"); - - xml_open_tag(&ctx, "link"); - xml_escaped(&ctx, BLOG_SERVER_URL); - xml_escaped(&ctx, entries[i].link); - xml_close_tag(&ctx, "link"); - - xml_open_tag(&ctx, "guid"); - xml_escaped(&ctx, BLOG_SERVER_URL); - xml_escaped(&ctx, entries[i].link); - xml_close_tag(&ctx, "guid"); - - if(entries[i].text_size > 0) { - xml_open_tag(&ctx, "description"); - xml_open_cdata(&ctx); - xml_raw(&ctx, entries[i].text); - xml_close_cdata(&ctx); - xml_close_tag(&ctx, "description"); - } + if(entry_get_text(&entries[i]) != -1) { + xml_open_tag(&ctx, "item"); + xml_open_tag(&ctx, "title"); + xml_escaped(&ctx, entries[i].title); + xml_close_tag(&ctx, "title"); + + xml_open_tag(&ctx, "link"); + xml_escaped(&ctx, BLOG_SERVER_URL); + xml_escaped(&ctx, entries[i].link); + xml_close_tag(&ctx, "link"); + + xml_open_tag(&ctx, "guid"); + xml_escaped(&ctx, BLOG_SERVER_URL); + xml_escaped(&ctx, entries[i].link); + xml_close_tag(&ctx, "guid"); + + if(entries[i].text_size > 0) { + xml_open_tag(&ctx, "description"); + xml_open_cdata(&ctx); + xml_raw(&ctx, entries[i].text); + xml_close_cdata(&ctx); + xml_close_tag(&ctx, "description"); + } - char strtime_entry[MAX_TIMESTR_SIZE]; + char strtime_entry[MAX_TIMESTR_SIZE]; - if(flocaltime(strtime_entry, RSS_TIME_FORMAT, MAX_TIMESTR_SIZE, &entries[i].time) > 0) { - xml_open_tag(&ctx, "pubDate"); - xml_escaped(&ctx, strtime_entry); - xml_close_tag(&ctx, "pubDate"); - } + if(flocaltime(strtime_entry, RSS_TIME_FORMAT, MAX_TIMESTR_SIZE, &entries[i].time) > 0) { + xml_open_tag(&ctx, "pubDate"); + xml_escaped(&ctx, strtime_entry); + xml_close_tag(&ctx, "pubDate"); + } - xml_close_tag(&ctx, "item"); + xml_close_tag(&ctx, "item"); + + entry_unget_text(&entries[i]); + } } xml_close_all(&ctx); @@ -359,7 +352,7 @@ void blog_rss(char script_name[]) { void blog_atom(char script_name[]) { struct entry *entries = NULL; - int count = make_index(BLOG_DIR, script_name, 1, &entries); + int count = make_index(BLOG_DIR, script_name, 0, &entries); if(count < 0) { send_standard_headers(500, "text/plain"); @@ -431,37 +424,41 @@ void blog_atom(char script_name[]) { } for(int i = 0; i < count; i++) { - xml_open_tag(&ctx, "entry"); + if(entry_get_text(&entries[i]) != -1) { + xml_open_tag(&ctx, "entry"); + + xml_open_tag(&ctx, "id"); + xml_escaped(&ctx, BLOG_SERVER_URL); + xml_escaped(&ctx, entries[i].link); + xml_close_tag(&ctx, "id"); + + xml_open_tag(&ctx, "title"); + xml_escaped(&ctx, entries[i].title); + xml_close_tag(&ctx, "title"); + + char strtime_entry[MAX_TIMESTR_SIZE]; + if(flocaltime(strtime_entry, ATOM_TIME_FORMAT, MAX_TIMESTR_SIZE, &entries[i].time) > 0) { + xml_open_tag(&ctx, "updated"); + xml_escaped(&ctx, strtime_entry); + xml_close_tag(&ctx, "updated"); + } - xml_open_tag(&ctx, "id"); - xml_escaped(&ctx, BLOG_SERVER_URL); - xml_escaped(&ctx, entries[i].link); - xml_close_tag(&ctx, "id"); + char *entry_url = catn_alloc(2, BLOG_SERVER_URL, entries[i].link); + if(entry_url != NULL) { + xml_empty_tag(&ctx, "link", 3, "rel", "alternate", "type", "text/html", "href", entry_url); + free(entry_url); + } - xml_open_tag(&ctx, "title"); - xml_escaped(&ctx, entries[i].title); - xml_close_tag(&ctx, "title"); + xml_open_tag_attrs(&ctx, "content", 1, "type", "html"); + xml_open_cdata(&ctx); + xml_raw(&ctx, entries[i].text); + xml_close_cdata(&ctx); + xml_close_tag(&ctx, "content"); - char strtime_entry[MAX_TIMESTR_SIZE]; - if(flocaltime(strtime_entry, ATOM_TIME_FORMAT, MAX_TIMESTR_SIZE, &entries[i].time) > 0) { - xml_open_tag(&ctx, "updated"); - xml_escaped(&ctx, strtime_entry); - xml_close_tag(&ctx, "updated"); - } + xml_close_tag(&ctx, "entry"); - char *entry_url = catn_alloc(2, BLOG_SERVER_URL, entries[i].link); - if(entry_url != NULL) { - xml_empty_tag(&ctx, "link", 3, "rel", "alternate", "type", "text/html", "href", entry_url); - free(entry_url); + entry_unget_text(&entries[i]); } - - xml_open_tag_attrs(&ctx, "content", 1, "type", "html"); - xml_open_cdata(&ctx); - xml_raw(&ctx, entries[i].text); - xml_close_cdata(&ctx); - xml_close_tag(&ctx, "content"); - - xml_close_tag(&ctx, "entry"); } xml_close_tag(&ctx, "feed"); diff --git a/shell.nix b/shell.nix index ca97a56..4b23757 100644 --- a/shell.nix +++ b/shell.nix @@ -3,5 +3,5 @@ pkgs.mkShell { name = "sternenblog-env"; - buildInputs = with pkgs; [ gnumake valgrind gdb doxygen ]; + buildInputs = with pkgs; [ gnumake valgrind gdb doxygen strace ]; } |