diff --git a/gio/tests/file.c b/gio/tests/file.c index e8b2d4245..c09409c2a 100644 --- a/gio/tests/file.c +++ b/gio/tests/file.c @@ -2928,6 +2928,144 @@ test_load_bytes_async (void) g_main_loop_unref (data.main_loop); } +static const gsize testfile_4gb_size = ((gsize) 1 << 32) + (1 << 16); /* 4GB + a bit */ + +/* @filename will be modified as per g_mkstemp() */ +static gboolean +create_testfile_4gb_or_skip (char *filename) +{ + GError *error = NULL; + int fd; + int ret; + + fd = g_mkstemp (filename); + g_assert_cmpint (fd, !=, -1); + ret = ftruncate (fd, testfile_4gb_size); + g_clear_fd (&fd, &error); + g_assert_no_error (error); + if (ret == 1) + { + g_test_skip ("Could not create testfile >4GB"); + g_assert_no_errno (g_unlink (filename)); + return FALSE; + } + + return TRUE; +} + +static void +check_testfile_4gb_contents (const char *data, + gsize len) +{ + gsize i; + + g_assert_nonnull (data); + g_assert_cmpuint (testfile_4gb_size, ==, len); + + for (i = 0; i < testfile_4gb_size; i++) + { + if (data[i] != 0) + break; + } + g_assert_cmpint (i, ==, testfile_4gb_size); +} + +static void +test_load_contents_4gb (void) +{ + char filename[] = "g_file_load_contents_4gb_XXXXXX"; + GError *error = NULL; + gboolean result; + char *data; + gsize len; + GFile *file; + + if (!create_testfile_4gb_or_skip (filename)) + return; + + file = g_file_new_for_path (filename); + result = g_file_load_contents (file, NULL, &data, &len, NULL, &error); + g_assert_no_error (error); + g_assert_true (result); + + check_testfile_4gb_contents (data, len); + + g_file_delete (file, NULL, NULL); + + g_free (data); + g_object_unref (file); +} + +static void +load_contents_4gb_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_out = user_data; + + g_assert (*result_out == NULL); + *result_out = g_object_ref (result); + + g_main_context_wakeup (NULL); +} + +static void +test_load_contents_4gb_async (void) +{ + char filename[] = "g_file_load_contents_4gb_async_XXXXXX"; + GFile *file; + GAsyncResult *async_result = NULL; + GError *error = NULL; + char *data; + gsize len; + gboolean ret; + + if (!create_testfile_4gb_or_skip (filename)) + return; + + file = g_file_new_for_path (filename); + g_file_load_contents_async (file, NULL, load_contents_4gb_cb, &async_result); + + while (async_result == NULL) + g_main_context_iteration (NULL, TRUE); + + ret = g_file_load_contents_finish (file, async_result, &data, &len, NULL, &error); + g_assert_no_error (error); + g_assert_true (ret); + + check_testfile_4gb_contents (data, len); + + g_file_delete (file, NULL, NULL); + + g_free (data); + g_object_unref (async_result); + g_object_unref (file); +} + +static void +test_load_bytes_4gb (void) +{ + char filename[] = "g_file_load_bytes_4gb_XXXXXX"; + GError *error = NULL; + GBytes *bytes; + GFile *file; + + if (!create_testfile_4gb_or_skip (filename)) + return; + + file = g_file_new_for_path (filename); + bytes = g_file_load_bytes (file, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_true (bytes); + + check_testfile_4gb_contents (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); + + g_file_delete (file, NULL, NULL); + + g_bytes_unref (bytes); + g_object_unref (file); +} + static void test_writev_helper (GOutputVector *vectors, gsize n_vectors, @@ -4230,6 +4368,9 @@ main (int argc, char *argv[]) g_test_add_func ("/file/measure-async", test_measure_async); g_test_add_func ("/file/load-bytes", test_load_bytes); g_test_add_func ("/file/load-bytes-async", test_load_bytes_async); + g_test_add_func ("/file/load-bytes-4gb", test_load_bytes_4gb); + g_test_add_func ("/file/load-contents-4gb", test_load_contents_4gb); + g_test_add_func ("/file/load-contents-4gb-async", test_load_contents_4gb_async); g_test_add_func ("/file/writev", test_writev); g_test_add_func ("/file/writev/no-bytes-written", test_writev_no_bytes_written); g_test_add_func ("/file/writev/no-vectors", test_writev_no_vectors);