new builtin “rename” (this name sounds better than “mksh_mv_rescue” ☻)
to just call rename(2) directly, e.g. if /bin/mv needs /lib/ld-uClibc.so.0 some assorted code cleanup
This commit is contained in:
		
							
								
								
									
										4
									
								
								check.t
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								check.t
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # $MirOS: src/bin/mksh/check.t,v 1.135 2007/08/18 00:22:07 tg Exp $ | ||||
| # $MirOS: src/bin/mksh/check.t,v 1.136 2007/08/19 22:06:25 tg Exp $ | ||||
| # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | ||||
| # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | ||||
| # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | ||||
| @@ -7,7 +7,7 @@ | ||||
| # http://www.research.att.com/~gsf/public/ifs.sh | ||||
|  | ||||
| expected-stdout: | ||||
| 	@(#)MIRBSD KSH R31 2007/08/18 | ||||
| 	@(#)MIRBSD KSH R31 2007/08/19 | ||||
| description: | ||||
| 	Check version of shell. | ||||
| category: pdksh | ||||
|   | ||||
							
								
								
									
										272
									
								
								funcs.c
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								funcs.c
									
									
									
									
									
								
							| @@ -5,7 +5,126 @@ | ||||
|  | ||||
| #include "sh.h" | ||||
|  | ||||
| __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.62 2007/07/31 13:55:26 tg Exp $"); | ||||
| __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.63 2007/08/19 22:06:26 tg Exp $"); | ||||
|  | ||||
| /* A leading = means assignments before command are kept; | ||||
|  * a leading * means a POSIX special builtin; | ||||
|  * a leading + means a POSIX regular builtin | ||||
|  * (* and + should not be combined). | ||||
|  */ | ||||
| const struct builtin mkshbuiltins[] = { | ||||
| 	{"*=.", c_dot}, | ||||
| 	{"*=:", c_label}, | ||||
| 	{"[", c_test}, | ||||
| 	{"*=break", c_brkcont}, | ||||
| 	{"=builtin", c_builtin}, | ||||
| 	{"*=continue", c_brkcont}, | ||||
| 	{"*=eval", c_eval}, | ||||
| 	{"*=exec", c_exec}, | ||||
| 	{"*=exit", c_exitreturn}, | ||||
| 	{"+false", c_label}, | ||||
| 	{"*=return", c_exitreturn}, | ||||
| 	{"*=set", c_set}, | ||||
| 	{"*=shift", c_shift}, | ||||
| 	{"=times", c_times}, | ||||
| 	{"*=trap", c_trap}, | ||||
| 	{"+=wait", c_wait}, | ||||
| 	{"+read", c_read}, | ||||
| 	{"test", c_test}, | ||||
| 	{"+true", c_label}, | ||||
| 	{"ulimit", c_ulimit}, | ||||
| 	{"+umask", c_umask}, | ||||
| 	{"*=unset", c_unset}, | ||||
| 	{"+alias", c_alias},	/* no =: at&t manual wrong */ | ||||
| 	{"+cd", c_cd}, | ||||
| 	{"+command", c_command}, | ||||
| 	{"echo", c_print}, | ||||
| 	{"*=export", c_typeset}, | ||||
| 	{"+fc", c_fc}, | ||||
| 	{"+getopts", c_getopts}, | ||||
| 	{"+jobs", c_jobs}, | ||||
| 	{"+kill", c_kill}, | ||||
| 	{"let", c_let}, | ||||
| 	{"print", c_print}, | ||||
| 	{"pwd", c_pwd}, | ||||
| 	{"*=readonly", c_typeset}, | ||||
| 	{"=typeset", c_typeset}, | ||||
| 	{"+unalias", c_unalias}, | ||||
| 	{"whence", c_whence}, | ||||
| 	{"+bg", c_fgbg}, | ||||
| 	{"+fg", c_fgbg}, | ||||
| 	{"bind", c_bind}, | ||||
| #if HAVE_MKNOD | ||||
| 	{"mknod", c_mknod}, | ||||
| #endif | ||||
| 	{"rename", c_rename}, | ||||
| 	{NULL, (int (*)(const char **))NULL} | ||||
| }; | ||||
|  | ||||
| struct kill_info { | ||||
| 	int num_width; | ||||
| 	int name_width; | ||||
| }; | ||||
|  | ||||
| static const struct t_op { | ||||
| 	char	op_text[4]; | ||||
| 	Test_op	op_num; | ||||
| } u_ops[] = { | ||||
| 	{"-a",	TO_FILAXST }, | ||||
| 	{"-b",	TO_FILBDEV }, | ||||
| 	{"-c",	TO_FILCDEV }, | ||||
| 	{"-d",	TO_FILID }, | ||||
| 	{"-e",	TO_FILEXST }, | ||||
| 	{"-f",	TO_FILREG }, | ||||
| 	{"-G",	TO_FILGID }, | ||||
| 	{"-g",	TO_FILSETG }, | ||||
| 	{"-h",	TO_FILSYM }, | ||||
| 	{"-H",	TO_FILCDF }, | ||||
| 	{"-k",	TO_FILSTCK }, | ||||
| 	{"-L",	TO_FILSYM }, | ||||
| 	{"-n",	TO_STNZE }, | ||||
| 	{"-O",	TO_FILUID }, | ||||
| 	{"-o",	TO_OPTION }, | ||||
| 	{"-p",	TO_FILFIFO }, | ||||
| 	{"-r",	TO_FILRD }, | ||||
| 	{"-s",	TO_FILGZ }, | ||||
| 	{"-S",	TO_FILSOCK }, | ||||
| 	{"-t",	TO_FILTT }, | ||||
| 	{"-u",	TO_FILSETU }, | ||||
| 	{"-w",	TO_FILWR }, | ||||
| 	{"-x",	TO_FILEX }, | ||||
| 	{"-z",	TO_STZER }, | ||||
| 	{"",	TO_NONOP } | ||||
| }; | ||||
| static const struct t_op b_ops[] = { | ||||
| 	{"=",	TO_STEQL }, | ||||
| 	{"==",	TO_STEQL }, | ||||
| 	{"!=",	TO_STNEQ }, | ||||
| 	{"<",	TO_STLT }, | ||||
| 	{">",	TO_STGT }, | ||||
| 	{"-eq",	TO_INTEQ }, | ||||
| 	{"-ne",	TO_INTNE }, | ||||
| 	{"-gt",	TO_INTGT }, | ||||
| 	{"-ge",	TO_INTGE }, | ||||
| 	{"-lt",	TO_INTLT }, | ||||
| 	{"-le",	TO_INTLE }, | ||||
| 	{"-ef",	TO_FILEQ }, | ||||
| 	{"-nt",	TO_FILNT }, | ||||
| 	{"-ot",	TO_FILOT }, | ||||
| 	{"",	TO_NONOP } | ||||
| }; | ||||
|  | ||||
| static int test_eaccess(const char *, int); | ||||
| static int test_oexpr(Test_env *, int); | ||||
| static int test_aexpr(Test_env *, int); | ||||
| static int test_nexpr(Test_env *, int); | ||||
| static int test_primary(Test_env *, int); | ||||
| static int ptest_isa(Test_env *, Test_meta); | ||||
| static const char *ptest_getopnd(Test_env *, Test_op, int); | ||||
| static void ptest_error(Test_env *, int, const char *); | ||||
| static char *kill_fmt_entry(const void *, int, char *, int); | ||||
| static void p_time(struct shf *, int, struct timeval *, int, | ||||
|     const char *, const char *); | ||||
|  | ||||
| int | ||||
| c_cd(const char **wp) | ||||
| @@ -1079,12 +1198,6 @@ c_fgbg(const char **wp) | ||||
| 	return bg ? 0 : rv; | ||||
| } | ||||
|  | ||||
| struct kill_info { | ||||
| 	int num_width; | ||||
| 	int name_width; | ||||
| }; | ||||
| static char *kill_fmt_entry(const void *, int, char *, int); | ||||
|  | ||||
| /* format a single kill item */ | ||||
| static char * | ||||
| kill_fmt_entry(const void *arg, int i, char *buf, int buflen) | ||||
| @@ -1099,7 +1212,6 @@ kill_fmt_entry(const void *arg, int i, char *buf, int buflen) | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| c_kill(const char **wp) | ||||
| { | ||||
| @@ -1348,37 +1460,6 @@ c_bind(const char **wp) | ||||
| 	return rv; | ||||
| } | ||||
|  | ||||
| /* A leading = means assignments before command are kept; | ||||
|  * a leading * means a POSIX special builtin; | ||||
|  * a leading + means a POSIX regular builtin | ||||
|  * (* and + should not be combined). | ||||
|  */ | ||||
| const struct builtin kshbuiltins [] = { | ||||
| 	{"+alias", c_alias},	/* no =: at&t manual wrong */ | ||||
| 	{"+cd", c_cd}, | ||||
| 	{"+command", c_command}, | ||||
| 	{"echo", c_print}, | ||||
| 	{"*=export", c_typeset}, | ||||
| 	{"+fc", c_fc}, | ||||
| 	{"+getopts", c_getopts}, | ||||
| 	{"+jobs", c_jobs}, | ||||
| 	{"+kill", c_kill}, | ||||
| 	{"let", c_let}, | ||||
| 	{"print", c_print}, | ||||
| 	{"pwd", c_pwd}, | ||||
| 	{"*=readonly", c_typeset}, | ||||
| 	{"=typeset", c_typeset}, | ||||
| 	{"+unalias", c_unalias}, | ||||
| 	{"whence", c_whence}, | ||||
| 	{"+bg", c_fgbg}, | ||||
| 	{"+fg", c_fgbg}, | ||||
| 	{"bind", c_bind}, | ||||
| 	{NULL, (int (*)(const char **))NULL} | ||||
| }; | ||||
|  | ||||
| static void p_time(struct shf *, int, struct timeval *, int, | ||||
|     const char *, const char *); | ||||
|  | ||||
| /* :, false and true */ | ||||
| int | ||||
| c_label(const char **wp) | ||||
| @@ -2204,7 +2285,7 @@ c_exec(const char **wp __unused) | ||||
| } | ||||
|  | ||||
| #if HAVE_MKNOD | ||||
| static int | ||||
| int | ||||
| c_mknod(const char **wp) | ||||
| { | ||||
| 	int argc, optc, rv = 0; | ||||
| @@ -2296,40 +2377,6 @@ c_builtin(const char **wp __unused) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* A leading = means assignments before command are kept; | ||||
|  * a leading * means a POSIX special builtin; | ||||
|  * a leading + means a POSIX regular builtin | ||||
|  * (* and + should not be combined). | ||||
|  */ | ||||
| const struct builtin shbuiltins [] = { | ||||
| 	{"*=.", c_dot}, | ||||
| 	{"*=:", c_label}, | ||||
| 	{"[", c_test}, | ||||
| 	{"*=break", c_brkcont}, | ||||
| 	{"=builtin", c_builtin}, | ||||
| 	{"*=continue", c_brkcont}, | ||||
| 	{"*=eval", c_eval}, | ||||
| 	{"*=exec", c_exec}, | ||||
| 	{"*=exit", c_exitreturn}, | ||||
| 	{"+false", c_label}, | ||||
| 	{"*=return", c_exitreturn}, | ||||
| 	{"*=set", c_set}, | ||||
| 	{"*=shift", c_shift}, | ||||
| 	{"=times", c_times}, | ||||
| 	{"*=trap", c_trap}, | ||||
| 	{"+=wait", c_wait}, | ||||
| 	{"+read", c_read}, | ||||
| 	{"test", c_test}, | ||||
| 	{"+true", c_label}, | ||||
| 	{"ulimit", c_ulimit}, | ||||
| 	{"+umask", c_umask}, | ||||
| 	{"*=unset", c_unset}, | ||||
| #if HAVE_MKNOD | ||||
| 	{"mknod", c_mknod}, | ||||
| #endif | ||||
| 	{NULL, (int (*)(const char **))NULL} | ||||
| }; | ||||
|  | ||||
| /* test(1) accepts the following grammar: | ||||
| 	oexpr	::= aexpr | aexpr "-o" oexpr ; | ||||
| 	aexpr	::= nexpr | nexpr "-a" aexpr ; | ||||
| @@ -2353,64 +2400,6 @@ const struct builtin shbuiltins [] = { | ||||
|  | ||||
| #define T_ERR_EXIT	2	/* POSIX says > 1 for errors */ | ||||
|  | ||||
| struct t_op { | ||||
| 	char	op_text[4]; | ||||
| 	Test_op	op_num; | ||||
| }; | ||||
| static const struct t_op u_ops [] = { | ||||
| 	{"-a",	TO_FILAXST }, | ||||
| 	{"-b",	TO_FILBDEV }, | ||||
| 	{"-c",	TO_FILCDEV }, | ||||
| 	{"-d",	TO_FILID }, | ||||
| 	{"-e",	TO_FILEXST }, | ||||
| 	{"-f",	TO_FILREG }, | ||||
| 	{"-G",	TO_FILGID }, | ||||
| 	{"-g",	TO_FILSETG }, | ||||
| 	{"-h",	TO_FILSYM }, | ||||
| 	{"-H",	TO_FILCDF }, | ||||
| 	{"-k",	TO_FILSTCK }, | ||||
| 	{"-L",	TO_FILSYM }, | ||||
| 	{"-n",	TO_STNZE }, | ||||
| 	{"-O",	TO_FILUID }, | ||||
| 	{"-o",	TO_OPTION }, | ||||
| 	{"-p",	TO_FILFIFO }, | ||||
| 	{"-r",	TO_FILRD }, | ||||
| 	{"-s",	TO_FILGZ }, | ||||
| 	{"-S",	TO_FILSOCK }, | ||||
| 	{"-t",	TO_FILTT }, | ||||
| 	{"-u",	TO_FILSETU }, | ||||
| 	{"-w",	TO_FILWR }, | ||||
| 	{"-x",	TO_FILEX }, | ||||
| 	{"-z",	TO_STZER }, | ||||
| 	{"",	TO_NONOP } | ||||
| }; | ||||
| static const struct t_op b_ops [] = { | ||||
| 	{"=",	TO_STEQL }, | ||||
| 	{"==",	TO_STEQL }, | ||||
| 	{"!=",	TO_STNEQ }, | ||||
| 	{"<",	TO_STLT }, | ||||
| 	{">",	TO_STGT }, | ||||
| 	{"-eq",	TO_INTEQ }, | ||||
| 	{"-ne",	TO_INTNE }, | ||||
| 	{"-gt",	TO_INTGT }, | ||||
| 	{"-ge",	TO_INTGE }, | ||||
| 	{"-lt",	TO_INTLT }, | ||||
| 	{"-le",	TO_INTLE }, | ||||
| 	{"-ef",	TO_FILEQ }, | ||||
| 	{"-nt",	TO_FILNT }, | ||||
| 	{"-ot",	TO_FILOT }, | ||||
| 	{"",	TO_NONOP } | ||||
| }; | ||||
|  | ||||
| static int	test_eaccess(const char *, int); | ||||
| static int	test_oexpr(Test_env *, int); | ||||
| static int	test_aexpr(Test_env *, int); | ||||
| static int	test_nexpr(Test_env *, int); | ||||
| static int	test_primary(Test_env *, int); | ||||
| static int	ptest_isa(Test_env *, Test_meta); | ||||
| static const char *ptest_getopnd(Test_env *, Test_op, int); | ||||
| static void	ptest_error(Test_env *, int, const char *); | ||||
|  | ||||
| int | ||||
| c_test(const char **wp) | ||||
| { | ||||
| @@ -3033,3 +3022,22 @@ c_ulimit(const char **wp) | ||||
| 	} | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
| int | ||||
| c_rename(const char **wp) | ||||
| { | ||||
| 	int rv = 1; | ||||
|  | ||||
| 	if (wp == NULL /* argv */ || | ||||
| 	    wp[0] == NULL /* name of builtin */ || | ||||
| 	    wp[1] == NULL /* first argument */ || | ||||
| 	    wp[2] == NULL /* second argument */ || | ||||
| 	    wp[3] != NULL /* no further args please */) | ||||
| 		bi_errorf("syntax error"); | ||||
| 	else if ((rv = rename(wp[1], wp[2])) != 0) { | ||||
| 		rv = errno; | ||||
| 		bi_errorf("failed: %s", strerror(rv)); | ||||
| 	} | ||||
|  | ||||
| 	return (rv); | ||||
| } | ||||
|   | ||||
							
								
								
									
										8
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								main.c
									
									
									
									
									
								
							| @@ -13,7 +13,7 @@ | ||||
| #include <locale.h> | ||||
| #endif | ||||
|  | ||||
| __RCSID("$MirOS: src/bin/mksh/main.c,v 1.86 2007/08/13 19:39:19 tg Exp $"); | ||||
| __RCSID("$MirOS: src/bin/mksh/main.c,v 1.87 2007/08/19 22:06:26 tg Exp $"); | ||||
|  | ||||
| extern char **environ; | ||||
|  | ||||
| @@ -125,10 +125,8 @@ main(int argc, const char *argv[]) | ||||
|  | ||||
| 	/* define built-in commands */ | ||||
| 	ktinit(&builtins, APERM, 64); /* must be 2^n (currently 40 builtins) */ | ||||
| 	for (i = 0; shbuiltins[i].name != NULL; i++) | ||||
| 		builtin(shbuiltins[i].name, shbuiltins[i].func); | ||||
| 	for (i = 0; kshbuiltins[i].name != NULL; i++) | ||||
| 		builtin(kshbuiltins[i].name, kshbuiltins[i].func); | ||||
| 	for (i = 0; mkshbuiltins[i].name != NULL; i++) | ||||
| 		builtin(mkshbuiltins[i].name, mkshbuiltins[i].func); | ||||
|  | ||||
| 	init_histvec(); | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								mksh.1
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								mksh.1
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| .\" $MirOS: src/bin/mksh/mksh.1,v 1.98 2007/08/18 01:20:28 tg Exp $ | ||||
| .\" $MirOS: src/bin/mksh/mksh.1,v 1.99 2007/08/19 22:06:26 tg Exp $ | ||||
| .\" $OpenBSD: ksh.1,v 1.120 2007/05/31 20:47:44 otto Exp $ | ||||
| .\" | ||||
| .Dd August 18, 2007 | ||||
| .Dd August 19, 2007 | ||||
| .Dt MKSH 1 | ||||
| .Os MirBSD | ||||
| .Sh NAME | ||||
| @@ -3183,6 +3183,17 @@ option is used, in which case | ||||
| commands defining all read-only parameters, including their values, are | ||||
| printed. | ||||
| .Pp | ||||
| .It Ic rename Ar from to | ||||
| Renames the file | ||||
| .Ar from | ||||
| to | ||||
| .Ar to . | ||||
| Both must be complete pathnames and on the same device. | ||||
| This builtin is intended for emergency situations where | ||||
| .Pa /bin/mv | ||||
| becomes unusable, and directly calls | ||||
| .Xr rename 2 . | ||||
| .Pp | ||||
| .It Ic return Op Ar status | ||||
| Returns from a function or | ||||
| .Ic .\& | ||||
| @@ -5283,6 +5294,7 @@ Privileged shell profile. | ||||
| .Xr mkfifo 2 , | ||||
| .Xr open 2 , | ||||
| .Xr pipe 2 , | ||||
| .Xr rename 2 , | ||||
| .Xr wait 2 , | ||||
| .Xr arc4random 3 , | ||||
| .Xr getopt 3 , | ||||
|   | ||||
							
								
								
									
										10
									
								
								sh.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								sh.h
									
									
									
									
									
								
							| @@ -8,8 +8,8 @@ | ||||
| /*	$OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $	*/ | ||||
| /*	$OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $	*/ | ||||
|  | ||||
| #define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.171 2007/08/18 00:22:09 tg Exp $" | ||||
| #define MKSH_VERSION "R31 2007/08/18" | ||||
| #define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.172 2007/08/19 22:06:27 tg Exp $" | ||||
| #define MKSH_VERSION "R31 2007/08/19" | ||||
|  | ||||
| #if HAVE_SYS_PARAM_H | ||||
| #include <sys/param.h> | ||||
| @@ -818,7 +818,7 @@ struct builtin { | ||||
| 	int (*func)(const char **); | ||||
| }; | ||||
|  | ||||
| extern const struct builtin shbuiltins [], kshbuiltins []; | ||||
| extern const struct builtin mkshbuiltins[]; | ||||
|  | ||||
| /* var spec values */ | ||||
| #define V_NONE		0 | ||||
| @@ -1271,6 +1271,10 @@ void timex_hook(struct op *, char ** volatile *); | ||||
| int c_exec(const char **); | ||||
| int c_builtin(const char **); | ||||
| int c_test(const char **); | ||||
| #if HAVE_MKNOD | ||||
| int c_mknod(const char **); | ||||
| #endif | ||||
| int c_rename(const char **); | ||||
| /* histrap.c */ | ||||
| void init_histvec(void); | ||||
| void hist_init(Source *); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user