mirror of
https://github.com/sheumann/hush.git
synced 2024-12-28 07:30:23 +00:00
Patch from vodz:
1) complete true: $ > /tmp/tmpfile 2) the builtin pwd now does not unwrap symlinks 3) reduce 680 bytes
This commit is contained in:
parent
3cd2760ba1
commit
a3483db55f
163
shell/ash.c
163
shell/ash.c
@ -1556,9 +1556,7 @@ static int hashcmd (int, char **);
|
||||
static int helpcmd (int, char **);
|
||||
static int jobscmd (int, char **);
|
||||
static int localcmd (int, char **);
|
||||
#ifndef CONFIG_PWD
|
||||
static int pwdcmd (int, char **);
|
||||
#endif
|
||||
static int readcmd (int, char **);
|
||||
static int returncmd (int, char **);
|
||||
static int setcmd (int, char **);
|
||||
@ -1653,9 +1651,7 @@ static const struct builtincmd builtincmds[] = {
|
||||
{ BUILTIN_REGULAR "let", letcmd },
|
||||
#endif
|
||||
{ BUILTIN_ASSIGN "local", localcmd },
|
||||
#ifndef CONFIG_PWD
|
||||
{ BUILTIN_NOSPEC "pwd", pwdcmd },
|
||||
#endif
|
||||
{ BUILTIN_REGULAR "read", readcmd },
|
||||
{ BUILTIN_SPEC_ASSG "readonly", exportcmd },
|
||||
{ BUILTIN_SPECIAL "return", returncmd },
|
||||
@ -1736,7 +1732,6 @@ static int forkshell (struct job *, const union node *, int);
|
||||
static int waitforjob (struct job *);
|
||||
|
||||
static int docd (char *, int);
|
||||
static char *getcomponent (void);
|
||||
static void updatepwd (const char *);
|
||||
static void getpwd (void);
|
||||
|
||||
@ -1744,7 +1739,6 @@ static char *padvance (const char **, const char *);
|
||||
|
||||
static char nullstr[1]; /* zero length string */
|
||||
static char *curdir = nullstr; /* current working directory */
|
||||
static char *cdcomppath;
|
||||
|
||||
static int
|
||||
cdcmd(argc, argv)
|
||||
@ -1801,58 +1795,15 @@ cdcmd(argc, argv)
|
||||
*/
|
||||
|
||||
static int
|
||||
docd(dest, print)
|
||||
char *dest;
|
||||
int print;
|
||||
docd(char *dest, int print)
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
char *component;
|
||||
struct stat statb;
|
||||
int first;
|
||||
int badstat;
|
||||
|
||||
TRACE(("docd(\"%s\", %d) called\n", dest, print));
|
||||
|
||||
/*
|
||||
* Check each component of the path. If we find a symlink or
|
||||
* something we can't stat, clear curdir to force a getcwd()
|
||||
* next time we get the value of the current directory.
|
||||
*/
|
||||
badstat = 0;
|
||||
cdcomppath = sstrdup(dest);
|
||||
STARTSTACKSTR(p);
|
||||
if (*dest == '/') {
|
||||
STPUTC('/', p);
|
||||
cdcomppath++;
|
||||
}
|
||||
first = 1;
|
||||
while ((q = getcomponent()) != NULL) {
|
||||
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
|
||||
continue;
|
||||
if (! first)
|
||||
STPUTC('/', p);
|
||||
first = 0;
|
||||
component = q;
|
||||
while (*q)
|
||||
STPUTC(*q++, p);
|
||||
if (equal(component, ".."))
|
||||
continue;
|
||||
STACKSTRNUL(p);
|
||||
if ((lstat(stackblock(), &statb) < 0)
|
||||
|| (S_ISLNK(statb.st_mode))) {
|
||||
/* print = 1; */
|
||||
badstat = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INTOFF;
|
||||
if (chdir(dest) < 0) {
|
||||
INTON;
|
||||
return -1;
|
||||
}
|
||||
updatepwd(badstat ? NULL : dest);
|
||||
updatepwd(dest);
|
||||
INTON;
|
||||
if (print && iflag)
|
||||
printf(snlfmt, curdir);
|
||||
@ -1860,32 +1811,6 @@ docd(dest, print)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the next component of the path name pointed to by cdcomppath.
|
||||
* This routine overwrites the string pointed to by cdcomppath.
|
||||
*/
|
||||
|
||||
static char *
|
||||
getcomponent() {
|
||||
char *p;
|
||||
char *start;
|
||||
|
||||
if ((p = cdcomppath) == NULL)
|
||||
return NULL;
|
||||
start = cdcomppath;
|
||||
while (*p != '/' && *p != '\0')
|
||||
p++;
|
||||
if (*p == '\0') {
|
||||
cdcomppath = NULL;
|
||||
} else {
|
||||
*p++ = '\0';
|
||||
cdcomppath = p;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Update curdir (the name of the current directory) in response to a
|
||||
* cd command. We also call hashcd to let the routines in exec.c know
|
||||
@ -1897,62 +1822,25 @@ static void hashcd (void);
|
||||
static void
|
||||
updatepwd(const char *dir)
|
||||
{
|
||||
char *new;
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
hashcd(); /* update command hash table */
|
||||
|
||||
/*
|
||||
* If our argument is NULL, we don't know the current directory
|
||||
* any more because we traversed a symbolic link or something
|
||||
* we couldn't stat().
|
||||
*/
|
||||
/* If our argument is NULL, we don't know the current directory */
|
||||
if (dir == NULL || curdir == nullstr) {
|
||||
setpwd(0, 1);
|
||||
return;
|
||||
}
|
||||
len = strlen(dir);
|
||||
cdcomppath = sstrdup(dir);
|
||||
STARTSTACKSTR(new);
|
||||
if (*dir != '/') {
|
||||
p = curdir;
|
||||
while (*p)
|
||||
STPUTC(*p++, new);
|
||||
if (p[-1] == '/')
|
||||
STUNPUTC(new);
|
||||
}
|
||||
while ((p = getcomponent()) != NULL) {
|
||||
if (equal(p, "..")) {
|
||||
while (new > stackblock() && (STUNPUTC(new), *new) != '/');
|
||||
} else if (*p != '\0' && ! equal(p, ".")) {
|
||||
STPUTC('/', new);
|
||||
while (*p)
|
||||
STPUTC(*p++, new);
|
||||
}
|
||||
}
|
||||
if (new == stackblock())
|
||||
STPUTC('/', new);
|
||||
STACKSTRNUL(new);
|
||||
setpwd(stackblock(), 1);
|
||||
setpwd(dir, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_PWD
|
||||
static int
|
||||
pwdcmd(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
pwdcmd(int argc, char **argv)
|
||||
{
|
||||
printf(snlfmt, curdir);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find out what the current directory is. If we already know the current
|
||||
* directory, this routine returns immediately.
|
||||
*/
|
||||
/* Ask system the current directory */
|
||||
static void
|
||||
getpwd(void)
|
||||
{
|
||||
@ -1964,19 +1852,22 @@ getpwd(void)
|
||||
static void
|
||||
setpwd(const char *val, int setold)
|
||||
{
|
||||
char *cated = NULL;
|
||||
|
||||
if (setold) {
|
||||
setvar("OLDPWD", curdir, VEXPORT);
|
||||
}
|
||||
INTOFF;
|
||||
if (curdir != nullstr) {
|
||||
if(val!=NULL && *val != '/')
|
||||
val = cated = concat_path_file(curdir, val);
|
||||
free(curdir);
|
||||
curdir = nullstr;
|
||||
}
|
||||
if (!val) {
|
||||
if (!val)
|
||||
getpwd();
|
||||
} else {
|
||||
curdir = savestr(val);
|
||||
}
|
||||
else
|
||||
curdir = simplify_path(val);
|
||||
free(cated);
|
||||
INTON;
|
||||
setvar("PWD", curdir, VEXPORT);
|
||||
}
|
||||
@ -5950,6 +5841,7 @@ init(void) {
|
||||
|
||||
/* from cd.c: */
|
||||
{
|
||||
curdir = nullstr;
|
||||
setpwd(0, 0);
|
||||
}
|
||||
|
||||
@ -7939,7 +7831,6 @@ readcmdfile(const char *name)
|
||||
* search for the file, which is necessary to find sub-commands.
|
||||
*/
|
||||
|
||||
|
||||
static inline char *
|
||||
find_dot_file(char *mybasename)
|
||||
{
|
||||
@ -9633,7 +9524,7 @@ static union node *list (int);
|
||||
static union node *andor (void);
|
||||
static union node *pipeline (void);
|
||||
static union node *command (void);
|
||||
static union node *simplecmd (void);
|
||||
static union node *simplecmd(union node **rpp, union node *redir);
|
||||
static void parsefname (void);
|
||||
static void parseheredoc (void);
|
||||
static char peektoken (void);
|
||||
@ -9816,7 +9707,7 @@ pipeline() {
|
||||
|
||||
|
||||
static union node *
|
||||
command() {
|
||||
command(void) {
|
||||
union node *n1, *n2;
|
||||
union node *ap, **app;
|
||||
union node *cp, **cpp;
|
||||
@ -10005,7 +9896,7 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : ""));
|
||||
synexpect(-1);
|
||||
case TWORD:
|
||||
tokpushback++;
|
||||
n1 = simplecmd();
|
||||
n1 = simplecmd(rpp, redir);
|
||||
return n1;
|
||||
default:
|
||||
synexpect(-1);
|
||||
@ -10035,18 +9926,25 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : ""));
|
||||
|
||||
|
||||
static union node *
|
||||
simplecmd() {
|
||||
simplecmd(union node **rpp, union node *redir) {
|
||||
union node *args, **app;
|
||||
union node *n = NULL;
|
||||
union node *vars, **vpp;
|
||||
union node **rpp, *redir;
|
||||
union node **orig_rpp;
|
||||
|
||||
args = NULL;
|
||||
app = &args;
|
||||
vars = NULL;
|
||||
vpp = &vars;
|
||||
redir = NULL;
|
||||
|
||||
/* If we don't have any redirections already, then we must reset
|
||||
rpp to be the address of the local redir variable. */
|
||||
if (redir == 0)
|
||||
rpp = &redir;
|
||||
/* We save the incoming value, because we need this for shell
|
||||
functions. There can not be a redirect or an argument between
|
||||
the function name and the open parenthesis. */
|
||||
orig_rpp = rpp;
|
||||
|
||||
checkalias = 2;
|
||||
for (;;) {
|
||||
@ -10073,7 +9971,7 @@ simplecmd() {
|
||||
case TLP:
|
||||
if (
|
||||
args && app == &args->narg.next &&
|
||||
!vars && !redir
|
||||
!vars && rpp == orig_rpp
|
||||
) {
|
||||
/* We have a function */
|
||||
if (readtoken() != TRP)
|
||||
@ -10459,7 +10357,6 @@ breakloop:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If eofmark is NULL, read a word or a redirection symbol. If eofmark
|
||||
* is not NULL, read a here document. In the latter case, eofmark is the
|
||||
@ -12730,7 +12627,7 @@ findvar(struct var **vpp, const char *name)
|
||||
/*
|
||||
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
|
||||
* This file contains code for the times builtin.
|
||||
* $Id: ash.c,v 1.29 2001/10/24 05:00:16 andersen Exp $
|
||||
* $Id: ash.c,v 1.30 2001/10/24 08:01:06 andersen Exp $
|
||||
*/
|
||||
static int timescmd (int argc, char **argv)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user