add getopts for exec (unbreaks “exec -- /bin/ls”) and steal -a and -c from ksh93
This commit is contained in:
		
							
								
								
									
										6
									
								
								check.t
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								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 -*- | # -*- 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: | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								exec.c
									
									
									
									
									
								
							| @@ -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,12 +831,22 @@ 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); | ||||||
|  |  | ||||||
|  | 		/* 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 (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 | ||||||
| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								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 $ | .\" $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
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								sh.h
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								var.c
									
									
									
									
									
								
							| @@ -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)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user