diff --git a/tcsh-6.19.00-018-add-noclobber-and-ask-options.patch b/tcsh-6.19.00-018-add-noclobber-and-ask-options.patch new file mode 100644 index 0000000..3c89d20 --- /dev/null +++ b/tcsh-6.19.00-018-add-noclobber-and-ask-options.patch @@ -0,0 +1,276 @@ +From 858a705a79a53890eb97bf1f234692c0347c932a Mon Sep 17 00:00:00 2001 +From: christos +Date: Tue, 8 Sep 2015 15:49:53 +0000 +Subject: [PATCH] add noclobber/ask options (Martin Tournoij) + +--- + Fixes | 1 + + sh.decls.h | 1 + + sh.func.c | 17 +++++++++++++++++ + sh.h | 6 ++++++ + sh.sem.c | 10 +++++++++- + sh.set.c | 32 ++++++++++++++++++++++++++++++++ + tc.const.c | 2 ++ + tc.func.c | 14 ++------------ + tcsh.man | 3 +++ + tests/syntax.at | 26 ++++++++++++++++++++++++++ + 10 files changed, 99 insertions(+), 13 deletions(-) + +diff --git a/Fixes b/Fixes +index 0481286..689aeb0 100644 +--- a/Fixes ++++ b/Fixes +@@ -1,3 +1,4 @@ ++ 8. Add notempty and ask values for the noclobber setting (Martin Tournoij) + 7. more correct $wordchars for vimode (Luke Mewburn) + 6. expose VImode in $vimode (Luke Mewburn) + 5. display what the compiled in editor is in bindkey -d (Luke Mewburn) +diff --git a/sh.decls.h b/sh.decls.h +index 78bbed9..671a0b7 100644 +--- a/sh.decls.h ++++ b/sh.decls.h +@@ -185,6 +185,7 @@ extern void unalias (Char **, struct command *); + extern void wfree (void); + extern void dobuiltins (Char **, struct command *); + extern void reexecute (struct command *); ++extern int getYN (const char *); + + /* + * sh.glob.c +diff --git a/sh.func.c b/sh.func.c +index bb670b8..41f9e71 100644 +--- a/sh.func.c ++++ b/sh.func.c +@@ -2722,3 +2722,20 @@ nlsclose(void) + } + #endif /* NLS_CATALOGS */ + } ++ ++int ++getYN(const char *prompt) ++{ ++ int doit, c; ++ xprintf("%s", prompt); ++ flush(); ++ (void) force_read(SHIN, &c, 1); ++ /* ++ * Perhaps we should use the yesexpr from the ++ * actual locale ++ */ ++ doit = (strchr(CGETS(22, 14, "Yy"), c) != NULL); ++ while (c != '\n' && force_read(SHIN, &c, 1) == 1) ++ continue; ++ return doit; ++} +diff --git a/sh.h b/sh.h +index 51d3f3b..38b7efd 100644 +--- a/sh.h ++++ b/sh.h +@@ -193,6 +193,11 @@ static __inline void tcsh_ignore(intptr_t a) + # endif /* SYSVREL */ + #endif /* ECHO_STYLE */ + ++/* values for noclobber */ ++#define NOCLOBBER_DEFAULT 1 ++#define NOCLOBBER_NOTEMPTY 2 ++#define NOCLOBBER_ASK 4 ++ + /* + * The shell moves std in/out/diag and the old std input away from units + * 0, 1, and 2 so that it is easy to set up these standards for invoked +@@ -577,6 +582,7 @@ EXTERN int arun IZERO; /* Currently running multi-line-aliases */ + EXTERN int implicit_cd IZERO;/* implicit cd enabled?(1=enabled,2=verbose) */ + EXTERN int cdtohome IZERO; /* cd without args goes home */ + EXTERN int inheredoc IZERO; /* Currently parsing a heredoc */ ++EXTERN int no_clobber IZERO; /* no clobber enabled? 1=yes 2=notempty, 4=ask*/ + /* We received a window change event */ + EXTERN volatile sig_atomic_t windowchg IZERO; + #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) +diff --git a/sh.sem.c b/sh.sem.c +index c4eb394..4293b1b 100644 +--- a/sh.sem.c ++++ b/sh.sem.c +@@ -909,7 +909,7 @@ doio(struct command *t, int *pipein, int *pipeout) + else + fd = 0; + if ((flags & F_APPEND) == 0 || fd == -1) { +- if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) { ++ if (!(flags & F_OVERWRITE) && no_clobber) { + if (flags & F_APPEND) + stderror(ERR_SYSTEM, tmp, strerror(errno)); + chkclob(tmp); +@@ -981,5 +981,13 @@ chkclob(const char *cp) + return; + if (S_ISCHR(stb.st_mode)) + return; ++ if (no_clobber & NOCLOBBER_NOTEMPTY && stb.st_size == 0) ++ return; ++ if (no_clobber & NOCLOBBER_ASK) { ++ if (getYN(CGETS(22, 15, ++ "Do you really want to overwrite an existing file? [N/y] "))) ++ return; ++ } ++ + stderror(ERR_EXISTS, cp); + } +diff --git a/sh.set.c b/sh.set.c +index 52602f0..6428562 100644 +--- a/sh.set.c ++++ b/sh.set.c +@@ -55,6 +55,7 @@ static struct varent *madrof (Char *, struct varent *); + static void unsetv1 (struct varent *); + static void exportpath (Char **); + static void balance (struct varent *, int, int); ++static int set_noclobber (Char **); + + /* + * C Shell +@@ -72,6 +73,13 @@ update_vars(Char *vp) + dohash(NULL, NULL); + } + } ++ else if (eq(vp, STRnoclobber)) { ++ struct varent *p = adrof(STRnoclobber); ++ if (p == NULL) ++ stderror(ERR_NAME | ERR_UNDVAR); ++ else ++ no_clobber = set_noclobber(p->vec); ++ } + else if (eq(vp, STRhistchars)) { + Char *pn = varval(vp); + +@@ -772,6 +780,8 @@ unset(Char **v, struct command *c) + PRCH = tcsh ? '>' : '%'; + PRCHROOT = '#'; + } ++ if (adrof(STRnoclobber) == 0) ++ no_clobber = 0; + if (adrof(STRhistlit) == 0) + HistLit = 0; + if (adrof(STRloginsh) == 0) +@@ -937,6 +947,28 @@ exportpath(Char **val) + cleanup_until(exppath); + } + ++static int ++set_noclobber(Char **val) ++{ ++ Char *option; ++ int nc = NOCLOBBER_DEFAULT; ++ ++ if (val == NULL) ++ return nc; ++ while (*val) { ++ if (*val == 0 || eq(*val, STRRparen)) ++ return nc; ++ ++ option = *val++; ++ ++ if (eq(option, STRnotempty)) ++ nc |= NOCLOBBER_NOTEMPTY; ++ else if (eq(option, STRask)) ++ nc |= NOCLOBBER_ASK; ++ } ++ return nc; ++} ++ + #ifndef lint + /* + * Lint thinks these have null effect +diff --git a/tc.const.c b/tc.const.c +index 06ddd2b..d5d0eb4 100644 +--- a/tc.const.c ++++ b/tc.const.c +@@ -372,6 +372,8 @@ Char STRsldotcshrc[] = { '/', '.', 'c', 's', 'h', 'r', 'c', '\0' }; + Char STRsldotlogin[] = { '/', '.', 'l', 'o', 'g', 'i', 'n', '\0' }; + Char STRignoreeof[] = { 'i', 'g', 'n', 'o', 'r', 'e', 'e', 'o', 'f', '\0' }; + Char STRnoclobber[] = { 'n', 'o', 'c', 'l', 'o', 'b', 'b', 'e', 'r', '\0' }; ++Char STRnotempty[] = { 'n', 'o', 't', 'e', 'm', 'p', 't', 'y', '\0' }; ++Char STRask[] = { 'a', 's', 'k', '\0' }; + Char STRhelpcommand[] = { 'h', 'e', 'l', 'p', 'c', 'o', 'm', 'm', 'a', 'n', + 'd', '\0' }; + Char STRfignore[] = { 'f', 'i', 'g', 'n', 'o', 'r', 'e', '\0' }; +diff --git a/tc.func.c b/tc.func.c +index 9af4858..f2b1a97 100644 +--- a/tc.func.c ++++ b/tc.func.c +@@ -1145,7 +1145,6 @@ rmstar(struct wordent *cp) + Char *tag; + #endif /* RMDEBUG */ + Char *charac; +- char c; + int ask, doit, star = 0, silent = 0, opintr_disabled; + + if (!adrof(STRrmstar)) +@@ -1178,17 +1177,8 @@ rmstar(struct wordent *cp) + if (!Strcmp(args->word, STRstar)) + star = 1; + if (ask && star) { +- xprintf("%s", CGETS(22, 8, +- "Do you really want to delete all files? [n/y] ")); +- flush(); +- (void) force_read(SHIN, &c, 1); +- /* +- * Perhaps we should use the yesexpr from the +- * actual locale +- */ +- doit = (strchr(CGETS(22, 14, "Yy"), c) != NULL); +- while (c != '\n' && force_read(SHIN, &c, 1) == 1) +- continue; ++ doit = getYN(CGETS(22, 8, ++ "Do you really want to delete all files? [N/y] ")); + if (!doit) { + /* remove the command instead */ + #ifdef RMDEBUG +diff --git a/tcsh.man b/tcsh.man +index 0a35405..2aa37ac 100644 +--- a/tcsh.man ++++ b/tcsh.man +@@ -1636,6 +1636,9 @@ If the shell variable \fBnoclobber\fR is set, then the file must not exist or be + character special file (e.g., a terminal or `/dev/null') or an error results. + This helps prevent accidental destruction of files. In this case the `!' forms + can be used to suppress this check. ++If \fBnotempty\fR is given in \fBnoclobber\fR, `>' is allowed on empty files; ++if \fBask\fR is set, an interacive confirmation is presented, rather than an ++error. + .PP + The forms involving `&' route the diagnostic output into the specified file as + well as the standard output. \fIname\fR is expanded in the same way as `<' +diff --git a/tests/syntax.at b/tests/syntax.at +index 23fc8d5..35134d1 100644 +--- a/tests/syntax.at ++++ b/tests/syntax.at +@@ -161,4 +161,30 @@ AT_CHECK([tcsh -f -c '(echo $this_does_not_exist) |& cat'], 1, + [this_does_not_exist: Undefined variable. + ]) + ++dnl noclobber=notempty ++echo Hello > output ++AT_CHECK([tcsh -f -c 'set noclobber=notempty; echo OK >& output'], 1, [], ++[output: File exists. ++]) ++ ++rm -f output ++touch output ++AT_CHECK([tcsh -f -c 'set noclobber=notempty; echo OK >& output']) ++AT_CHECK([cat output], , ++[OK ++]) ++ ++dnl noclobber=ask ++dnl touch output ++dnl AT_CHECK([tcsh -f -c 'set noclobber=ask; echo "n" | echo OK >& output'], 0, [], ++dnl [output: File exists. ++dnl ]) ++dnl T_CHECK([tcsh -f -c 'set noclobber=ask; echo "y" | echo OK >& output']) ++ ++dnl noclobber=(notempty ask) ++dnl rm -f output ++dnl touch output ++dnl AT_CHECK([tcsh -f -c 'set noclobber=(notempty ask); echo OK >& output']) ++ ++ + AT_CLEANUP +-- +2.5.5 + diff --git a/tcsh.spec b/tcsh.spec index db42ed0..9dd242a 100644 --- a/tcsh.spec +++ b/tcsh.spec @@ -46,6 +46,7 @@ Patch014: tcsh-6.19.00-014-do-not-use-union-wait.patch Patch015: tcsh-6.19.00-015-set-LC_COLLATE-to-C-and-add-HTML-makefile.patch Patch016: tcsh-6.19.00-016-do-not-quote-name-expanded-by-completion.patch Patch017: tcsh-6.19.00-017-fix-for-finnish-translations.patch +Patch018: tcsh-6.19.00-018-add-noclobber-and-ask-options.patch # Downstream patches -- these should be always included when doing rebase: @@ -184,6 +185,7 @@ fi tcsh-6.19.00-015-set-LC_COLLATE-to-C-and-add-HTML-makefile.patch tcsh-6.19.00-016-do-not-quote-name-expanded-by-completion.patch tcsh-6.19.00-017-fix-for-finnish-translations.patch + tcsh-6.19.00-018-add-noclobber-and-ask-options.patch * Thu Apr 21 2016 David Kaspar [Dee'Kej] - 6.19.00-6 - Drop tcsh-6.15.00-closem.patch - issue not reproducible, patch not accepted by upstream