summaryrefslogtreecommitdiff
path: root/sh.sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'sh.sem.c')
-rw-r--r--sh.sem.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/sh.sem.c b/sh.sem.c
index c88097466faf..764c857cd67a 100644
--- a/sh.sem.c
+++ b/sh.sem.c
@@ -1,4 +1,4 @@
-/* $Header: /p/tcsh/cvsroot/tcsh/sh.sem.c,v 3.86 2011/02/25 23:24:19 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/sh.sem.c,v 3.90 2015/10/31 18:54:42 christos Exp $ */
/*
* sh.sem.c: I/O redirections and job forking. A touchy issue!
* Most stuff with builtins is incorrect
@@ -33,7 +33,7 @@
*/
#include "sh.h"
-RCSID("$tcsh: sh.sem.c,v 3.86 2011/02/25 23:24:19 christos Exp $")
+RCSID("$tcsh: sh.sem.c,v 3.90 2015/10/31 18:54:42 christos Exp $")
#include "tc.h"
#include "tw.h"
@@ -212,8 +212,14 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
* If noexec then this is all we do.
*/
if (t->t_dflg & F_READ) {
+ int old_pintr_disabled;
+
xclose(0);
+ if (setintr)
+ pintr_push_enable(&old_pintr_disabled);
heredoc(t->t_dlef);
+ if (setintr)
+ cleanup_until(&old_pintr_disabled);
if (noexec)
xclose(0);
}
@@ -346,10 +352,6 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
* not pipedout, niced, nohupped, or &'d. It would be nice(?) to not
* fork in some of these cases.
*/
- /*
- * Prevent forking cd, pushd, popd, chdir cause this will cause the
- * shell not to change dir!
- */
#ifdef BACKPIPE
/*
* Can't have NOFORK for the tail of a pipe - because it is not the
@@ -358,11 +360,26 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
*/
if (t->t_dflg & F_PIPEIN)
t->t_dflg &= ~(F_NOFORK);
+#else
+ /*
+ * "command | builtin" may cause major misbehaviour as noted in
+ * in the BUGS file entry
+ * Subject: Redirected input to built-in functions misbehaves badly
+ * forking when the builtin is the end of the pipe corrects the
+ * problem.
+ */
+ if (bifunc && (t->t_dflg & F_PIPEIN))
+ t->t_dflg &= ~(F_NOFORK);
#endif /* BACKPIPE */
+ /*
+ * Prevent forking cd, pushd, popd, chdir cause this will cause the
+ * shell not to change dir! (XXX: but only for nice?)
+ */
if (bifunc && (bifunc->bfunct == (bfunc_t)dochngd ||
bifunc->bfunct == (bfunc_t)dopushd ||
bifunc->bfunct == (bfunc_t)dopopd))
t->t_dflg &= ~(F_NICE);
+
if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&
(!bifunc || t->t_dflg &
(F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP | F_HUP)))) ||
@@ -560,13 +577,13 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
(void) signal(SIGHUP, SIG_DFL);
if (t->t_dflg & F_NICE) {
int nval = SIGN_EXTEND_CHAR(t->t_nice);
-# ifdef HAVE_SETPRIORITY
+# if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno)
stderror(ERR_SYSTEM, "setpriority",
strerror(errno));
-# else /* !HAVE_SETPRIORITY */
+# else /* !HAVE_SETPRIORITY || !PRIO_PROCESS */
(void) nice(nval);
-# endif /* HAVE_SETPRIORITY */
+# endif /* HAVE_SETPRIORITY && PRIO_PROCESS */
}
# ifdef F_VER
if (t->t_dflg & F_VER) {
@@ -898,7 +915,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);
@@ -970,5 +987,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);
}