xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit ede1101042d459db02bfbe3eae76c72d4b24f673

Test and document fix of undo chmod losing 8th bit
That is owner's read permission was always lost on undo.
Author: xaizek
Author date (UTC): 2026-01-13 14:01
Committer name: xaizek
Committer date (UTC): 2026-01-13 15:29
Parent(s): a4620de4964aff0ba1c047b193fd78389b32a99f
Signing key: 99DC5E4DB05F6BE2
Tree: ec8e15c66137d0f8544dc04392de1b7448e8c44a
File Lines added Lines deleted
ChangeLog 3 0
tests/commands/misc_fops.c 72 0
File ChangeLog changed (mode: 100644) (index ec3030e04..2302e8e9a)
177 177 Fixed a crash if GLib didn't return a file type. Patch by Jan Fixed a crash if GLib didn't return a file type. Patch by Jan
178 178 Palus (a.k.a. jpalus). Palus (a.k.a. jpalus).
179 179
180 Fixed undoing of chmod operation not restoring owner's read permission.
181 Thanks to aleksejrs. Patch by Kirill Rekhov.
182
180 183 0.14-beta to 0.14 (2025-02-08) 0.14-beta to 0.14 (2025-02-08)
181 184
182 185 Improved documentation on zh/zl menu keys a bit. Improved documentation on zh/zl menu keys a bit.
File tests/commands/misc_fops.c changed (mode: 100644) (index 9bc4bc12c..5dbb34120)
10 10
11 11 #include "../../src/compat/fs_limits.h" #include "../../src/compat/fs_limits.h"
12 12 #include "../../src/compat/os.h" #include "../../src/compat/os.h"
13 #include "../../src/engine/keys.h"
14 #include "../../src/modes/modes.h"
13 15 #include "../../src/ui/statusbar.h" #include "../../src/ui/statusbar.h"
14 16 #include "../../src/ui/ui.h" #include "../../src/ui/ui.h"
15 17 #include "../../src/utils/fs.h" #include "../../src/utils/fs.h"
16 18 #include "../../src/utils/path.h" #include "../../src/utils/path.h"
17 19 #include "../../src/cmd_core.h" #include "../../src/cmd_core.h"
18 20 #include "../../src/filelist.h" #include "../../src/filelist.h"
21 #include "../../src/ops.h"
19 22 #include "../../src/registers.h" #include "../../src/registers.h"
23 #include "../../src/undo.h"
24
25 static OpsResult exec_func(OPS op, void *data, const char *src,
26 const char *dst);
27 static int op_avail(OPS op);
20 28
21 29 static char *saved_cwd; static char *saved_cwd;
22 30
 
... ... TEST(chmod_works, IF(not_windows))
124 132 assert_success(remove(path)); assert_success(remove(path));
125 133 } }
126 134
135 TEST(chmod_undo_restores_all_bits, IF(not_windows))
136 {
137 char path[PATH_MAX + 1];
138
139 modes_init();
140
141 undo_teardown();
142
143 static int max_undo_levels = 1;
144 un_init(&exec_func, &op_avail, NULL, &max_undo_levels);
145
146 assert_success(chdir(sandbox));
147
148 strcpy(lwin.curr_dir, sandbox);
149 append_view_entry(&lwin, "file");
150
151 snprintf(path, sizeof(path), "%s/file", sandbox);
152 create_file(path);
153 assert_success(os_chmod(path, 0777));
154
155 populate_dir_list(&lwin, /*reload=*/1);
156 #ifndef _WIN32
157 /* Can't just assume 0777 because of umask. */
158 int expected_mode = lwin.dir_entry[0].mode & 0777;
159 #endif
160
161 (void)cmds_dispatch("chmod 000", &lwin, CIT_COMMAND);
162
163 populate_dir_list(&lwin, /*reload=*/1);
164 #ifndef _WIN32
165 assert_int_equal(0000, lwin.dir_entry[0].mode & 0777);
166 #endif
167
168 (void)cmds_dispatch("normal u", &lwin, CIT_COMMAND);
169
170 populate_dir_list(&lwin, /*reload=*/1);
171 #ifndef _WIN32
172 assert_int_equal(expected_mode, lwin.dir_entry[0].mode & 0777);
173 #endif
174
175 snprintf(path, sizeof(path), "%s/file", sandbox);
176 remove_file(path);
177
178 vle_keys_reset();
179 }
180
127 181 TEST(putting_files_works) TEST(putting_files_works)
128 182 { {
129 183 char path[PATH_MAX + 1]; char path[PATH_MAX + 1];
 
... ... TEST(zero_count_is_rejected)
190 244 assert_string_equal(expected, ui_sb_last()); assert_string_equal(expected, ui_sb_last());
191 245 } }
192 246
247 static OpsResult
248 exec_func(OPS op, void *data, const char *src, const char *dst)
249 {
250 return perform_operation(op, NULL, data, src, dst);
251 }
252
253 static int
254 op_avail(OPS op)
255 {
256 #ifndef _WIN32
257 if(op == OP_CHMOD)
258 {
259 return 1;
260 }
261 #endif
262 return 0;
263 }
264
193 265 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
194 266 /* vim: set cinoptions+=t0 filetype=c : */ /* vim: set cinoptions+=t0 filetype=c : */
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master