diff --git a/HISTORY b/HISTORY index d495ac6..fe1bd16 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.44 2020-09-12 +Version 1.44 2020-09-25 * add test file src/tests/test_pthread_lock.c * add uniq_skiplist.[hc] * add function split_string_ex diff --git a/src/shared_func.c b/src/shared_func.c index daa7e79..f7ed4bf 100644 --- a/src/shared_func.c +++ b/src/shared_func.c @@ -3171,6 +3171,66 @@ int fc_get_last_line(const char *filename, char *buff, return 0; } +int fc_get_last_lines(const char *filename, char *buff, + const int buff_size, string_t *lines, int *count) +{ + int64_t file_size; + int64_t offset; + int64_t read_bytes; + int remain_len; + int i; + int result; + + if (*count <= 0) { + return EINVAL; + } + + if ((result=getFileSize(filename, &file_size)) != 0) { + *count = 0; + return result; + } + + if (file_size == 0) { + *count = 0; + return ENOENT; + } + + if (file_size >= buff_size) { + offset = (file_size - buff_size) + 1; + } else { + offset = 0; + } + read_bytes = (file_size - offset) + 1; + if ((result=getFileContentEx(filename, buff, + offset, &read_bytes)) != 0) + { + return result; + } + if (read_bytes == 0) { + *count = 0; + return ENOENT; + } + + remain_len = read_bytes - 1; + for (i=0; i<*count; i++) { + lines->str = (char *)fc_memrchr(buff, '\n', remain_len); + if (lines->str == NULL) { + lines->str = buff; + break; + } + + remain_len = lines->str - buff; + } + + if (i < *count) { + *count = i + 1; + } else { + lines->str += 1; //skip \n + } + lines->len = (buff + read_bytes) - lines->str; + return 0; +} + static bool path_contains_special(const string_t *pts, const int count) { const string_t *ps; diff --git a/src/shared_func.h b/src/shared_func.h index ebccb7c..f67384c 100644 --- a/src/shared_func.h +++ b/src/shared_func.h @@ -978,6 +978,9 @@ int fc_get_first_line(const char *filename, char *buff, int fc_get_last_line(const char *filename, char *buff, const int buff_size, int64_t *file_size, string_t *line); +int fc_get_last_lines(const char *filename, char *buff, + const int buff_size, string_t *lines, int *count); + /** if the input path contains the needle path * parameters: * path: the absolute path to match