From edb195cfd28b0c09bda888d2f05d8fc808a5cd2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Baasch=20de=20Souza?= Date: Tue, 30 Jun 2020 22:24:25 -0300 Subject: evil: Implement ftruncate Create POSIX-compliant ftruncate with tests. --- src/lib/evil/evil_unistd.c | 20 ++++++++++++++++++++ src/lib/evil/evil_unistd.h | 1 + src/tests/evil/evil_test_unistd.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/lib/evil/evil_unistd.c b/src/lib/evil/evil_unistd.c index 5c065bee9a..5f1d3aea39 100644 --- a/src/lib/evil/evil_unistd.c +++ b/src/lib/evil/evil_unistd.c @@ -25,6 +25,26 @@ execvp(const char *file, char *const argv[]) LONGLONG _evil_time_freq; LONGLONG _evil_time_count; +EVIL_API int +ftruncate(int fd, off_t size) +{ + HANDLE file = (HANDLE)_get_osfhandle(fd); + + if (SetFilePointer(file, (LONG)size, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + { + _set_errno(EINVAL); + return -1; + } + + if (!SetEndOfFile(file)) + { + _set_errno(EIO); + return -1; + } + + return 0; +} + /* * Time related functions * diff --git a/src/lib/evil/evil_unistd.h b/src/lib/evil/evil_unistd.h index 24c6d7c88f..4e74ceedff 100644 --- a/src/lib/evil/evil_unistd.h +++ b/src/lib/evil/evil_unistd.h @@ -23,6 +23,7 @@ #include // for _execvp (but not execvp), getpid #undef execvp EVIL_API int execvp(const char *file, char *const argv[]); +EVIL_API int ftruncate(int fd, off_t size); /* Values for the second argument to access. These may be OR'd together. */ #define R_OK 4 /* Test for read permission. */ diff --git a/src/tests/evil/evil_test_unistd.c b/src/tests/evil/evil_test_unistd.c index c5f56d0fc0..f96a714a06 100644 --- a/src/tests/evil/evil_test_unistd.c +++ b/src/tests/evil/evil_test_unistd.c @@ -22,6 +22,8 @@ #include #include +#include +#include # define WIN32_LEAN_AND_MEAN # include @@ -109,7 +111,38 @@ EFL_START_TEST(evil_unistd_pipe) } EFL_END_TEST +EFL_START_TEST(evil_unistd_ftruncate) +{ + FILE* f = fopen("foo.txt", "wb"); + ck_assert(f); + fseek(f, 0L, SEEK_END); + ck_assert_int_eq(ftell(f), 0); + + int fd = fileno(f); + int ret; + + ret = ftruncate(fd, 16L); + ck_assert(ret >= 0); + fseek(f, 0L, SEEK_END); + ck_assert_int_eq(ftell(f), 16); + + ret = ftruncate(fd, 8L); + ck_assert(ret >= 0); + fseek(f, 0L, SEEK_END); + ck_assert_int_eq(ftell(f), 8); + + ret = ftruncate(fd, -8L); + ck_assert(ret < 0); + ck_assert_int_eq(errno, EINVAL); + fseek(f, 0L, SEEK_END); + ck_assert_int_eq(ftell(f), 8); + + fclose(f); +} +EFL_END_TEST + void evil_test_unistd(TCase *tc) { tcase_add_test(tc, evil_unistd_pipe); + tcase_add_test(tc, evil_unistd_ftruncate); } -- cgit v1.2.1