diff --git a/check.t b/check.t index 3e1c8aa..5336b61 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.677 2015/01/25 15:23:39 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.678 2015/02/06 10:56:44 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,7 +30,7 @@ # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R50 2015/01/25 + @(#)MIRBSD KSH R50 2015/02/06 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R50 2015/01/25 + @(#)LEGACY KSH R50 2015/02/06 description: Check version of legacy shell. stdin: diff --git a/exec.c b/exec.c index 4a8c735..754ee92 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.142 2015/02/06 10:09:06 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.143 2015/02/06 10:56:46 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -446,7 +446,6 @@ execute(struct op * volatile t, case TEXEC: /* an eval'd TCOM */ - s = t->args[0]; up = makenv(); restoresigs(); cleanup_proc_env(); @@ -460,7 +459,7 @@ execute(struct op * volatile t, if (rv == ENOEXEC) scriptexec(t, (const char **)up); else - errorf("%s: %s", s, cstrerror(rv)); + errorf("%s: %s", t->str, cstrerror(rv)); } Break: exstat = rv & 0xFF; @@ -509,6 +508,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, int fcflags = FC_BI|FC_FUNC|FC_PATH; struct block *l_expand, *l_assign; int optc; + const char *exec_argv0 = NULL; + bool exec_clrenv = false; /* snag the last argument for $_ */ if (Flag(FTALKING) && *(lastp = ap)) { @@ -554,7 +555,22 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, } else if (tp->val.f == c_exec) { if (ap[1] == NULL) break; - ap++; + ksh_getopt_reset(&builtin_opt, GF_ERROR); + while ((optc = ksh_getopt(ap, &builtin_opt, "a:c")) != -1) + switch (optc) { + case 'a': + exec_argv0 = builtin_opt.optarg; + break; + case 'c': + exec_clrenv = true; + /* ensure we can actually do this */ + resetspec = true; + break; + default: + rv = 2; + goto Leave; + } + ap += builtin_opt.optind; flags |= XEXEC; } else if (tp->val.f == c_command) { bool saw_p = false; @@ -633,6 +649,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, type_flags = LOCAL|LOCAL_COPY|EXPORT; } l_assign = e->loc; + if (exec_clrenv) + l_assign->flags |= BF_STOPENV; if (Flag(FEXPORT)) type_flags |= EXPORT; if (Flag(FXTRACE)) @@ -813,14 +831,24 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, break; } - /* set $_ to programme's full path */ + /* set $_ to program's full path */ /* setstr() can't fail here */ setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0), tp->val.s, KSH_RETURN_ERROR); - if (flags&XEXEC) { + /* to fork, we set up a TEXEC node and call execute */ + texec.type = TEXEC; + /* for vistree/dumptree */ + texec.left = t; + texec.str = tp->val.s; + texec.args = ap; + + /* in this case we do not fork, of course */ + if (flags & XEXEC) { + if (exec_argv0) + texec.args[0] = exec_argv0; j_exit(); - if (!(flags&XBGND) + if (!(flags & XBGND) #ifndef MKSH_UNEMPLOYED || Flag(FMONITOR) #endif @@ -830,12 +858,6 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, } } - /* to fork we set up a TEXEC node and call execute */ - texec.type = TEXEC; - /* for tprint */ - texec.left = t; - texec.str = tp->val.s; - texec.args = ap; rv = exchild(&texec, flags, xerrok, -1); break; } diff --git a/mksh.1 b/mksh.1 index 83a0a77..0449282 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,9 +1,9 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.348 2015/01/25 15:23:42 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.349 2015/02/06 10:56:47 tg Exp $ .\" $OpenBSD: ksh.1,v 1.156 2015/01/16 15:32:32 schwarze Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" 2010, 2011, 2012, 2013, 2014, 2015 -.\" Thorsten Glaser +.\" Thorsten “mirabilos” Glaser .\" .\" Provided that these terms and disclaimer and all copyright notices .\" are retained or reproduced in an accompanying document, permission @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: January 25 2015 $ +.Dd $Mdocdate: February 6 2015 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -3376,9 +3376,25 @@ string which the shell then parses and executes in the current environment. .Pp .It Xo .Ic exec +.Op Fl a Ar argv0 +.Op Fl c .Op Ar command Op Ar arg ... .Xc The command is executed without forking, replacing the shell process. +This is currently absolute, i.e.\& +.Ic exec +never returns, even if the +.Ar command +is not found. +The +.Fl a +option permits setting a different +.Li argv[0] +value, and +.Fl c +clears the environment before executing the child process, except for the +.Ev _ +variable and direct assignments. .Pp If no command is given except for I/O redirection, the I/O redirection is permanent and the shell is @@ -6485,7 +6501,7 @@ $ /bin/sleep 666 && echo fubar .Ed .Pp This document attempts to describe -.Nm mksh\ R50 +.Nm mksh\ R51beta and up, compiled without any options impacting functionality, such as .Dv MKSH_SMALL , diff --git a/sh.h b/sh.h index fe4c057..c09f38f 100644 --- a/sh.h +++ b/sh.h @@ -169,9 +169,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.709 2015/01/25 15:23:43 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.710 2015/02/06 10:56:48 tg Exp $"); #endif -#define MKSH_VERSION "R50 2015/01/25" +#define MKSH_VERSION "R50 2015/02/06" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -1237,6 +1237,7 @@ struct block { /* Values for struct block.flags */ #define BF_DOGETOPTS BIT(0) /* save/restore getopts state */ +#define BF_STOPENV BIT(1) /* do not export further */ /* * Used by ktwalk() and ktnext() routines. diff --git a/var.c b/var.c index ea32740..18a1633 100644 --- a/var.c +++ b/var.c @@ -2,7 +2,7 @@ /*- * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - * 2011, 2012, 2013, 2014 + * 2011, 2012, 2013, 2014, 2015 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -28,7 +28,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.185 2014/12/15 23:18:47 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.186 2015/02/06 10:56:49 tg Exp $"); /*- * Variables @@ -1112,6 +1112,8 @@ makenv(void) } XPput(denv, vp->val.s); } + if (l->flags & BF_STOPENV) + break; } XPput(denv, NULL); return ((char **)XPclose(denv));