From 6dc28ff5673c86d8d6042b47538c2f66e7726717 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 3 Mar 2026 22:41:14 -0600 Subject: [PATCH] Bugfix: Invalid seeked value on failure in f_file_seek(). The `lseek()` can return a negative value. Use a local variable to get the `lseek()` value. This then allows for the `seeked` to be NULL. Change the `seeked` parameter to be optional and when set to NULL then it is not assigned. This neither breaks API nor ABI. The `seeked` value is only assigned when the result is `-1`. The POSIX standard is inconsistent about negative return values. In the case of `lseek()`, only `-1` is technically an error. --- level_0/f_file/c/file.c | 7 ++++--- level_0/f_file/c/file.h | 4 +++- level_0/f_file/data/documentation/man/man3/f_file_seek.3 | 1 + level_0/f_file/tests/unit/c/test-file-seek.c | 6 ------ 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/level_0/f_file/c/file.c b/level_0/f_file/c/file.c index cbd55e110..f4fa12b20 100644 --- a/level_0/f_file/c/file.c +++ b/level_0/f_file/c/file.c @@ -1823,14 +1823,13 @@ extern "C" { f_status_t f_file_seek(const f_file_t file, const int whence, const off_t offset, off_t * const seeked) { #ifndef _di_level_0_parameter_checking_ if (whence < 0) return F_status_set_error(F_parameter); - if (!seeked) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ if (file.id == -1) return F_file_descriptor_not; - *seeked = lseek(file.id, offset, whence); + const int result = lseek(file.id, offset, whence); - if (*seeked < 0) { + if (result == -1) { if (errno == EBADF) return F_status_set_error(F_file_descriptor_not); if (errno == EINVAL) return F_status_set_error(F_parameter); if (errno == ENXIO) return F_status_set_error(F_bound_not); @@ -1840,6 +1839,8 @@ extern "C" { return F_status_set_error(F_failure); } + *seeked = result; + return F_okay; } #endif // _di_f_file_seek_ diff --git a/level_0/f_file/c/file.h b/level_0/f_file/c/file.h index 5ca80bc14..151a108b1 100644 --- a/level_0/f_file/c/file.h +++ b/level_0/f_file/c/file.h @@ -1964,9 +1964,11 @@ extern "C" { * @param offset * The offset to use, based off of whence. * @param seeked - * This gets update to represent the total amount seeked. + * (optional) This gets update to represent the total amount seeked. * To be compared against offset. * + * Set to NULL to not use. + * * @return * F_okay on success. * F_file_descriptor_not if file.id is -1. diff --git a/level_0/f_file/data/documentation/man/man3/f_file_seek.3 b/level_0/f_file/data/documentation/man/man3/f_file_seek.3 index e3f0c55e2..e535195da 100644 --- a/level_0/f_file/data/documentation/man/man3/f_file_seek.3 +++ b/level_0/f_file/data/documentation/man/man3/f_file_seek.3 @@ -33,6 +33,7 @@ The offset to use, based off of whence. .TP .B seeked This gets update to represent the total amount seeked. To be compared against offset. +(optional) This gets update to represent the total amount seeked. To be compared against offset. Set to NULL to not use. .SH STRUCTURES .SS "" diff --git a/level_0/f_file/tests/unit/c/test-file-seek.c b/level_0/f_file/tests/unit/c/test-file-seek.c index 024170552..39589a004 100644 --- a/level_0/f_file/tests/unit/c/test-file-seek.c +++ b/level_0/f_file/tests/unit/c/test-file-seek.c @@ -56,12 +56,6 @@ void test__f_file_seek__parameter_checking(void **state) { assert_int_equal(status, F_status_set_error(F_parameter)); } - - { - const f_status_t status = f_file_seek(file, 0, 0, 0); - - assert_int_equal(status, F_status_set_error(F_parameter)); - } } void test__f_file_seek__returns_file_descriptor_not(void **state) { -- 2.47.3