summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/librcscripts/dynbuf.c')
-rw-r--r--src/core/librcscripts/dynbuf.c105
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))
{