diff options
Diffstat (limited to 'src/core/librcscripts/dynbuf.c')
-rw-r--r-- | src/core/librcscripts/dynbuf.c | 105 |
1 files changed, 90 insertions, 15 deletions
diff --git a/src/core/librcscripts/dynbuf.c b/src/core/librcscripts/dynbuf.c index 65e8a43..5fc156e 100644 --- a/src/core/librcscripts/dynbuf.c +++ b/src/core/librcscripts/dynbuf.c @@ -30,7 +30,7 @@ #include "rcscripts.h" -static dyn_buf_t *reallocate_dyn_buf (dyn_buf_t * dynbuf, size_t needed); +static dyn_buf_t *reallocate_dyn_buf (dyn_buf_t *dynbuf, size_t needed); dyn_buf_t * new_dyn_buf (void) @@ -51,18 +51,51 @@ new_dyn_buf (void) dynbuf->length = DYNAMIC_BUFFER_SIZE; dynbuf->rd_index = 0; dynbuf->wr_index = 0; + dynbuf->file_map = FALSE; return dynbuf; } dyn_buf_t * -reallocate_dyn_buf (dyn_buf_t * dynbuf, size_t needed) +new_dyn_buf_mmap_file (const char *name) +{ + dyn_buf_t *dynbuf = NULL; + + dynbuf = xmalloc (sizeof (dyn_buf_t)); + if (NULL == dynbuf) + return NULL; + + if (-1 == file_map (name, &dynbuf->data, &dynbuf->length)) + { + DBG_MSG ("Failed to mmap file '%s'\n", name); + free (dynbuf); + + return NULL; + } + + dynbuf->wr_index = dynbuf->length; + dynbuf->rd_index = 0; + dynbuf->file_map = TRUE; + + return dynbuf; +} + +dyn_buf_t * +reallocate_dyn_buf (dyn_buf_t *dynbuf, size_t needed) { int len; if (!check_arg_dyn_buf (dynbuf)) return NULL; + if (dynbuf->file_map) + { + errno = EPERM; + DBG_MSG ("Cannot reallocate mmap()'d file!\n"); + + return NULL; + } + len = sizeof (char) * (dynbuf->wr_index + needed + 1); if (dynbuf->length < len) @@ -85,15 +118,24 @@ reallocate_dyn_buf (dyn_buf_t * dynbuf, size_t needed) } void -free_dyn_buf (dyn_buf_t * dynbuf) +free_dyn_buf (dyn_buf_t *dynbuf) { if (NULL == dynbuf) return; - if (NULL != dynbuf->data) + if (!dynbuf->file_map) + { + if (NULL != dynbuf->data) + { + free (dynbuf->data); + dynbuf->data = NULL; + } + } + else { - free (dynbuf->data); - dynbuf->data = NULL; + save_errno (); + file_unmap (dynbuf->data, dynbuf->length); + restore_errno (); } dynbuf->length = 0; @@ -105,16 +147,24 @@ free_dyn_buf (dyn_buf_t * dynbuf) } int -write_dyn_buf (dyn_buf_t * dynbuf, const char *buf, size_t length) +write_dyn_buf (dyn_buf_t *dynbuf, const char *buf, size_t length) { int len; if (!check_arg_dyn_buf (dynbuf)) return -1; - if (!check_arg_ptr ((char *) buf)) + if (!check_arg_str (buf)) return -1; + if (dynbuf->file_map) + { + errno = EPERM; + DBG_MSG ("Cannot write to readonly mmap()'d file!\n"); + + return -1; + } + if (NULL == reallocate_dyn_buf (dynbuf, length)) { DBG_MSG ("Could not reallocate dynamic buffer!\n"); @@ -137,7 +187,7 @@ write_dyn_buf (dyn_buf_t * dynbuf, const char *buf, size_t length) return length; } -int write_dyn_buf_from_fd (int fd, dyn_buf_t * dynbuf, size_t length) +int write_dyn_buf_from_fd (int fd, dyn_buf_t *dynbuf, size_t length) { int len = length; @@ -147,6 +197,14 @@ int write_dyn_buf_from_fd (int fd, dyn_buf_t * dynbuf, size_t length) if (!check_arg_fd (fd)) return -1; + if (dynbuf->file_map) + { + errno = EPERM; + DBG_MSG ("Cannot write to readonly mmap()'d file!\n"); + + return -1; + } + if (NULL == reallocate_dyn_buf (dynbuf, length)) { DBG_MSG ("Could not reallocate dynamic buffer!\n"); @@ -170,7 +228,7 @@ int write_dyn_buf_from_fd (int fd, dyn_buf_t * dynbuf, size_t length) } int -sprintf_dyn_buf (dyn_buf_t * dynbuf, const char *format, ...) +sprintf_dyn_buf (dyn_buf_t *dynbuf, const char *format, ...) { va_list arg1, arg2; char test_str[10]; @@ -179,6 +237,17 @@ sprintf_dyn_buf (dyn_buf_t * dynbuf, const char *format, ...) if (!check_arg_dyn_buf (dynbuf)) return -1; + if (!check_arg_str (format)) + return -1; + + if (dynbuf->file_map) + { + errno = EPERM; + DBG_MSG ("Cannot write to readonly mmap()'d file!\n"); + + return -1; + } + va_start (arg1, format); va_copy (arg2, arg1); @@ -206,7 +275,7 @@ sprintf_dyn_buf (dyn_buf_t * dynbuf, const char *format, ...) } int -read_dyn_buf (dyn_buf_t * dynbuf, char *buf, size_t length) +read_dyn_buf (dyn_buf_t *dynbuf, char *buf, size_t length) { int len = length; @@ -239,7 +308,7 @@ read_dyn_buf (dyn_buf_t * dynbuf, char *buf, size_t length) } int -read_dyn_buf_to_fd (int fd, dyn_buf_t * dynbuf, size_t length) +read_dyn_buf_to_fd (int fd, dyn_buf_t *dynbuf, size_t length) { int len = length; @@ -277,17 +346,23 @@ read_line_dyn_buf (dyn_buf_t *dynbuf) if (!check_arg_dyn_buf (dynbuf)) return NULL; + if (dynbuf->rd_index == dynbuf->wr_index) + return NULL; + for (count = dynbuf->rd_index; count < dynbuf->wr_index && dynbuf->data[count] != '\n'; count++); - if (count > dynbuf->rd_index) + if (count <= dynbuf->wr_index) { buf = xstrndup ((dynbuf->data + dynbuf->rd_index), (count - dynbuf->rd_index)); if (NULL == buf) return NULL; + dynbuf->rd_index = count; + /* Also skip the '\n' .. */ - dynbuf->rd_index = count + 1; + if (dynbuf->rd_index < dynbuf->wr_index) + dynbuf->rd_index++; } return buf; @@ -316,7 +391,7 @@ check_dyn_buf (dyn_buf_t *dynbuf) inline bool __check_arg_dyn_buf (dyn_buf_t *dynbuf, const char *file, const char *func, - size_t line) + size_t line) { if (!check_dyn_buf (dynbuf)) { |