diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-04-14 18:05:06 +0200 |
---|---|---|
committer | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-04-14 18:05:06 +0200 |
commit | d5597d99de2615b5d592fd61b906fc8af3c296fd (patch) | |
tree | 8fad6d02c10b21953e00db0036f698e8c13e8e7d | |
parent | 27b9371d7e187d4a8aad27d6ce53c500c148212e (diff) | |
download | embedlog-d5597d99de2615b5d592fd61b906fc8af3c296fd.tar.gz embedlog-d5597d99de2615b5d592fd61b906fc8af3c296fd.tar.bz2 embedlog-d5597d99de2615b5d592fd61b906fc8af3c296fd.zip |
add: alternative algorithm for finding rotate file
previous algo on fopen was raping MTD devices like there was no
tommorow, new algo performs at most single write on fopen
(when there is no any log files yet) but requires POSIX
access and stat
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/el-file.c | 92 |
2 files changed, 91 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 466c8a9..ccb0e8b 100644 --- a/configure.ac +++ b/configure.ac @@ -97,6 +97,7 @@ AS_IF([test "x$enable_out_file" = "xyes"], [ AC_DEFINE([ENABLE_OUT_FILE], [1], [Enable printing to file]) AC_CHECK_FUNCS(access) + AC_CHECK_FUNCS(stat) AC_CHECK_FUNCS([fopen fclose fwrite remove rename],, AC_MSG_ERROR(not found, needed by --enable-out-file)) ]) diff --git a/src/el-file.c b/src/el-file.c index 58dba28..9581b21 100644 --- a/src/el-file.c +++ b/src/el-file.c @@ -39,14 +39,20 @@ ========================================================================== */ #if HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif #include "el-options.h" #if HAVE_UNISTD_H -#include <unistd.h> +# include <unistd.h> #endif + +#if HAVE_STAT +# include <sys/types.h> +# include <sys/stat.h> +#endif + #include <errno.h> #include <limits.h> #include <stdint.h> @@ -315,6 +321,86 @@ int el_file_open return -1; } +#if HAVE_ACCESS && HAVE_STAT + + if (i != 0) + { + struct stat st; + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + + /* + * if i is 0, then this is last file to check (there are no + * logs from embed log in directory) and there is no need to + * check if file exists or not - we open it unconditionally, + * thus this path is not taken in such case. + */ + + if (el_file_exists(options->current_log) == 0) + { + /* + * current log file does not exist, this is not the file + * you are looking for + */ + + continue; + } + + if (stat(options->current_log, &st) != 0) + { + /* + * error while stating file, probably don't have access + * to that file, or directory, or whatever, something + * bad has happend and we don't want to pursue this, + * exit with error from stat. + */ + + options->current_log[0] = '\0'; + return -1; + } + + if (st.st_size == 0) + { + /* + * there is an empty file, maybe we created it and then + * crashed? Or maybe someone is trying to pull our legs + * and drops bombs under our feets. Either way, this is + * definitely not oldest file. We also remove it so it + * doesn't botter us later + */ + + remove(options->current_log); + continue; + } + } + + /* + * we got our file, let's open it for writing and let's call it + * a day + */ + + if ((f = fopen(options->current_log, "a")) == NULL) + { + /* + * well not so fast! while file exists, and we were able to + * read it (stat) it looks like we cannot write to it, tough + * luck, that means error and no logging to file + */ + + options->current_log[0] = '\0'; + return -1; + } + + /* + * we need to check for currently opened file size once again, + * as if i equal 0 here, we never called stat() on our file and + * we don't know the size of it + */ + + fseek(f, 0, SEEK_END); + fsize = ftell(f); + +#else /* HAVE_ACCESS && HAVE_STAT */ + if ((f = fopen(options->current_log, "a")) == NULL) { /* @@ -363,6 +449,8 @@ int el_file_open continue; } +#endif /* HAVE_ACCESS && HAVE_STAT */ + /* * oldest file found, file is already opened so we simply return * from the function |