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:
tg 2007-08-19 22:06:27 +00:00
parent 49c95a8938
commit ca46f3dc98
5 changed files with 166 additions and 144 deletions

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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 *);