tcsh-6.19.00-018-add-noclobber-and-ask-options.patch added

> add noclobber/ask options (Martin Tournoij)
This commit is contained in:
David Kaspar [Dee'Kej] 2016-05-03 15:37:48 +02:00
parent 9f627d2ba0
commit d8b6dd5802
2 changed files with 278 additions and 0 deletions

View File

@ -0,0 +1,276 @@
From 858a705a79a53890eb97bf1f234692c0347c932a Mon Sep 17 00:00:00 2001
From: christos <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

View File

@ -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 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 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 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: # 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-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-016-do-not-quote-name-expanded-by-completion.patch
tcsh-6.19.00-017-fix-for-finnish-translations.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] <dkaspar@redhat.com> - 6.19.00-6 * Thu Apr 21 2016 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 6.19.00-6
- Drop tcsh-6.15.00-closem.patch - issue not reproducible, patch not accepted by upstream - Drop tcsh-6.15.00-closem.patch - issue not reproducible, patch not accepted by upstream