summaryrefslogtreecommitdiff
path: root/Src/Modules/files.c
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2020-02-14 01:58:20 +0100
committerAxel Beckert <abe@deuxchevaux.org>2020-02-14 01:58:20 +0100
commitbfc5d42735c1660263904ec5254cccf539a0a458 (patch)
tree9bbb81b4a53941427e6f9e65ae55027d9108df8c /Src/Modules/files.c
parent74561cc51b8867e43cb2937ab2edfb36e2a829bf (diff)
parent643de931640e01aa246723d2038328ef33737965 (diff)
downloadzsh-bfc5d42735c1660263904ec5254cccf539a0a458.tar.gz
zsh-bfc5d42735c1660263904ec5254cccf539a0a458.zip
Merge tag 'zsh-5.7.1-test-3' into debian
Test release: 5.7.1-test-3
Diffstat (limited to 'Src/Modules/files.c')
-rw-r--r--Src/Modules/files.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index 6f816bac0..6d20e38a8 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -613,12 +613,52 @@ bin_rm(char *nam, char **args, Options ops, UNUSED(int func))
rmm.opt_interact = OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f');
rmm.opt_unlinkdir = OPT_ISSET(ops,'d');
err = recursivecmd(nam, OPT_ISSET(ops,'f'),
- OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'d'),
+ !OPT_ISSET(ops,'d') && (OPT_ISSET(ops,'R') ||
+ OPT_ISSET(ops,'r')),
OPT_ISSET(ops,'s'),
args, recurse_donothing, rm_dirpost, rm_leaf, &rmm);
return OPT_ISSET(ops,'f') ? 0 : err;
}
+/* chmod builtin */
+
+struct chmodmagic {
+ char *nam;
+ mode_t mode;
+};
+
+/**/
+static int
+chmod_dochmod(char *arg, char *rp, UNUSED(struct stat const *sp), void *magic)
+{
+ struct chmodmagic *chm = magic;
+
+ if(chmod(rp, chm->mode)) {
+ zwarnnam(chm->nam, "%s: %e", arg, errno);
+ return 1;
+ }
+ return 0;
+}
+
+/**/
+static int
+bin_chmod(char *nam, char **args, Options ops, int func)
+{
+ struct chmodmagic chm;
+ char *str = args[0], *ptr;
+
+ chm.nam = nam;
+
+ chm.mode = zstrtol(str, &ptr, 8);
+ if(!*str || *ptr) {
+ zwarnnam(nam, "invalid mode `%s'", str);
+ return 1;
+ }
+
+ return recursivecmd(nam, 0, OPT_ISSET(ops,'R'), OPT_ISSET(ops,'s'),
+ args + 1, chmod_dochmod, recurse_donothing, chmod_dochmod, &chm);
+}
+
/* chown builtin */
struct chownmagic {
@@ -754,20 +794,22 @@ static struct builtin bintab[] = {
/* The names which overlap commands without necessarily being
* fully compatible. */
BUILTIN("chgrp", 0, bin_chown, 2, -1, BIN_CHGRP, "hRs", NULL),
+ BUILTIN("chmod", 0, bin_chmod, 2, -1, 0, "Rs", NULL),
BUILTIN("chown", 0, bin_chown, 2, -1, BIN_CHOWN, "hRs", NULL),
BUILTIN("ln", 0, bin_ln, 1, -1, BIN_LN, LN_OPTS, NULL),
BUILTIN("mkdir", 0, bin_mkdir, 1, -1, 0, "pm:", NULL),
BUILTIN("mv", 0, bin_ln, 2, -1, BIN_MV, "fi", NULL),
- BUILTIN("rm", 0, bin_rm, 1, -1, 0, "dfirs", NULL),
+ BUILTIN("rm", 0, bin_rm, 1, -1, 0, "dfiRrs", NULL),
BUILTIN("rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL),
BUILTIN("sync", 0, bin_sync, 0, 0, 0, NULL, NULL),
/* The "safe" zsh-only names */
BUILTIN("zf_chgrp", 0, bin_chown, 2, -1, BIN_CHGRP, "hRs", NULL),
+ BUILTIN("zf_chmod", 0, bin_chmod, 2, -1, 0, "Rs", NULL),
BUILTIN("zf_chown", 0, bin_chown, 2, -1, BIN_CHOWN, "hRs", NULL),
BUILTIN("zf_ln", 0, bin_ln, 1, -1, BIN_LN, LN_OPTS, NULL),
BUILTIN("zf_mkdir", 0, bin_mkdir, 1, -1, 0, "pm:", NULL),
BUILTIN("zf_mv", 0, bin_ln, 2, -1, BIN_MV, "fi", NULL),
- BUILTIN("zf_rm", 0, bin_rm, 1, -1, 0, "dfirs", NULL),
+ BUILTIN("zf_rm", 0, bin_rm, 1, -1, 0, "dfiRrs", NULL),
BUILTIN("zf_rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL),
BUILTIN("zf_sync", 0, bin_sync, 0, 0, 0, NULL, NULL),