summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/curses.c2
-rw-r--r--Src/Modules/db_gdbm.c2
-rw-r--r--Src/Modules/files.c48
-rw-r--r--Src/Modules/parameter.c2
-rw-r--r--Src/Modules/system.c6
-rw-r--r--Src/Modules/zftp.c15
-rw-r--r--Src/Modules/zpty.c2
-rw-r--r--Src/Modules/zutil.c33
8 files changed, 86 insertions, 24 deletions
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index a60dfcbf8..19f285e34 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -1519,7 +1519,7 @@ zccmd_resize(const char *nam, char **args)
// is not available.
return 0;
} else {
- // Without this call some window moves are innacurate. Tested on
+ // Without this call some window moves are inaccurate. Tested on
// OS X ncurses 5.4, Homebrew ncursesw 6.0-2, Arch Linux ncursesw
// 6.0, Ubuntu 14.04 ncurses 5.9, FreeBSD ncursesw.so.8
//
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index 12dd839cf..b8e7c76c6 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -766,7 +766,7 @@ static int remove_tied_name( const char *name ) {
/*
* Unmetafy that:
- * - duplicates bufer to work on it,
+ * - duplicates buffer to work on it,
* - does zalloc of exact size for the new string,
* - restores work buffer to original content, to restore strlen
*/
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),
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 76824cf58..ef9148d7b 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -1552,7 +1552,7 @@ setpmnameddirs(Param pm, HashTable ht)
}
}
- /* The INTERACTIVE stuff ensures that the dirs are not immediatly removed
+ /* The INTERACTIVE stuff ensures that the dirs are not immediately removed
* when the sub-pms are deleted. */
i = opts[INTERACTIVE];
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index 7a4f4ee13..fb3d80773 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -174,7 +174,7 @@ bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
}
while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds,
- NULL, NULL,&select_tv)) < 1) {
+ NULL, NULL,&select_tv)) < 0) {
if (errno != EINTR || errflag || retflag || breaks || contflag)
break;
}
@@ -316,7 +316,7 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
int o, fd, moved_fd, explicit = -1;
mode_t perms = 0666;
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
- int fdflags;
+ int fdflags = 0;
#endif
if (!OPT_ISSET(ops, 'u')) {
@@ -396,8 +396,8 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
#endif /* O_CLOEXEC */
fcntl(moved_fd, F_SETFD, FD_CLOEXEC);
#endif /* FD_CLOEXEC */
+ fdtable[moved_fd] = FDT_EXTERNAL;
if (explicit == -1) {
- fdtable[moved_fd] = FDT_EXTERNAL;
setiparam(fdvar, moved_fd);
/* if setting the variable failed, close moved_fd to avoid leak */
if (errflag)
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 4aaa1f072..e8e239e76 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -237,7 +237,7 @@ enum {
/*
* We keep an fd open for communication between the main shell
* and forked off bits and pieces. This allows us to know
- * if something happend in a subshell: mode changed, type changed,
+ * if something happened in a subshell: mode changed, type changed,
* connection was closed. If something too substantial happened
* in a subshell --- connection opened, ZFTP_USER and ZFTP_PWD changed
* --- we don't try to track it because it's too complicated.
@@ -1257,14 +1257,8 @@ zfstats(char *fnam, int remote, off_t *retsize, char **retmdtm, int fd)
if (retmdtm) {
/* use gmtime() rather than localtime() for consistency */
tm = gmtime(&statbuf.st_mtime);
- /*
- * FTP format for data is YYYYMMDDHHMMSS
- * Using tm directly is easier than worrying about
- * incompatible strftime()'s.
- */
- sprintf(tmbuf, "%04d%02d%02d%02d%02d%02d",
- tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ /* FTP format for date is YYYYMMDDHHMMSS */
+ ztrftime(tmbuf, sizeof(tmbuf), "%Y%m%d%H%M%S", tm, 0L);
mt = ztrdup(tmbuf);
}
}
@@ -2518,7 +2512,8 @@ zftp_local(UNUSED(char *name), char **args, int flags)
#ifdef OFF_T_IS_64_BIT
printf("%s %s\n", output64(sz), mt);
#else
- DPUTS(sizeof(sz) > 4, "Shell compiled with wrong off_t size");
+ DPUTS(sizeof(sz) > sizeof(long),
+ "Shell compiled with wrong off_t size");
printf("%ld %s\n", (long)sz, mt);
#endif
zsfree(mt);
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 2f83f7ce6..45fd15ee0 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -426,7 +426,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
execode(prog, 1, 0, "zpty");
stopmsg = 2;
mypid = 0; /* trick to ensure we _exit() */
- zexit(lastval, 0);
+ zexit(lastval, ZEXIT_NORMAL);
}
master = movefd(master);
if (master == -1) {
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 19a8306b5..24659cb16 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -88,7 +88,8 @@ typedef struct style *Style;
struct style {
struct hashnode node;
- Stypat pats; /* patterns */
+ Stypat pats; /* patterns, sorted by weight descending, then
+ by order of definition, newest first. */
};
struct stypat {
@@ -337,7 +338,19 @@ setstypat(Style s, char *pat, Patprog prog, char **vals, int eval)
p->eval = eprog;
p->next = NULL;
- /* Calculate the weight. */
+ /* Calculate the weight.
+ *
+ * The weight of a pattern is scored as follows:
+ *
+ * - The pattern is split to colon-separated components.
+ * - A component equal to '*' (with nothing else) scores 0 points.
+ * - A component that's a pattern, otherwise, scores 1 point.
+ * - A component that's a literal string scores 2 points.
+ * - The score of a pattern is the sum of the score of its components.
+ *
+ * This corresponds to the notion of 'more specific' in the zshmodules(1)
+ * documentation of zstyle.
+ */
for (weight = 0, tmp = 2, first = 1, str = pat; *str; str++) {
if (first && *str == '*' && (!str[1] || str[1] == ':')) {
@@ -362,9 +375,9 @@ setstypat(Style s, char *pat, Patprog prog, char **vals, int eval)
}
p->weight = (weight += tmp);
+ /* Insert 'q' to 's->pats', using 'qq' as a temporary. */
for (qq = NULL, q = s->pats; q && q->weight >= weight;
qq = q, q = q->next);
-
p->next = q;
if (qq)
qq->next = p;
@@ -1644,7 +1657,7 @@ static int
bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
char *o, *p, *n, **pp, **aval, **ap, *assoc = NULL, **cp, **np;
- int del = 0, flags = 0, extract = 0, keep = 0;
+ int del = 0, flags = 0, extract = 0, fail = 0, keep = 0;
Zoptdesc sopts[256], d;
Zoptarr a, defarr = NULL;
Zoptval v;
@@ -1681,6 +1694,14 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
extract = 1;
break;
+ case 'F':
+ if (o[2]) {
+ args--;
+ o = NULL;
+ break;
+ }
+ fail = 1;
+ break;
case 'K':
if (o[2]) {
args--;
@@ -1843,6 +1864,10 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
if (!(d = lookup_opt(o + 1))) {
while (*++o) {
if (!(d = sopts[STOUC(*o)])) {
+ if (fail) {
+ zwarnnam(nam, "bad option: %c", *o);
+ return 1;
+ }
o = NULL;
break;
}