diff --git a/util/compressutils.c b/util/compressutils.c index efd8e88c..0a64d4e2 100644 --- a/util/compressutils.c +++ b/util/compressutils.c @@ -304,3 +304,35 @@ gvm_gzip_open_file_reader (const char *path) FILE *file = fopencookie (gz_file, "r", io_functions); return file; } + +/** + * @brief Opens a gzip file as a FILE* stream for reading and decompression. + * + * @param[in] fd File descriptor of the gzip file to open. + * + * @return The FILE* on success, NULL otherwise. + */ +FILE * +gvm_gzip_open_file_reader_fd (int fd) +{ + static cookie_io_functions_t io_functions = { + .read = gz_file_read, + .write = NULL, + .seek = NULL, + .close = gz_file_close, + }; + + if (fd < 0) + { + return NULL; + } + + gzFile gz_file = gzdopen (fd, "r"); + if (gz_file == NULL) + { + return NULL; + } + + FILE *file = fopencookie (gz_file, "r", io_functions); + return file; +} diff --git a/util/compressutils.h b/util/compressutils.h index f319952f..f5debd75 100644 --- a/util/compressutils.h +++ b/util/compressutils.h @@ -25,4 +25,7 @@ gvm_uncompress (const void *, unsigned long, unsigned long *); FILE * gvm_gzip_open_file_reader (const char *); +FILE * +gvm_gzip_open_file_reader_fd (int); + #endif /* not _GVM_COMPRESSUTILS_H */ diff --git a/util/compressutils_tests.c b/util/compressutils_tests.c index 4731cc13..b0ed30a6 100644 --- a/util/compressutils_tests.c +++ b/util/compressutils_tests.c @@ -7,6 +7,7 @@ #include #include +#include Describe (compressutils); BeforeEach (compressutils) @@ -79,6 +80,30 @@ Ensure (compressutils, can_uncompress_using_reader) assert_that (fclose (stream), is_equal_to (0)); } +Ensure (compressutils, can_uncompress_using_fd_reader) +{ + const char *testdata = "TEST-12345-12345-TEST"; + size_t compressed_len; + char *compressed = + gvm_compress_gzipheader (testdata, strlen (testdata) + 1, &compressed_len); + + char compressed_filename[35] = "/tmp/gvm_gzip_test_XXXXXX"; + int compressed_fd = mkstemp (compressed_filename); + write (compressed_fd, compressed, compressed_len); + close (compressed_fd); + + compressed_fd = open (compressed_filename, O_RDONLY); + + FILE *stream = gvm_gzip_open_file_reader_fd (compressed_fd); + assert_that (stream, is_not_null); + + gchar *uncompressed = g_malloc0 (30); + fread (uncompressed, 1, 30, stream); + assert_that (uncompressed, is_equal_to_string (testdata)); + + assert_that (fclose (stream), is_equal_to (0)); +} + /* Test suite. */ int main (int argc, char **argv) @@ -92,9 +117,10 @@ main (int argc, char **argv) add_test_with_context (suite, compressutils, can_compress_and_uncompress_with_header); add_test_with_context (suite, compressutils, can_uncompress_using_reader); + add_test_with_context (suite, compressutils, can_uncompress_using_fd_reader); if (argc > 1) return run_single_test (suite, argv[1], create_text_reporter ()); return run_test_suite (suite, create_text_reporter ()); -} \ No newline at end of file +}