diff options
Diffstat (limited to 'sh.sem.c')
-rw-r--r-- | sh.sem.c | 45 |
1 files changed, 35 insertions, 10 deletions
@@ -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); } |