summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCauĂȘ Baasch de Souza <cauebs@pm.me>2020-06-30 22:24:25 -0300
committerFelipe Magno de Almeida <felipe@expertise.dev>2020-12-15 16:10:26 -0300
commitedb195cfd28b0c09bda888d2f05d8fc808a5cd2f (patch)
tree7b7ce78218dcb8d95b4eaa6baec64bc3c6a3a9e1
parent38a94040a2409a0856cee918075cf555f8c7b885 (diff)
downloadefl-edb195cfd28b0c09bda888d2f05d8fc808a5cd2f.tar.gz
evil: Implement ftruncate
Create POSIX-compliant ftruncate with tests.
-rw-r--r--src/lib/evil/evil_unistd.c20
-rw-r--r--src/lib/evil/evil_unistd.h1
-rw-r--r--src/tests/evil/evil_test_unistd.c33
3 files changed, 54 insertions, 0 deletions
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 <process.h> // 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 <stdlib.h>
#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
# define WIN32_LEAN_AND_MEAN
# include <winsock2.h>
@@ -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);
}