File size: 3,506 Bytes
e996a55 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #include "unity/unity.h"
#include "zlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# define CLOSE _close
#else
# include <unistd.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>
# 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();
} |