📄 live-g-file.c
字号:
/* GLib testing framework examples and tests * Copyright (C) 2008 Red Hat, Inc. * Authors: Tomas Bzatek <tbzatek@redhat.com> * * This work is provided "as is"; redistribution and modification * in whole or in part, in any medium, physical or electronic is * permitted without restriction. * * This work is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * In no event shall the authors or contributors be liable for any * direct, indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of substitute * goods or services; loss of use, data, or profits; or business * interruption) however caused and on any theory of liability, whether * in contract, strict liability, or tort (including negligence or * otherwise) arising in any way out of the use of this software, even * if advised of the possibility of such damage. */#include <glib/glib.h>#include <gio/gio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#define DEFAULT_TEST_DIR "testdir_live-g-file"#define PATTERN_FILE_SIZE 0x10000#define TEST_HANDLE_SPECIAL TRUEenum StructureExtraFlags{ TEST_DELETE_NORMAL = 1 << 0, TEST_DELETE_TRASH = 1 << 1, TEST_DELETE_NON_EMPTY = 1 << 2, TEST_DELETE_FAILURE = 1 << 3, TEST_NOT_EXISTS = 1 << 4, TEST_ENUMERATE_FILE = 1 << 5, TEST_NO_ACCESS = 1 << 6, TEST_COPY = 1 << 7, TEST_MOVE = 1 << 8, TEST_COPY_ERROR_RECURSE = 1 << 9, TEST_ALREADY_EXISTS = 1 << 10, TEST_TARGET_IS_FILE = 1 << 11, TEST_CREATE = 1 << 12, TEST_REPLACE = 1 << 13, TEST_APPEND = 1 << 14, TEST_OPEN = 1 << 15, TEST_OVERWRITE = 1 << 16, TEST_INVALID_SYMLINK = 1 << 17,};struct StructureItem{ const char *filename; const char *link_to; GFileType file_type; GFileCreateFlags create_flags; guint32 mode; gboolean handle_special; enum StructureExtraFlags extra_flags;};#define TEST_DIR_NO_ACCESS "dir_no-access"#define TEST_DIR_NO_WRITE "dir_no-write"#define TEST_DIR_TARGET "dir-target"#define TEST_NAME_NOT_EXISTS "not_exists"#define TEST_TARGET_FILE "target-file"static const struct StructureItem sample_struct[] = {/* filename link file_type create_flags mode | handle_special | extra_flags */ {"dir1", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_DELETE_NON_EMPTY | TEST_REPLACE | TEST_OPEN}, {"dir1/subdir", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE | TEST_APPEND}, {"dir2", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_MOVE | TEST_CREATE}, {TEST_DIR_TARGET, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE}, {TEST_DIR_NO_ACCESS, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IWUSR + S_IRGRP + S_IWGRP + S_IROTH + S_IWOTH, 0, TEST_NO_ACCESS | TEST_OPEN}, {TEST_DIR_NO_WRITE, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH, 0, 0}, {TEST_TARGET_FILE, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OPEN}, {"normal_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_CREATE | TEST_OVERWRITE}, {"normal_file-symlink", "normal_file", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_COPY | TEST_OPEN}, {"executable_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRWXU + S_IRWXG + S_IRWXO, 0, TEST_DELETE_TRASH | TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_REPLACE}, {"private_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_PRIVATE, 0, 0, TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_APPEND}, {"normal_file2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OVERWRITE | TEST_REPLACE}, {"readonly_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRUSR + S_IRGRP + S_IROTH, 0, TEST_DELETE_NORMAL | TEST_OPEN}, {"UTF_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_CREATE | TEST_OPEN | TEST_OVERWRITE}, {"dir_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_CREATE}, {"pattern_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_COPY | TEST_OPEN | TEST_APPEND}, {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_NOT_EXISTS | TEST_COPY | TEST_OPEN}, {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_TRASH | TEST_NOT_EXISTS | TEST_MOVE}, {"not_exists2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_CREATE}, {"not_exists3", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_REPLACE}, {"not_exists4", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_APPEND}, {"dir_no-execute/file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_DELETE_FAILURE | TEST_NOT_EXISTS | TEST_OPEN}, {"lost_symlink", "nowhere", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_DELETE_NORMAL | TEST_OPEN | TEST_INVALID_SYMLINK}, };static gboolean write_test;static gboolean verbose;static gboolean posix_compat;#ifdef G_HAVE_ISO_VARARGS#define log(...) if (verbose) g_print (__VA_ARGS__)#elif defined(G_HAVE_GNUC_VARARGS)#define log(msg...) if (verbose) g_print (msg)#else /* no varargs macros */static voidlog (const g_char *format, ...){ va_list args; va_start (args, format); if (verbose) g_print (format, args); va_end (args);}#endifstatic GFile *create_empty_file (GFile * parent, const char *filename, GFileCreateFlags create_flags){ GFile *child; gboolean res; GError *error; GFileOutputStream *outs; child = g_file_get_child (parent, filename); g_assert (child != NULL); error = NULL; outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error); g_assert (error == NULL); g_assert (outs != NULL); error = NULL; res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error); g_object_unref (outs); return child;}static GFile *create_empty_dir (GFile * parent, const char *filename){ GFile *child; gboolean res; GError *error; child = g_file_get_child (parent, filename); g_assert (child != NULL); error = NULL; res = g_file_make_directory (child, NULL, &error); g_assert_cmpint (res, ==, TRUE); g_assert (error == NULL); return child;}static GFile *create_symlink (GFile * parent, const char *filename, const char *points_to){ GFile *child; gboolean res; GError *error; child = g_file_get_child (parent, filename); g_assert (child != NULL); error = NULL; res = g_file_make_symbolic_link (child, points_to, NULL, &error); g_assert_cmpint (res, ==, TRUE); g_assert (error == NULL); return child;}static voidtest_create_structure (gconstpointer test_data){ GFile *root; GFile *child; gboolean res; GError *error; GFileOutputStream *outs; GDataOutputStream *outds; int i; struct StructureItem item; g_assert (test_data != NULL); log ("\n Going to create testing structure in '%s'...\n", (char *) test_data); root = g_file_new_for_commandline_arg ((char *) test_data); g_assert (root != NULL); /* create root directory */ res = g_file_make_directory (root, NULL, NULL); /* don't care about errors here */ /* create any other items */ for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) { item = sample_struct[i]; if ((item.handle_special) || ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))) continue; child = NULL; switch (item.file_type) { case G_FILE_TYPE_REGULAR: log (" Creating file '%s'...\n", item.filename); child = create_empty_file (root, item.filename, item.create_flags); break; case G_FILE_TYPE_DIRECTORY: log (" Creating directory '%s'...\n", item.filename); child = create_empty_dir (root, item.filename); break; case G_FILE_TYPE_SYMBOLIC_LINK: log (" Creating symlink '%s' --> '%s'...\n", item.filename, item.link_to); child = create_symlink (root, item.filename, item.link_to); break; default: break; } g_assert (child != NULL); if ((item.mode > 0) && (posix_compat)) { error = NULL; res = g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE, item.mode, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); g_assert_cmpint (res, ==, TRUE); g_assert (error == NULL); } g_object_unref (child); } /* create a pattern file */ log (" Creating pattern file..."); child = g_file_get_child (root, "pattern_file"); g_assert (child != NULL); error = NULL; outs = g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); g_assert (error == NULL); g_assert (outs != NULL); outds = g_data_output_stream_new (G_OUTPUT_STREAM (outs)); g_assert (outds != NULL); for (i = 0; i < PATTERN_FILE_SIZE; i++) { error = NULL; res = g_data_output_stream_put_byte (outds, i % 256, NULL, &error); g_assert (error == NULL); } error = NULL; res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error); g_assert (error == NULL); g_object_unref (outds); g_object_unref (outs); g_object_unref (child); log (" done.\n"); g_object_unref (root);}static GFile *file_exists (GFile * parent, const char *filename, gboolean * result){ GFile *child; gboolean res; if (result) *result = FALSE; child = g_file_get_child (parent, filename); g_assert (child != NULL); res = g_file_query_exists (child, NULL); if (result) *result = res; return child;}static voidtest_attributes (struct StructureItem item, GFileInfo * info){ GFileType ftype; guint32 mode; const char *name, *display_name, *edit_name, *copy_name, *symlink_target; gboolean utf8_valid; gboolean has_attr; gboolean is_symlink; gboolean can_read, can_write; /* standard::type */ has_attr = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); g_assert_cmpint (has_attr, ==, TRUE); ftype = g_file_info_get_file_type (info); g_assert_cmpint (ftype, !=, G_FILE_TYPE_UNKNOWN); g_assert_cmpint (ftype, ==, item.file_type); /* unix::mode */ if ((item.mode > 0) && (posix_compat)) { mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF; g_assert_cmpint (mode, ==, item.mode); } /* access::can-read */ if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK) { can_read = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ); g_assert_cmpint (can_read, ==, TRUE); } /* access::can-write */ if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)) { can_write = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); g_assert_cmpint (can_write, ==, TRUE); } /* standard::name */ name = g_file_info_get_name (info); g_assert (name != NULL); /* standard::display-name */ display_name = g_file_info_get_display_name (info); g_assert (display_name != NULL); utf8_valid = g_utf8_validate (display_name, -1, NULL); g_assert_cmpint (utf8_valid, ==, TRUE); /* standard::edit-name */ edit_name = g_file_info_get_edit_name (info); if (edit_name) { utf8_valid = g_utf8_validate (edit_name, -1, NULL); g_assert_cmpint (utf8_valid, ==, TRUE); } /* standard::copy-name */ copy_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME); if (copy_name) { utf8_valid = g_utf8_validate (copy_name, -1, NULL); g_assert_cmpint (utf8_valid, ==, TRUE); } /* standard::is-symlink */ if (posix_compat) { is_symlink = g_file_info_get_is_symlink (info); g_assert_cmpint (is_symlink, ==, item.file_type == G_FILE_TYPE_SYMBOLIC_LINK); } /* standard::symlink-target */ if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat)) { symlink_target = g_file_info_get_symlink_target (info); g_assert_cmpstr (symlink_target, ==, item.link_to); }}static voidtest_initial_structure (gconstpointer test_data){ GFile *root; GFile *child; gboolean res; GError *error; GFileInputStream *ins; int i; GFileInfo *info; guint32 size; guchar *buffer; gssize read, total_read; struct StructureItem item; g_assert (test_data != NULL); log ("\n Testing sample structure in '%s'...\n", (char *) test_data); root = g_file_new_for_commandline_arg ((char *) test_data); g_assert (root != NULL); res = g_file_query_exists (root, NULL); g_assert_cmpint (res, ==, TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -