coreutils / tests /head /tests_for_elseek_diagnostic.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 <fcntl.h>
#include <sys/types.h>
/* The function under test is available due to inclusion in same TU:
static void elseek_diagnostic (off_t offset, int whence, char const *filename);
We'll call it directly below. */
/* Helpers to capture stderr output around a single call */
static char* capture_elseek_diagnostic(off_t offset, int whence, const char* filename, int errnum)
{
int saved_stderr = dup(STDERR_FILENO);
if (saved_stderr < 0)
return NULL;
int pipefd[2];
if (pipe(pipefd) != 0) {
close(saved_stderr);
return NULL;
}
/* Redirect stderr to the pipe write end */
if (dup2(pipefd[1], STDERR_FILENO) < 0) {
close(saved_stderr);
close(pipefd[0]);
close(pipefd[1]);
return NULL;
}
close(pipefd[1]); /* Only fd 2 writes to the pipe now */
/* Set errno as desired and invoke function under test */
errno = errnum;
elseek_diagnostic(offset, whence, filename);
/* Flush and restore stderr */
fflush(stderr);
if (dup2(saved_stderr, STDERR_FILENO) < 0) {
/* Even if restore fails, attempt to read captured data */
}
close(saved_stderr);
/* Read all data from the pipe read end */
size_t cap = 256;
size_t len = 0;
char *buf = (char*)malloc(cap);
if (!buf) {
close(pipefd[0]);
return NULL;
}
while (1) {
if (len + 128 > cap) {
size_t new_cap = cap * 2;
char *nb = (char*)realloc(buf, new_cap);
if (!nb) {
free(buf);
close(pipefd[0]);
return NULL;
}
buf = nb;
cap = new_cap;
}
ssize_t n = read(pipefd[0], buf + len, cap - len);
if (n > 0) {
len += (size_t)n;
continue;
}
break; /* EOF or error */
}
close(pipefd[0]);
/* NUL-terminate */
if (len == cap) {
char *nb = (char*)realloc(buf, cap + 1);
if (!nb) {
free(buf);
return NULL;
}
buf = nb;
}
buf[len] = '\0';
return buf;
}
static int contains_substr(const char* haystack, const char* needle)
{
return haystack && needle && strstr(haystack, needle) != NULL;
}
void setUp(void) {
/* no-op */
}
void tearDown(void) {
/* no-op */
}
static void test_elseek_diagnostic_seek_set_message(void)
{
const char *fname = "foo.txt";
off_t off = 123;
char *out = capture_elseek_diagnostic(off, SEEK_SET, fname, EINVAL);
TEST_ASSERT_NOT_NULL(out);
/* Expect the key phrase and the numeric offset */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "cannot seek to offset 123"),
"Expected 'cannot seek to offset 123' in output");
/* Filename should appear (possibly quoted), so just search for raw name */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "foo.txt"),
"Expected filename to appear in output");
free(out);
}
static void test_elseek_diagnostic_seek_cur_message(void)
{
const char *fname = "bar.dat";
off_t off = 456;
char *out = capture_elseek_diagnostic(off, SEEK_CUR, fname, EFBIG);
TEST_ASSERT_NOT_NULL(out);
/* Expect the key phrase and the numeric offset */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "cannot seek to relative offset 456"),
"Expected 'cannot seek to relative offset 456' in output");
/* Filename should appear (possibly quoted) */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "bar.dat"),
"Expected filename to appear in output");
free(out);
}
static void test_elseek_diagnostic_negative_offset_printed(void)
{
const char *fname = "neg.bin";
off_t off = -5;
char *out = capture_elseek_diagnostic(off, SEEK_CUR, fname, EINVAL);
TEST_ASSERT_NOT_NULL(out);
/* Ensure the negative value is printed correctly */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "cannot seek to relative offset -5"),
"Expected negative offset '-5' to appear correctly");
/* Filename presence */
TEST_ASSERT_TRUE_MESSAGE(contains_substr(out, "neg.bin"),
"Expected filename to appear in output");
free(out);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_elseek_diagnostic_seek_set_message);
RUN_TEST(test_elseek_diagnostic_seek_cur_message);
RUN_TEST(test_elseek_diagnostic_negative_offset_printed);
return UNITY_END();
}