add getopts for exec (unbreaks “exec -- /bin/ls”) and steal -a and -c from ksh93

This commit is contained in:
tg 2015-02-06 10:56:49 +00:00
parent b94b2e363a
commit f6f49a119b
5 changed files with 65 additions and 24 deletions

View File

@ -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 -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 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 # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R50 2015/01/25 @(#)MIRBSD KSH R50 2015/02/06
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R50 2015/01/25 @(#)LEGACY KSH R50 2015/02/06
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:

48
exec.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #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 #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh" #define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -446,7 +446,6 @@ execute(struct op * volatile t,
case TEXEC: case TEXEC:
/* an eval'd TCOM */ /* an eval'd TCOM */
s = t->args[0];
up = makenv(); up = makenv();
restoresigs(); restoresigs();
cleanup_proc_env(); cleanup_proc_env();
@ -460,7 +459,7 @@ execute(struct op * volatile t,
if (rv == ENOEXEC) if (rv == ENOEXEC)
scriptexec(t, (const char **)up); scriptexec(t, (const char **)up);
else else
errorf("%s: %s", s, cstrerror(rv)); errorf("%s: %s", t->str, cstrerror(rv));
} }
Break: Break:
exstat = rv & 0xFF; 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; int fcflags = FC_BI|FC_FUNC|FC_PATH;
struct block *l_expand, *l_assign; struct block *l_expand, *l_assign;
int optc; int optc;
const char *exec_argv0 = NULL;
bool exec_clrenv = false;
/* snag the last argument for $_ */ /* snag the last argument for $_ */
if (Flag(FTALKING) && *(lastp = ap)) { 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) { } else if (tp->val.f == c_exec) {
if (ap[1] == NULL) if (ap[1] == NULL)
break; 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; flags |= XEXEC;
} else if (tp->val.f == c_command) { } else if (tp->val.f == c_command) {
bool saw_p = false; 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; type_flags = LOCAL|LOCAL_COPY|EXPORT;
} }
l_assign = e->loc; l_assign = e->loc;
if (exec_clrenv)
l_assign->flags |= BF_STOPENV;
if (Flag(FEXPORT)) if (Flag(FEXPORT))
type_flags |= EXPORT; type_flags |= EXPORT;
if (Flag(FXTRACE)) if (Flag(FXTRACE))
@ -813,14 +831,24 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
break; break;
} }
/* set $_ to programme's full path */ /* set $_ to program's full path */
/* setstr() can't fail here */ /* setstr() can't fail here */
setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0), setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0),
tp->val.s, KSH_RETURN_ERROR); 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(); j_exit();
if (!(flags&XBGND) if (!(flags & XBGND)
#ifndef MKSH_UNEMPLOYED #ifndef MKSH_UNEMPLOYED
|| Flag(FMONITOR) || Flag(FMONITOR)
#endif #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); rv = exchild(&texec, flags, xerrok, -1);
break; break;
} }

24
mksh.1
View File

@ -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 $ .\" $OpenBSD: ksh.1,v 1.156 2015/01/16 15:32:32 schwarze Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" 2010, 2011, 2012, 2013, 2014, 2015 .\" 2010, 2011, 2012, 2013, 2014, 2015
.\" Thorsten Glaser <tg@mirbsd.org> .\" Thorsten “mirabilos” Glaser <tg@mirbsd.org>
.\" .\"
.\" Provided that these terms and disclaimer and all copyright notices .\" Provided that these terms and disclaimer and all copyright notices
.\" are retained or reproduced in an accompanying document, permission .\" are retained or reproduced in an accompanying document, permission
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" 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. .\" 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 .Pp
.It Xo .It Xo
.Ic exec .Ic exec
.Op Fl a Ar argv0
.Op Fl c
.Op Ar command Op Ar arg ... .Op Ar command Op Ar arg ...
.Xc .Xc
The command is executed without forking, replacing the shell process. 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 .Pp
If no command is given except for I/O redirection, the I/O redirection is If no command is given except for I/O redirection, the I/O redirection is
permanent and the shell is permanent and the shell is
@ -6485,7 +6501,7 @@ $ /bin/sleep 666 && echo fubar
.Ed .Ed
.Pp .Pp
This document attempts to describe This document attempts to describe
.Nm mksh\ R50 .Nm mksh\ R51beta
and up, and up,
compiled without any options impacting functionality, such as compiled without any options impacting functionality, such as
.Dv MKSH_SMALL , .Dv MKSH_SMALL ,

5
sh.h
View File

@ -169,9 +169,9 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R50 2015/01/25" #define MKSH_VERSION "R50 2015/02/06"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -1237,6 +1237,7 @@ struct block {
/* Values for struct block.flags */ /* Values for struct block.flags */
#define BF_DOGETOPTS BIT(0) /* save/restore getopts state */ #define BF_DOGETOPTS BIT(0) /* save/restore getopts state */
#define BF_STOPENV BIT(1) /* do not export further */
/* /*
* Used by ktwalk() and ktnext() routines. * Used by ktwalk() and ktnext() routines.

6
var.c
View File

@ -2,7 +2,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014 * 2011, 2012, 2013, 2014, 2015
* Thorsten Glaser <tg@mirbsd.org> * Thorsten Glaser <tg@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
@ -28,7 +28,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #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 * Variables
@ -1112,6 +1112,8 @@ makenv(void)
} }
XPput(denv, vp->val.s); XPput(denv, vp->val.s);
} }
if (l->flags & BF_STOPENV)
break;
} }
XPput(denv, NULL); XPput(denv, NULL);
return ((char **)XPclose(denv)); return ((char **)XPclose(denv));