diff options
Diffstat (limited to 'Src/Modules')
-rw-r--r-- | Src/Modules/curses.c | 2 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.c | 2 | ||||
-rw-r--r-- | Src/Modules/files.c | 48 | ||||
-rw-r--r-- | Src/Modules/parameter.c | 2 | ||||
-rw-r--r-- | Src/Modules/system.c | 6 | ||||
-rw-r--r-- | Src/Modules/zftp.c | 15 | ||||
-rw-r--r-- | Src/Modules/zpty.c | 2 | ||||
-rw-r--r-- | Src/Modules/zutil.c | 33 |
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; } |