diff options
| author | mycroft <mycroft@NetBSD.org> | 2004-07-07 19:20:09 +0000 |
|---|---|---|
| committer | mycroft <mycroft@NetBSD.org> | 2004-07-07 19:20:09 +0000 |
| commit | f662a744b613c47b419b64dcce51f7fe1fe7d738 (patch) | |
| tree | 3920a22be9361bd56e79641d6724f20cfeeeab73 /bin/ksh/exec.c | |
| parent | f61ec29665e6f1ac048da158d42ef08f664dfdcb (diff) | |
Cleanup of ksh memory handling from OpenBSD, via Stefan Krueger in PR 24962.
Should also fix:
PR 8153
PR 13301
PR 15256
PR 25084
Diffstat (limited to 'bin/ksh/exec.c')
| -rw-r--r-- | bin/ksh/exec.c | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/bin/ksh/exec.c b/bin/ksh/exec.c index 546d5b4981b..c640816bb62 100644 --- a/bin/ksh/exec.c +++ b/bin/ksh/exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: exec.c,v 1.8 2003/06/23 11:38:56 agc Exp $ */ +/* $NetBSD: exec.c,v 1.9 2004/07/07 19:20:09 mycroft Exp $ */ /* * execute command tree @@ -6,7 +6,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: exec.c,v 1.8 2003/06/23 11:38:56 agc Exp $"); +__RCSID("$NetBSD: exec.c,v 1.9 2004/07/07 19:20:09 mycroft Exp $"); #endif @@ -84,7 +84,6 @@ execute(t, flags) { int i; volatile int rv = 0; - volatile int rv_prop = 0; /* rv being propogated or newly generated? */ int pv[2]; char ** volatile ap; char *s, *cp; @@ -108,7 +107,7 @@ execute(t, flags) newenv(E_EXEC); if (trap) runtraps(0); - + if (t->type == TCOM) { /* Clear subst_exstat before argument expansion. Used by * null commands (see comexec() and c_eval()) and by c_set(). @@ -166,7 +165,6 @@ execute(t, flags) case TPAREN: rv = execute(t->left, flags|XFORK); - rv_prop = 1; break; case TPIPE: @@ -238,8 +236,10 @@ execute(t, flags) e->savefd[1] = savefd(1, 0); openpipe(pv); - ksh_dup2(pv[0], 0, FALSE); - close(pv[0]); + if (pv[0] != 0) { + ksh_dup2(pv[0], 0, FALSE); + close(pv[0]); + } coproc.write = pv[1]; coproc.job = (void *) 0; @@ -285,7 +285,6 @@ execute(t, flags) rv = execute(t->right, flags & XERROK); else flags |= XERROK; - rv_prop = 1; break; case TBANG: @@ -334,7 +333,6 @@ execute(t, flags) } } rv = 0; /* in case of a continue */ - rv_prop = 1; if (t->type == TFOR) { while (*ap != NULL) { setstr(global(t->str), *ap++, KSH_UNWIND_ERROR); @@ -346,7 +344,6 @@ execute(t, flags) for (;;) { if (!(cp = do_selectargs(ap, is_first))) { rv = 1; - rv_prop = 0; break; } is_first = FALSE; @@ -378,7 +375,6 @@ execute(t, flags) rv = 0; /* in case of a continue */ while ((execute(t->left, XERROK) == 0) == (t->type == TWHILE)) rv = execute(t->right, flags & XERROK); - rv_prop = 1; break; case TIF: @@ -388,7 +384,6 @@ execute(t, flags) rv = execute(t->left, XERROK) == 0 ? execute(t->right->left, flags & XERROK) : execute(t->right->right, flags & XERROK); - rv_prop = 1; break; case TCASE: @@ -401,12 +396,10 @@ execute(t, flags) break; Found: rv = execute(t->left, flags & XERROK); - rv_prop = 1; break; case TBRACE: rv = execute(t->left, flags & XERROK); - rv_prop = 1; break; case TFUNCT: @@ -418,7 +411,6 @@ execute(t, flags) * (allows "ls -l | time grep foo"). */ rv = timex(t, flags & ~XEXEC); - rv_prop = 1; break; case TEXEC: /* an eval'd TCOM */ @@ -444,11 +436,9 @@ execute(t, flags) exstat = rv; quitenv(); /* restores IO */ - if ((flags&XEXEC)) { + if ((flags&XEXEC)) unwind(LEXIT); /* exit child */ - /* NOTREACHED */ - } - if (rv != 0 && !rv_prop && !(flags & XERROK)) { + if (rv != 0 && !(flags & XERROK)) { if (Flag(FERREXIT)) unwind(LERROR); trapsig(SIGERR_); @@ -468,21 +458,19 @@ comexec(t, tp, ap, flags) int volatile flags; { int i; - int rv = 0; + volatile int rv = 0; register char *cp; register char **lastp; static struct op texec; /* Must be static (XXX but why?) */ int type_flags; int keepasn_ok; int fcflags = FC_BI|FC_FUNC|FC_PATH; -#ifdef __GNUC__ - (void) &rv; -#endif + int bourne_function_call = 0; #ifdef KSH /* snag the last argument for $_ XXX not the same as at&t ksh, * which only seems to set $_ after a newline (but not in - * functions/dot scripts, but in interactive and scipt) - + * functions/dot scripts, but in interactive and script) - * perhaps save last arg here and set it in shell()?. */ if (Flag(FTALKING) && *(lastp = ap)) { @@ -567,9 +555,10 @@ comexec(t, tp, ap, flags) newblock(); /* ksh functions don't keep assignments, POSIX functions do. */ if (keepasn_ok && tp && tp->type == CFUNC - && !(tp->flag & FKSH)) + && !(tp->flag & FKSH)) { + bourne_function_call = 1; type_flags = 0; - else + } else type_flags = LOCAL|LOCAL_COPY|EXPORT; } if (Flag(FEXPORT)) @@ -586,6 +575,8 @@ comexec(t, tp, ap, flags) shf_flush(shl_out); } typeset(cp, type_flags, 0, 0, 0); + if (bourne_function_call && !(type_flags & EXPORT)) + typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0); } if ((cp = *ap) == NULL) { @@ -735,8 +726,8 @@ comexec(t, tp, ap, flags) #ifdef KSH /* set $_ to program's full path */ /* setstr() can't fail here */ - setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), tp->val.s, - KSH_RETURN_ERROR); + setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), + tp->val.s, KSH_RETURN_ERROR); #endif /* KSH */ if (flags&XEXEC) { @@ -851,7 +842,7 @@ scriptexec(tp, ap) } else { /* Use ksh documented shell default if present * else use OS2_SHELL which is assumed to need - * the /c option and '\' as dir separater. + * the /c option and '\' as dir separator. */ char *p = shell; @@ -1157,14 +1148,14 @@ search_access(path, mode, errnop) char *tp = mpath + strlen(mpath); char *p; char **sfx; - + /* If a suffix has been specified, check if it is one of the * suffixes that indicate the file is executable - if so, change * the access test to R_OK... * This code assumes OS/2 files can have only one suffix... */ if ((p = strrchr((p = ksh_strrchr_dirsep(mpath)) ? p : mpath, '.'))) { - if (mode == X_OK) + if (mode == X_OK) mode = R_OK; return search_access1(mpath, mode, errnop); } @@ -1240,7 +1231,7 @@ search(name, path, mode, errnop) } /* Look in current context always. (os2 style) */ - if (search_access(Xstring(xs, xp), mode, errnop) == 0) + if (search_access(Xstring(xs, xp), mode, errnop) == 0) return Xstring(xs, xp); /* not Xclose() - xp may be wrong */ #else /* OS2 */ if (ksh_strchr_dirsep(name)) { @@ -1374,6 +1365,8 @@ iosetup(iop, tp) snptreef((char *) 0, 32, "%R", &iotmp), emsg); return -1; } + if (u == iop->unit) + return 0; /* "dup from" == "dup to" */ break; } } @@ -1398,13 +1391,19 @@ iosetup(iop, tp) return -1; } /* Do not save if it has already been redirected (i.e. "cat >x >y"). */ - if (e->savefd[iop->unit] == 0) - /* c_exec() assumes e->savefd[fd] set for any redirections. - * Ask savefd() not to close iop->unit - allows error messages - * to be seen if iop->unit is 2; also means we can't lose - * the fd (eg, both dup2 below and dup2 in restfd() failing). - */ - e->savefd[iop->unit] = savefd(iop->unit, 1); + if (e->savefd[iop->unit] == 0) { + /* If these are the same, it means unit was previously closed */ + if (u == iop->unit) + e->savefd[iop->unit] = -1; + else + /* c_exec() assumes e->savefd[fd] set for any + * redirections. Ask savefd() not to close iop->unit; + * this allows error messages to be seen if iop->unit + * is 2; also means we can't lose the fd (eg, both + * dup2 below and dup2 in restfd() failing). + */ + e->savefd[iop->unit] = savefd(iop->unit, 1); + } if (do_close) close(iop->unit); |
