aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2017-10-18 08:49:01 +0200
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2017-10-18 08:49:01 +0200
commit57fe5475fff971ce183946f80652979b9445ce0e (patch)
treee8c2205607982cd668598fa8e082ce00568efe39
parent3fa79ea0753236644547b8e67184a9c438255bb1 (diff)
downloadembedlog-57fe5475fff971ce183946f80652979b9445ce0e.tar.gz
embedlog-57fe5475fff971ce183946f80652979b9445ce0e.tar.bz2
embedlog-57fe5475fff971ce183946f80652979b9445ce0e.zip
Some bug fixes
-rw-r--r--src/el-file.c100
-rw-r--r--src/el-options.c27
-rw-r--r--src/el-perror.c91
-rw-r--r--src/el-print.c5
4 files changed, 153 insertions, 70 deletions
diff --git a/src/el-file.c b/src/el-file.c
index 2ac3180..afa2560 100644
--- a/src/el-file.c
+++ b/src/el-file.c
@@ -65,44 +65,11 @@
/* ==========================================================================
- checks if we can (or should) write to a file
- ========================================================================== */
-
-
-static int el_file_is_writeable
-(
- struct el_options *options, /* file options */
- size_t slen /* length of string caller wants to print */
-)
-{
- if (options->file == NULL)
- {
- /*
- * well, it's hard to write to a file if it is not opened
- */
-
- return 0;
- }
-
- if (options->fpos + slen > options->frotate_size)
- {
- /*
- * writing to file, would overflow it (according to frotate_size
- * set by user), so write should no be allowed.
- */
-
- return 0;
- }
-
- return 1;
-}
-
-
-/* ==========================================================================
function rotates file, meaning if currently opened file has suffix .3,
function will close that file and will open file with suffix .4. If
creating new suffix is impossible (we reached frotate_number of
- suffixed) function will rename files, and create new file with suffix .0
+ suffixed) function will remove oldest log file and new file will be
+ created
========================================================================== */
@@ -230,6 +197,12 @@ int el_file_open
{
if (options->file)
{
+ off_t fsize; /* size of the opened file we close */
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ fsize = ftell(options->file);
+
/*
* to prevent any memory leak in case of double open, we first
* close already opened file Such situation may happen when library
@@ -237,6 +210,17 @@ int el_file_open
*/
fclose(options->file);
+
+ if (fsize == 0)
+ {
+ /*
+ * file is empty, so we get rid of it, as it was probably opened
+ * by mistake
+ */
+
+ remove(options->fname);
+ }
+
options->file = NULL;
}
@@ -356,25 +340,49 @@ int el_file_puts
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- sl = strlen(s);
-
- if (options->frotate_number && el_file_is_writeable(options, sl) == 0)
+ if (options->file == NULL)
{
/*
- * we get here only when frotate is enabled, and writing to current
- * file would result in exceding frotate_size of file. In suche case
- * we rotate the file by closing the old one and opening new file,
- * and if we already filled frotate_number files, we remove the
- * oldest one, unless frotate_number is -1, then we rotate without
- * deleting anything.
+ * file has not been opened, prevent segfault
*/
- if (el_file_rotate(options) != 0)
+ errno = EBADF;
+ return -1;
+ }
+
+ sl = strlen(s);
+
+ if (options->frotate_number)
+ {
+ if (options->fpos + sl > options->frotate_size)
+ {
+ /*
+ * we get here only when frotate is enabled, and writing to
+ * current file would result in exceding frotate_size of file.
+ * In such case we rotate the file by closing the old one and
+ * opening new file, and if we already filled frotate_number
+ * files, we remove the oldest one.
+ */
+
+ if (el_file_rotate(options) != 0)
+ {
+ return -1;
+ }
+ }
+
+ if (sl > options->frotate_size)
{
- return -1;
+ /*
+ * we can't fit message even in an empty file, in such case we
+ * need to truncate log, so we don't create file bigger than
+ * configured frotate_size
+ */
+
+ sl = options->frotate_size;
}
}
+
if (fwrite(s, sl, 1, options->file) != 1)
{
return -1;
diff --git a/src/el-options.c b/src/el-options.c
index 0ade6d7..404da17 100644
--- a/src/el-options.c
+++ b/src/el-options.c
@@ -203,14 +203,36 @@ static int el_vooption
case EL_OPT_FNAME:
value_str = va_arg(ap, const char *);
+ VALID(EINVAL, value_str);
options->fname = value_str;
return el_file_open(options);
case EL_OPT_FROTATE_NUMBER:
+ {
+ int previous_frotate; /* previous value of frotate number */
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
value_int = va_arg(ap, int);
VALID(EINVAL, value_int >= 0);
+ previous_frotate = options->frotate_number;
options->frotate_number = value_int;
+
+ if (previous_frotate == 0 && options->file)
+ {
+ /*
+ * user turned on file rotation when file is already opened
+ * without rotation. To prevent weird situations and even data
+ * loss, we reopen file as opening with log rotation is a bit
+ * different. el_file_open function will close file before
+ * reopening
+ */
+
+ return el_file_open(options);
+ }
+
return 0;
+ }
case EL_OPT_FROTATE_SIZE:
value_long = va_arg(ap, long);
@@ -299,10 +321,11 @@ int el_cleanup
/* ==========================================================================
- cleans up whatever has been initialized/reserver by el_cleanup
+ cleans up whatever has been initialized/reserved by el_option and
+ el_init calls
errno
- EINVAL options is invlaid (null)
+ EINVAL options is invalid (null)
========================================================================== */
diff --git a/src/el-perror.c b/src/el-perror.c
index c5a5d86..b6c6171 100644
--- a/src/el-perror.c
+++ b/src/el-perror.c
@@ -33,6 +33,63 @@
/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ ____ __ _
+ / __/__ __ ____ _____ / /_ (_)____ ____ _____
+ / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
+ / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
+ /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
+
+ ========================================================================== */
+
+
+/* ==========================================================================
+ calls el_print with 'fmt' and '...' parameters, but additionaly prints
+ information about errno. Functionaly it is similar to perror function
+ ========================================================================== */
+
+
+static int el_ovperror
+(
+ const char *file, /* file name where log is printed */
+ size_t num, /* line number where log is printed */
+ enum el_level level, /* log level to print message with */
+ struct el_options *options, /* options defining printing style */
+ const char *fmt, /* message format (see printf (3)) */
+ va_list ap /* additional parameters for fmt */
+)
+{
+ int rc; /* return code from el_print() */
+ unsigned long e; /* errno from upper layer */
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ e = errno;
+ rc = 0;
+
+ if (fmt)
+ {
+ /*
+ * we print formatted message only when it is supplied by the user,
+ * otherwise only errno message will be printed
+ */
+
+ rc |= el_ovprint(file, num, level, options, fmt, ap);
+ }
+
+ rc |= el_oprint(file, num, level, options,
+ "errno num: %lu, strerror: %s", e, strerror(e));
+
+ return rc;
+}
+
+
+/* ==========================================================================
__ __ _
____ __ __ / /_ / /(_)_____
/ __ \ / / / // __ \ / // // ___/
@@ -56,26 +113,22 @@
int el_perror
(
- const char *file, /* file name where log is printed */
- size_t num, /* line number where log is printed */
- enum el_level level, /* log level to print message with */
- const char *fmt, /* message format (see printf (3)) */
- ... /* additional parameters for fmt */
+ const char *file, /* file name where log is printed */
+ size_t num, /* line number where log is printed */
+ enum el_level level, /* log level to print message with */
+ const char *fmt, /* message format (see printf (3)) */
+ ... /* additional parameters for fmt */
)
{
- va_list ap; /* arguments '...' for 'fmt' */
- int rc; /* return code from el_print() */
- unsigned long e; /* errno from upper layer */
+ int rc; /* return code from el_operror() */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- e = errno;
-
va_start(ap, fmt);
- rc = el_ovprint(file, num, level, &g_options, fmt, ap);
- rc |= el_oprint(file, num, level, &g_options,
- "errno num: %lu, strerror: %s", e, strerror(e));
+ rc = el_ovperror(file, num, level, &g_options, fmt, ap);
va_end(ap);
+
+ return rc;
}
@@ -94,17 +147,13 @@ int el_operror
... /* additional parameters for fmt */
)
{
- va_list ap; /* arguments '...' for 'fmt' */
- int rc; /* return code from el_print() */
- unsigned long e; /* errno from upper layer */
+ int rc; /* return code from el_operror() */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- e = errno;
-
va_start(ap, fmt);
- rc = el_ovprint(file, num, level, options, fmt, ap);
- rc |= el_oprint(file, num, level, options,
- "errno num: %lu, strerror: %s", e, strerror(e));
+ rc = el_ovperror(file, num, level, options, fmt, ap);
va_end(ap);
+
+ return rc;
}
diff --git a/src/el-print.c b/src/el-print.c
index 3223ebc..559a1e7 100644
--- a/src/el-print.c
+++ b/src/el-print.c
@@ -600,7 +600,10 @@ int el_ovprint
buf[w++] = '\n';
buf[w++] = '\0';
- el_oputs(options, buf);
+ if (el_oputs(options, buf) != 0)
+ {
+ return -1;
+ }
if (e)
{