diff --git a/check.t b/check.t index cf04350..fa15f9d 100644 --- a/check.t +++ b/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 diff --git a/funcs.c b/funcs.c index e5af13c..1263d5c 100644 --- a/funcs.c +++ b/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); +} diff --git a/main.c b/main.c index 440790e..626b530 100644 --- a/main.c +++ b/main.c @@ -13,7 +13,7 @@ #include #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(); diff --git a/mksh.1 b/mksh.1 index 044d9fd..87bf625 100644 --- a/mksh.1 +++ b/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 , diff --git a/sh.h b/sh.h index 82878ed..4aa6ba2 100644 --- a/sh.h +++ b/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 @@ -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 *);