coreutils / tests /dd /tests_for_iftruncate.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* Unity required hooks */
void setUp(void) {
/* No setup needed */
}
void tearDown(void) {
/* No teardown needed */
}
/* Helper: write exactly len bytes to fd */
static void write_exact(int fd, const void *buf, size_t len)
{
const char *p = (const char *)buf;
size_t remaining = len;
while (remaining > 0) {
ssize_t w = write(fd, p, remaining);
TEST_ASSERT_MESSAGE(w >= 0, "write() failed during test setup");
if (w == 0) {
TEST_FAIL_MESSAGE("write() returned 0 unexpectedly");
}
p += w;
remaining -= (size_t)w;
}
}
/* Test: shrinking a regular file succeeds and sets the correct size */
static void test_iftruncate_shrink_file(void)
{
FILE *fp = tmpfile();
TEST_ASSERT_NOT_NULL_MESSAGE(fp, "tmpfile() failed");
int fd = fileno(fp);
TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "fileno() failed");
/* Create content: 1000 bytes */
char buf[1000];
memset(buf, 'A', sizeof buf);
write_exact(fd, buf, sizeof buf);
/* Shrink to 100 bytes */
errno = 0;
int rc = iftruncate(fd, (off_t)100);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "iftruncate should succeed when shrinking");
struct stat st;
int s = fstat(fd, &st);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, s, "fstat failed after shrinking");
TEST_ASSERT_EQUAL_INT64_MESSAGE((long long)100, (long long)st.st_size, "File size after shrink is incorrect");
/* Cleanup */
fclose(fp);
}
/* Test: extending a regular file succeeds, sets size, and zeros new bytes */
static void test_iftruncate_extend_file_zero_filled(void)
{
FILE *fp = tmpfile();
TEST_ASSERT_NOT_NULL_MESSAGE(fp, "tmpfile() failed");
int fd = fileno(fp);
TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "fileno() failed");
/* Ensure file initially empty */
struct stat st0;
TEST_ASSERT_EQUAL_INT(0, fstat(fd, &st0));
/* Extend to 4096 bytes */
errno = 0;
int rc = iftruncate(fd, (off_t)4096);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "iftruncate should succeed when extending");
struct stat st;
int s = fstat(fd, &st);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, s, "fstat failed after extending");
TEST_ASSERT_EQUAL_INT64_MESSAGE((long long)4096, (long long)st.st_size, "File size after extend is incorrect");
/* Read the last byte; should be zero */
off_t r = lseek(fd, (off_t)4095, SEEK_SET);
TEST_ASSERT_TRUE_MESSAGE(r == (off_t)4095, "lseek to last byte failed");
unsigned char c = 0xFF;
ssize_t rr = read(fd, &c, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(1, rr, "read of last byte failed");
TEST_ASSERT_EQUAL_UINT8_MESSAGE(0, c, "Extended area is not zero-filled");
/* Cleanup */
fclose(fp);
}
/* Test: invalid file descriptor propagates EBADF and returns -1 */
static void test_iftruncate_invalid_fd(void)
{
errno = 0;
int rc = iftruncate(-1, (off_t)123);
TEST_ASSERT_EQUAL_INT_MESSAGE(-1, rc, "iftruncate should fail for invalid fd");
TEST_ASSERT_EQUAL_INT_MESSAGE(EBADF, errno, "errno should be EBADF for invalid fd");
}
/* Test: negative length returns EINVAL */
static void test_iftruncate_negative_length(void)
{
FILE *fp = tmpfile();
TEST_ASSERT_NOT_NULL_MESSAGE(fp, "tmpfile() failed");
int fd = fileno(fp);
TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "fileno() failed");
errno = 0;
int rc = iftruncate(fd, (off_t)-1);
TEST_ASSERT_EQUAL_INT_MESSAGE(-1, rc, "iftruncate should fail for negative length");
TEST_ASSERT_EQUAL_INT_MESSAGE(EINVAL, errno, "errno should be EINVAL for negative length");
fclose(fp);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_iftruncate_shrink_file);
RUN_TEST(test_iftruncate_extend_file_zero_filled);
RUN_TEST(test_iftruncate_invalid_fd);
RUN_TEST(test_iftruncate_negative_length);
return UNITY_END();
}