diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-04-22 17:07:09 +0200 |
---|---|---|
committer | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-04-22 17:07:09 +0200 |
commit | a31fa3a531d338997dece723697f23940f8d0d8b (patch) | |
tree | 5de34774986ccabb353df1a26090cfe01cba9a36 | |
parent | d310bfd17fb51699086f47fa0a3e57878c0a8c83 (diff) | |
download | embedlog-a31fa3a531d338997dece723697f23940f8d0d8b.tar.gz embedlog-a31fa3a531d338997dece723697f23940f8d0d8b.tar.bz2 embedlog-a31fa3a531d338997dece723697f23940f8d0d8b.zip |
support automatic reopening of files when frotate is enabled
-rw-r--r-- | src/el-file.c | 61 | ||||
-rw-r--r-- | tst/test-el-file.c | 345 |
2 files changed, 347 insertions, 59 deletions
diff --git a/src/el-file.c b/src/el-file.c index 0b6512c..cafa331 100644 --- a/src/el-file.c +++ b/src/el-file.c @@ -284,6 +284,7 @@ skip_rotate: return 0; } + /* ========================================================================== __ __ _ ____ __ __ / /_ / /(_)_____ @@ -540,6 +541,7 @@ int el_file_open return -1; } + fseek(options->file, 0, SEEK_END); options->fpos = ftell(options->file); return 0; } @@ -565,6 +567,19 @@ int el_file_putb VALID(EBADF, options->current_log[0] != '\0'); + /* + * we need to reopen our file if it wasn't opened yet, or was removed + * due to error or deliberate acion of user + */ + + if (el_file_exists(options->current_log) == 0 || options->file == NULL) + { + if (el_file_open(options) != 0) + { + return -1; + } + } + if (options->frotate_number) { if (options->fpos != 0 && options->fpos + mlen > options->frotate_size) @@ -595,49 +610,6 @@ int el_file_putb } } - if (el_file_exists(options->current_log) == 0) - { - /* - * file doesn't exist, it may happen when someone unlinks currently - * opened file. Even tough user unlinked our log file, we still have - * file opened, so this file exists in the system, but not in the - * file system tree and as such, every write to such file is - * effectively writing to /dev/null. To prevent that, we close and - * reopen our current log file - */ - - if (options->file) - { - fclose(options->file); - } - - if ((options->file = fopen(options->current_log, "a")) == NULL) - { - return -1; - } - - options->fpos = 0; - } - - /* - * there is situation where we options->file is NULL here, it's when - * logs are on externally (like SD card) mounted directory, and this - * directory gets unmounted (or whatever, it dissapear), when we try to - * write to such directory we will fail and options->current_log will be - * set to NULL. Now when that directory reappear with previous content, - * we skip el_file_exists check (because file does exist) and we land - * here with NULL stream which on some systems may result in segfault. - * This check prevents it - */ - - if (options->file == NULL) - { - if ((options->file = fopen(options->current_log, "a")) == NULL) - { - return -1; - } - } - if (fwrite(mem, mlen, 1, options->file) != 1) { return -1; @@ -709,6 +681,9 @@ int el_file_putb errno = EBADF; return -1; } + + fseek(options->file, 0, SEEK_END); + options->fpos = ftell(options->file); #endif /* HAVE_FSYNC && HAVE_FILENO */ #ifdef RUN_TESTS diff --git a/tst/test-el-file.c b/tst/test-el-file.c index daa954b..dd13683 100644 --- a/tst/test-el-file.c +++ b/tst/test-el-file.c @@ -880,20 +880,22 @@ static void file_rotate_5_hole_in_log_rotate(void) el_puts("123"); mt_fok(file_check(WORKDIR"/log.0", "qaz")); - mt_fok(file_check(WORKDIR"/log.1", "edc")); - mt_fok(file_check(WORKDIR"/log.2", "rfv")); + mt_fok(file_check(WORKDIR"/log.2", "edc")); + mt_fok(file_check(WORKDIR"/log.3", "rfv")); mt_fok(file_check(WORKDIR"/log.4", "123")); el_puts("456"); - mt_fok(file_check(WORKDIR"/log.0", "edc")); - mt_fok(file_check(WORKDIR"/log.1", "rfv")); + mt_fok(file_check(WORKDIR"/log.0", "qaz")); + mt_fok(file_check(WORKDIR"/log.1", "edc")); + mt_fok(file_check(WORKDIR"/log.2", "rfv")); mt_fok(file_check(WORKDIR"/log.3", "123")); mt_fok(file_check(WORKDIR"/log.4", "456")); el_puts("789"); - mt_fok(file_check(WORKDIR"/log.0", "rfv")); + mt_fok(file_check(WORKDIR"/log.0", "edc")); + mt_fok(file_check(WORKDIR"/log.1", "rfv")); mt_fok(file_check(WORKDIR"/log.2", "123")); mt_fok(file_check(WORKDIR"/log.3", "456")); mt_fok(file_check(WORKDIR"/log.4", "789")); @@ -956,6 +958,309 @@ static void file_rotate_5_rename_file_halfway(void) ========================================================================== */ +static void file_rotate_directory_deleted(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + mt_fok(el_option(EL_FPATH, WORKDIR"/log")); + + el_puts("qaz"); + el_puts("wsx"); + el_puts("edc"); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + rmdir(WORKDIR); + mt_ferr(el_puts("rfv"), ENOENT); + + mkdir(WORKDIR, 0755); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_directory_reappear_after_delete(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + mt_fok(el_option(EL_FPATH, WORKDIR"/log")); + + el_puts("qaz"); + el_puts("wsx"); + el_puts("edc"); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + rmdir(WORKDIR); + mt_ferr(el_puts("rfv"), ENOENT); + + mkdir(WORKDIR, 0755); + + mt_fok(el_puts("rfv")); + mt_fok(el_puts("tgb")); + mt_fok(el_puts("yhn")); + mt_fok(el_puts("ujm")); + mt_fok(file_check(WORKDIR"/log.0", "rfv")); + mt_fok(file_check(WORKDIR"/log.1", "tgb")); + mt_fok(file_check(WORKDIR"/log.2", "yhn")); + mt_fok(file_check(WORKDIR"/log.3", "ujm")); + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + unlink(WORKDIR"/log.3"); + unlink(WORKDIR"/log.4"); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_write_after_failed_open(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + + rmdir(WORKDIR); + mt_ferr(el_option(EL_FPATH, WORKDIR"/log"), ENOENT); + mkdir(WORKDIR, 0755); + mt_fok(el_puts("qaz")); + mt_fok(file_check(WORKDIR"/log.0", "qaz")); + + unlink(WORKDIR"/log.0"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_write_after_failed_open_to_existing_file(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + + rmdir(WORKDIR); + mt_ferr(el_option(EL_FPATH, WORKDIR"/log"), ENOENT); + mkdir(WORKDIR, 0755); + mt_fok(system("echo -n qaz > \""WORKDIR"/log.0\"")); + mt_fok(system("echo -n ws > \""WORKDIR"/log.1\"")); + mt_fok(el_puts("edc")); + mt_fok(file_check(WORKDIR"/log.0", "qaz")); + mt_fok(file_check(WORKDIR"/log.1", "ws")); + mt_fok(file_check(WORKDIR"/log.2", "edc")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_write_after_failed_open_to_existing_file_with_holes(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + + rmdir(WORKDIR); + mt_ferr(el_option(EL_FPATH, WORKDIR"/log"), ENOENT); + mkdir(WORKDIR, 0755); + mt_fok(system("echo -n qaz > \""WORKDIR"/log.0\"")); + mt_fok(system("echo -n ws > \""WORKDIR"/log.2\"")); + mt_fok(system("echo -n e > \""WORKDIR"/log.4\"")); + mt_fok(el_puts("123")); + mt_fok(el_puts("456")); + + mt_fok(file_check(WORKDIR"/log.0", "ws")); + mt_fok(file_check(WORKDIR"/log.2", "e")); + mt_fok(file_check(WORKDIR"/log.3", "123")); + mt_fok(file_check(WORKDIR"/log.4", "456")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + unlink(WORKDIR"/log.3"); + unlink(WORKDIR"/log.4"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_write_after_failed_open_to_existing_file_with_holes2(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + + rmdir(WORKDIR); + mt_ferr(el_option(EL_FPATH, WORKDIR"/log"), ENOENT); + mkdir(WORKDIR, 0755); + mt_fok(system("echo -n qaz > \""WORKDIR"/log.0\"")); + mt_fok(system("echo -n ws > \""WORKDIR"/log.3\"")); + mt_fok(system("echo -n e > \""WORKDIR"/log.4\"")); + mt_fok(el_puts("123")); + mt_fok(el_puts("456")); + + mt_fok(file_check(WORKDIR"/log.0", "qaz")); + mt_fok(file_check(WORKDIR"/log.1", "ws")); + mt_fok(file_check(WORKDIR"/log.2", "e")); + mt_fok(file_check(WORKDIR"/log.3", "123")); + mt_fok(file_check(WORKDIR"/log.4", "456")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + unlink(WORKDIR"/log.3"); + unlink(WORKDIR"/log.4"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_write_after_failed_open_to_existing_file_with_holes3(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + + rmdir(WORKDIR); + mt_ferr(el_option(EL_FPATH, WORKDIR"/log"), ENOENT); + mkdir(WORKDIR, 0755); + mt_fok(system("echo -n qaz > \""WORKDIR"/log.1\"")); + mt_fok(system("echo -n ws > \""WORKDIR"/log.3\"")); + mt_fok(system("echo -n e > \""WORKDIR"/log.4\"")); + mt_fok(el_puts("123")); + mt_fok(el_puts("456")); + mt_fok(el_puts("789")); + mt_fok(file_check(WORKDIR"/log.0", "ws")); + mt_fok(file_check(WORKDIR"/log.1", "e")); + mt_fok(file_check(WORKDIR"/log.2", "123")); + mt_fok(file_check(WORKDIR"/log.3", "456")); + mt_fok(file_check(WORKDIR"/log.4", "789")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + unlink(WORKDIR"/log.3"); + unlink(WORKDIR"/log.4"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + +static void file_rotate_and_directory_reappear(void) +{ + /* + * mt_prepare_test not running here + */ + + el_init(); + el_option(EL_OUT, EL_OUT_FILE); + el_option(EL_FILE_SYNC_EVERY, 0); + el_option(EL_FROTATE_SIZE, 3); + el_option(EL_FROTATE_NUMBER, 5); + mt_fok(el_option(EL_FPATH, WORKDIR"/log")); + + mt_fok(el_puts("123")); + mt_fok(el_puts("456")); + mt_fok(el_puts("789")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + + rmdir(WORKDIR); + mt_ferr(el_puts(s9), ENOENT); + mkdir(WORKDIR, 0755); + + mt_fok(system("echo -n 123 > \""WORKDIR"/log.0\"")); + mt_fok(system("echo -n 456 > \""WORKDIR"/log.1\"")); + mt_fok(system("echo -n 789 > \""WORKDIR"/log.2\"")); + + mt_fok(el_puts("qaz")); + mt_fok(file_check(WORKDIR"/log.0", "123")); + mt_fok(file_check(WORKDIR"/log.1", "456")); + mt_fok(file_check(WORKDIR"/log.2", "789")); + mt_fok(file_check(WORKDIR"/log.3", "qaz")); + + unlink(WORKDIR"/log.0"); + unlink(WORKDIR"/log.1"); + unlink(WORKDIR"/log.2"); + unlink(WORKDIR"/log.3"); + unlink(WORKDIR"/log.4"); + el_cleanup(); +} + + +/* ========================================================================== + ========================================================================== */ + + static void file_no_dir_for_logs(void) { mt_ferr(el_option(EL_FPATH, "/tmp/i-dont/exist"), ENOENT); @@ -1069,29 +1374,29 @@ static void file_rotate_dir_removed_after_open_then_created_back_again(void) mt_fok(el_puts(s8)); mt_fok(el_puts(s5)); - mt_fok(file_check(WORKDIR"/log.2", s8 s5)); + mt_fok(file_check(WORKDIR"/log.0", s8 s5)); mt_fok(el_puts(s8)); mt_fok(el_puts(s3)); mt_fok(el_puts(s5)); - mt_fok(file_check(WORKDIR"/log.2", s8 s5)); - mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5)); + mt_fok(file_check(WORKDIR"/log.0", s8 s5)); + mt_fok(file_check(WORKDIR"/log.1", s8 s3 s5)); mt_fok(el_puts(s9)); mt_fok(el_puts(s5)); - mt_fok(file_check(WORKDIR"/log.2", s8 s5)); - mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5)); - mt_fok(file_check(WORKDIR"/log.4", s9 s5)); + mt_fok(file_check(WORKDIR"/log.0", s8 s5)); + mt_fok(file_check(WORKDIR"/log.1", s8 s3 s5)); + mt_fok(file_check(WORKDIR"/log.2", s9 s5)); mt_fok(el_puts(s3)); mt_fok(el_puts(s8)); - mt_fok(file_check(WORKDIR"/log.1", s8 s5)); - mt_fok(file_check(WORKDIR"/log.2", s8 s3 s5)); - mt_fok(file_check(WORKDIR"/log.3", s9 s5)); - mt_fok(file_check(WORKDIR"/log.4", s3 s8)); + mt_fok(file_check(WORKDIR"/log.0", s8 s5)); + mt_fok(file_check(WORKDIR"/log.1", s8 s3 s5)); + mt_fok(file_check(WORKDIR"/log.2", s9 s5)); + mt_fok(file_check(WORKDIR"/log.3", s3 s8)); } @@ -1209,7 +1514,7 @@ static void file_rotate_fail(void) mkdir(WORKDIR, 0755); mt_fok(el_puts(s8)); - mt_fok(file_check(WORKDIR"/log.1", s8)); + mt_fok(file_check(WORKDIR"/log.0", s8)); } @@ -1323,6 +1628,14 @@ void el_file_test_group(void) mt_run(file_print_without_setting_file); mt_run(file_write_after_failed_open); mt_run(file_write_after_failed_open_to_existing_file); + mt_run(file_rotate_directory_deleted); + mt_run(file_rotate_directory_reappear_after_delete); + mt_run(file_rotate_write_after_failed_open); + mt_run(file_rotate_write_after_failed_open_to_existing_file); + mt_run(file_rotate_write_after_failed_open_to_existing_file_with_holes); + mt_run(file_rotate_write_after_failed_open_to_existing_file_with_holes2); + mt_run(file_rotate_write_after_failed_open_to_existing_file_with_holes3); + mt_run(file_rotate_and_directory_reappear); mt_prepare_test = &test_prepare; mt_cleanup_test = &test_cleanup; |