#include <stic.h> #include <unistd.h> /* rmdir() unlink() */ #include <limits.h> /* INT_MAX */ #include <string.h> /* strcat() */ #include <test-utils.h> #include "../../src/compat/fs_limits.h" #include "../../src/compat/os.h" #include "../../src/cfg/config.h" #include "../../src/ui/ui.h" #include "../../src/utils/fs.h" #include "../../src/utils/path.h" #include "../../src/filelist.h" #include "../../src/fops_common.h" #include "../../src/fops_misc.h" #include "../../src/registers.h" #include "../../src/trash.h" static char options_prompt_abort(const struct custom_prompt_t *details); static char *saved_cwd; static int prompt_invocations; SETUP() { saved_cwd = save_cwd(); assert_success(chdir(SANDBOX_PATH)); view_setup(&lwin); assert_non_null(get_cwd(lwin.curr_dir, sizeof(lwin.curr_dir))); view_setup(&rwin); cfg.use_trash = 0; } TEARDOWN() { view_teardown(&lwin); view_teardown(&rwin); restore_cwd(saved_cwd); } TEST(marked_files_are_removed_permanently) { for(cfg.use_system_calls = 0; cfg.use_system_calls < 2; ++cfg.use_system_calls) { int bg; for(bg = 0; bg < 2; ++bg) { create_file("a"); create_file("b"); populate_dir_list(&lwin, 0); lwin.dir_entry[0].marked = 1; if(!bg) { (void)fops_delete(&lwin, '\0', 0); } else { (void)fops_delete_bg(&lwin, 0); wait_for_bg(); } assert_failure(unlink("a")); assert_success(unlink("b")); } } } TEST(files_in_trash_are_not_removed_to_trash) { cfg.use_trash = 1; trash_set_specs(lwin.curr_dir); create_file("a"); populate_dir_list(&lwin, 0); lwin.dir_entry[0].marked = 1; (void)fops_delete(&lwin, '\0', 1); (void)fops_delete_bg(&lwin, 1); wait_for_bg(); assert_success(unlink("a")); } TEST(trash_is_not_removed_to_trash) { cfg.use_trash = 1; trash_set_specs("trash"); create_dir("trash"); populate_dir_list(&lwin, 0); lwin.dir_entry[0].marked = 1; (void)fops_delete(&lwin, '\0', 1); (void)fops_delete_bg(&lwin, 1); wait_for_bg(); assert_success(rmdir("trash")); } TEST(marked_files_are_removed_to_trash) { char trash_dir[PATH_MAX + 1]; make_abs_path(trash_dir, sizeof(trash_dir), SANDBOX_PATH, "trash", saved_cwd); cfg.use_trash = 1; trash_set_specs(trash_dir); assert_success(rmdir("trash")); for(cfg.use_system_calls = 0; cfg.use_system_calls < 2; ++cfg.use_system_calls) { int bg; for(bg = 0; bg < 2; ++bg) { create_dir("trash"); create_file("a"); create_file("b"); populate_dir_list(&lwin, 0); lwin.dir_entry[2].marked = 1; restore_cwd(saved_cwd); saved_cwd = save_cwd(); assert_success(chdir(SANDBOX_PATH)); if(!bg) { (void)fops_delete(&lwin, 'x', 1); } else { (void)fops_delete_bg(&lwin, 1); wait_for_bg(); } assert_success(unlink("a")); assert_failure(unlink("b")); assert_success(unlink("trash/000_b")); assert_success(rmdir("trash")); } } } TEST(nested_file_is_removed) { cfg.use_trash = 1; trash_set_specs("trash"); for(cfg.use_system_calls = 0; cfg.use_system_calls < 2; ++cfg.use_system_calls) { int bg; for(bg = 0; bg < 2; ++bg) { int to_trash; for(to_trash = 0; to_trash < 2; ++to_trash) { if(to_trash) { create_dir("trash"); } create_dir("dir"); create_file("dir/a"); create_file("dir/b"); make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "", saved_cwd); assert_success(flist_load_tree(&lwin, lwin.curr_dir, INT_MAX)); lwin.dir_entry[2].marked = 1; if(!bg) { (void)fops_delete(&lwin, 'x', to_trash); } else { (void)fops_delete_bg(&lwin, to_trash); wait_for_bg(); } restore_cwd(saved_cwd); saved_cwd = save_cwd(); assert_success(chdir(SANDBOX_PATH)); assert_success(unlink("dir/a")); assert_failure(unlink("dir/b")); assert_success(rmdir("dir")); if(to_trash) { assert_success(unlink("trash/000_b")); assert_success(rmdir("trash")); } } } } } TEST(files_in_trash_are_not_removed_to_trash_in_cv) { cfg.use_trash = 1; strcat(lwin.curr_dir, "/dir"); trash_set_specs(lwin.curr_dir); remove_last_path_component(lwin.curr_dir); create_file("dir/a"); flist_custom_start(&lwin, "test"); flist_custom_add(&lwin, "dir"); flist_custom_add(&lwin, "dir/a"); assert_true(flist_custom_finish(&lwin, CV_REGULAR, 0) == 0); lwin.dir_entry[1].marked = 1; lwin.list_pos = 1; (void)fops_delete(&lwin, '\0', 1); (void)fops_delete_bg(&lwin, 1); wait_for_bg(); assert_success(unlink("dir/a")); assert_success(rmdir("dir")); } TEST(files_in_trash_are_not_removed_to_trash_in_tree) { cfg.use_trash = 1; trash_set_specs("dir"); create_dir("dir"); create_file("dir/a"); assert_success(flist_load_tree(&lwin, ".", INT_MAX)); lwin.dir_entry[1].marked = 1; lwin.list_pos = 1; (void)fops_delete(&lwin, '\0', 1); (void)fops_delete_bg(&lwin, 1); wait_for_bg(); assert_success(unlink("dir/a")); assert_success(rmdir("dir")); } TEST(trash_is_not_checked_on_permanent_bg_remove) { assert_success(trash_set_specs(lwin.curr_dir)); create_dir("dir"); populate_dir_list(&lwin, 0); lwin.dir_entry[0].marked = 1; (void)fops_delete_bg(&lwin, 0); wait_for_bg(); assert_failure(rmdir("dir")); } TEST(empty_directory_is_removed) { /* Make sure I/O notification is registered. */ fops_init(NULL, NULL); for(cfg.use_system_calls = 0; cfg.use_system_calls < 2; ++cfg.use_system_calls) { int bg; for(bg = 0; bg < 2; ++bg) { create_dir("dir"); populate_dir_list(&lwin, 0); lwin.dir_entry[0].marked = 1; if(!bg) { (void)fops_delete(&lwin, 'x', 0); } else { (void)fops_delete_bg(&lwin, 0); wait_for_bg(); } assert_failure(rmdir("dir")); } } } TEST(aborting_file_deletion_aborts_remaining_files, IF(regular_unix_user)) { create_dir("ro"); create_file("ro/a"); create_file("ro/b"); assert_success(os_chmod("ro", 0555)); prompt_invocations = 0; fops_init(/*line_func=*/NULL, &options_prompt_abort); flist_custom_start(&lwin, "test"); flist_custom_add(&lwin, "ro/a"); flist_custom_add(&lwin, "ro/b"); assert_true(flist_custom_finish(&lwin, CV_REGULAR, 0) == 0); assert_int_equal(2, lwin.list_rows); lwin.dir_entry[0].marked = 1; lwin.dir_entry[1].marked = 1; (void)fops_delete(&lwin, /*reg=*/'\0', /*use_trash=*/0); assert_int_equal(1, prompt_invocations); assert_success(os_chmod("ro", 0777)); remove_file("ro/a"); remove_file("ro/b"); remove_dir("ro"); } static char options_prompt_abort(const struct custom_prompt_t *details) { ++prompt_invocations; return 'a'; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set cinoptions+=t0 filetype=c : */