#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
+#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
TEST_OPEN = 1 << 15,
TEST_OVERWRITE = 1 << 16,
TEST_INVALID_SYMLINK = 1 << 17,
+ TEST_HIDDEN = 1 << 18,
+ TEST_DOT_HIDDEN = 1 << 19,
};
struct StructureItem
{"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},
+ {"dir_hidden", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, 0},
+ {"dir_hidden/.hidden", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, 0},
+ {"dir_hidden/.a-hidden-file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN},
+ {"dir_hidden/file-in-.hidden1", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN},
+ {"dir_hidden/file-in-.hidden2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN},
};
static gboolean test_suite;
g_assert_no_error (error);
}
+ if ((item.extra_flags & TEST_DOT_HIDDEN) == TEST_DOT_HIDDEN)
+ {
+ gchar *dir, *path, *basename;
+ FILE *f;
+
+ dir = g_path_get_dirname (item.filename);
+ basename = g_path_get_basename (item.filename);
+ path = g_build_filename (test_data, dir, ".hidden", NULL);
+
+ f = fopen (path, "a");
+ fprintf (f, "%s\n", basename);
+ fclose (f);
+
+ g_free (dir);
+ g_free (path);
+ g_free (basename);
+ }
+
g_object_unref (child);
}
gboolean utf8_valid;
gboolean has_attr;
gboolean is_symlink;
+ gboolean is_hidden;
gboolean can_read, can_write;
/* standard::type */
symlink_target = g_file_info_get_symlink_target (info);
g_assert_cmpstr (symlink_target, ==, item.link_to);
}
+
+ /* standard::is-hidden */
+ if ((item.extra_flags & TEST_HIDDEN) == TEST_HIDDEN)
+ {
+ is_hidden =
+ g_file_info_get_attribute_boolean (info,
+ G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
+ g_assert_cmpint (is_hidden, ==, TRUE);
+ }
}
static void
test_attributes (item, info);
g_object_unref (child);
+ g_object_unref (info);
}
/* read and test the pattern file */
g_assert (info != NULL);
size = g_file_info_get_size (info);
g_assert_cmpint (size, ==, PATTERN_FILE_SIZE);
+ g_object_unref (info);
error = NULL;
ins = g_file_read (child, NULL, &error);
info = g_file_enumerator_next_file (enumerator, NULL, &error);
while ((info) && (!error))
{
- descend = g_file_get_child (parent, g_file_info_get_name (info));
+ descend = g_file_enumerator_get_child (enumerator, info);
g_assert (descend != NULL);
relative_path = g_file_get_relative_path (root, descend);
g_assert (relative_path != NULL);
g_object_unref (descend);
error = NULL;
+ g_object_unref (info);
+ g_free (relative_path);
+
info = g_file_enumerator_next_file (enumerator, NULL, &error);
}
g_assert_no_error (error);
error->code, error->message);
g_assert_cmpint (res, ==, TRUE);
g_assert_no_error (error);
+ g_object_unref (os);
}
g_object_unref (child);
}
&error);
g_assert_cmpint (res, ==, TRUE);
g_assert_no_error (error);
+ g_object_unref (input_stream);
}
g_object_unref (child);
}
GError *error;
guint i;
struct StructureItem item;
+ gchar *path;
g_assert (test_data != NULL);
log ("\n");
g_assert (child != NULL);
/* we don't care about result here */
- log (" Deleting %s, path = %s\n", item.filename,
- g_file_get_path (child));
+ path = g_file_get_path (child);
+ log (" Deleting %s, path = %s\n", item.filename, path);
+ g_free (path);
+
error = NULL;
if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
res = g_file_delete (child, NULL, &error);
g_object_unref (root);
}
+static void
+test_make_directory_with_parents (gconstpointer test_data)
+{
+ GFile *root, *child, *grandchild, *greatgrandchild;
+ gboolean res;
+ GError *error = NULL;
+
+ g_assert (test_data != NULL);
+
+ 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);
+
+ child = g_file_get_child (root, "a");
+ grandchild = g_file_get_child (child, "b");
+ greatgrandchild = g_file_get_child (grandchild, "c");
+
+ /* Check that we can successfully make directory hierarchies of
+ * depth 1, 2, or 3
+ */
+ res = g_file_make_directory_with_parents (child, NULL, &error);
+ g_assert_cmpint (res, ==, TRUE);
+ g_assert_no_error (error);
+ res = g_file_query_exists (child, NULL);
+ g_assert_cmpint (res, ==, TRUE);
+
+ g_file_delete (child, NULL, NULL);
+
+ res = g_file_make_directory_with_parents (grandchild, NULL, &error);
+ g_assert_cmpint (res, ==, TRUE);
+ g_assert_no_error (error);
+ res = g_file_query_exists (grandchild, NULL);
+ g_assert_cmpint (res, ==, TRUE);
+
+ g_file_delete (grandchild, NULL, NULL);
+ g_file_delete (child, NULL, NULL);
+
+ res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
+ g_assert_cmpint (res, ==, TRUE);
+ g_assert_no_error (error);
+ res = g_file_query_exists (greatgrandchild, NULL);
+ g_assert_cmpint (res, ==, TRUE);
+
+ g_file_delete (greatgrandchild, NULL, NULL);
+ g_file_delete (grandchild, NULL, NULL);
+ g_file_delete (child, NULL, NULL);
+
+ /* Now test failure by trying to create a directory hierarchy
+ * where a ancestor exists but is read-only
+ */
+
+ /* No obvious way to do this on Windows */
+ if (!posix_compat)
+ goto out;
+
+#ifndef G_PLATFORM_WIN32
+ if (getuid() == 0) /* permissions are ignored for root */
+ goto out;
+#endif
+
+ g_file_make_directory (child, NULL, NULL);
+ g_assert_cmpint (res, ==, TRUE);
+
+ res = g_file_set_attribute_uint32 (child,
+ G_FILE_ATTRIBUTE_UNIX_MODE,
+ S_IRUSR + S_IXUSR, /* -r-x------ */
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, NULL);
+ g_assert_cmpint (res, ==, TRUE);
+
+ res = g_file_make_directory_with_parents (grandchild, NULL, &error);
+ g_assert_cmpint (res, ==, FALSE);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
+ g_clear_error (&error);
+
+ res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
+ g_assert_cmpint (res, ==, FALSE);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
+ g_clear_error (&error);
+
+out:
+ g_object_unref (greatgrandchild);
+ g_object_unref (grandchild);
+ g_object_unref (child);
+ g_object_unref (root);
+}
+
static void
cleanup_dir_recurse (GFile *parent, GFile *root)
g_assert (root != NULL);
- error = NULL;
enumerator =
g_file_enumerate_children (parent, "*",
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
- &error);
+ NULL);
if (! enumerator)
return;
info = g_file_enumerator_next_file (enumerator, NULL, &error);
while ((info) && (!error))
{
- descend = g_file_get_child (parent, g_file_info_get_name (info));
+ descend = g_file_enumerator_get_child (enumerator, info);
g_assert (descend != NULL);
relative_path = g_file_get_relative_path (root, descend);
g_assert (relative_path != NULL);
+ g_free (relative_path);
log (" deleting '%s'\n", g_file_info_get_display_name (info));
g_object_unref (descend);
error = NULL;
+ g_object_unref (info);
+
info = g_file_enumerator_next_file (enumerator, NULL, &error);
}
g_assert_no_error (error);
posix_compat = FALSE;
/* strip all gtester-specific args */
- g_type_init ();
g_test_init (&argc, &argv, NULL);
/* no extra parameters specified, assume we're executed from glib test suite */
return g_test_run ();
}
+ g_option_context_free (context);
/* Write test - clean target directory first */
/* this can be also considered as a test - enumerate + delete */
g_test_add_data_func ("/live-g-file/test_delete", target_path,
test_delete);
+ /* Write test - make_directory_with_parents */
+ if (write_test && (!only_create_struct))
+ g_test_add_data_func ("/live-g-file/test_make_directory_with_parents", target_path,
+ test_make_directory_with_parents);
+
if (write_test || only_create_struct)
g_test_add_data_func ("/live-g-file/final_clean", target_path,
prep_clean_structure);