#include "unity/unity.h" #include "zlib.h" #include #include #include #include #ifdef _WIN32 # include # include # define CLOSE _close #else # include # include # include # include # define CLOSE close #endif /* Helper: create a temporary read/write file descriptor. On POSIX, use mkstemp and unlink it immediately. On Windows, use tmpfile and duplicate its descriptor so fclose won't impact it. */ static int make_temp_fd(void) { #ifdef _WIN32 FILE *fp = tmpfile(); TEST_ASSERT_NOT_NULL_MESSAGE(fp, "tmpfile() failed"); int fd = _dup(_fileno(fp)); /* Close the FILE*, leaving the duplicated fd open */ fclose(fp); TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "_dup() failed to duplicate file descriptor"); return fd; #else char templ[] = "gzdopen_test_XXXXXX"; int fd = mkstemp(templ); TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "mkstemp() failed to create temporary file"); /* Unlink so the file is removed after close */ unlink(templ); return fd; #endif } void setUp(void) { /* Setup code here, or leave empty */ } void tearDown(void) { /* Cleanup code here, or leave empty */ } /* fd == -1 should return NULL */ void test_gzdopen_fd_invalid_returns_null(void) { gzFile gz = gzdopen(-1, "rb"); TEST_ASSERT_NULL(gz); } /* Mode lacking 'r', 'w', or 'a' should return NULL */ void test_gzdopen_mode_missing_rwab_returns_null(void) { int fd = make_temp_fd(); gzFile gz = gzdopen(fd, "b"); TEST_ASSERT_NULL(gz); /* Close the fd ourselves since gzdopen failed */ CLOSE(fd); } /* Mode containing '+' should return NULL */ void test_gzdopen_mode_with_plus_returns_null(void) { int fd = make_temp_fd(); gzFile gz = gzdopen(fd, "w+"); TEST_ASSERT_NULL(gz); CLOSE(fd); } /* Valid read mode should succeed */ void test_gzdopen_read_mode_returns_valid_handle(void) { int fd = make_temp_fd(); gzFile gz = gzdopen(fd, "rb"); TEST_ASSERT_NOT_NULL(gz); /* gzclose should succeed and will close the fd */ int rc = gzclose(gz); TEST_ASSERT_EQUAL_INT(0, rc); } /* Valid append mode should succeed */ void test_gzdopen_append_mode_returns_valid_handle(void) { int fd = make_temp_fd(); gzFile gz = gzdopen(fd, "ab"); TEST_ASSERT_NOT_NULL(gz); int rc = gzclose(gz); TEST_ASSERT_EQUAL_INT(0, rc); } /* Forcing transparent read ('T') in read mode should fail */ void test_gzdopen_read_mode_with_T_returns_null(void) { int fd = make_temp_fd(); gzFile gz = gzdopen(fd, "rbT"); TEST_ASSERT_NULL(gz); CLOSE(fd); } /* Valid write mode with options should succeed */ void test_gzdopen_write_mode_with_options_returns_valid_handle(void) { int fd = make_temp_fd(); /* compression level '9' and strategy 'h' (Huffman only) in mode string */ gzFile gz = gzdopen(fd, "wb9h"); TEST_ASSERT_NOT_NULL(gz); int rc = gzclose(gz); TEST_ASSERT_EQUAL_INT(0, rc); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_gzdopen_fd_invalid_returns_null); RUN_TEST(test_gzdopen_mode_missing_rwab_returns_null); RUN_TEST(test_gzdopen_mode_with_plus_returns_null); RUN_TEST(test_gzdopen_read_mode_returns_valid_handle); RUN_TEST(test_gzdopen_append_mode_returns_valid_handle); RUN_TEST(test_gzdopen_read_mode_with_T_returns_null); RUN_TEST(test_gzdopen_write_mode_with_options_returns_valid_handle); return UNITY_END(); }