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:
Eric Andersen 2001-10-24 08:01:06 +00:00
parent 3cd2760ba1
commit a3483db55f

View File

@ -1556,9 +1556,7 @@ static int hashcmd (int, char **);
static int helpcmd (int, char **); static int helpcmd (int, char **);
static int jobscmd (int, char **); static int jobscmd (int, char **);
static int localcmd (int, char **); static int localcmd (int, char **);
#ifndef CONFIG_PWD
static int pwdcmd (int, char **); static int pwdcmd (int, char **);
#endif
static int readcmd (int, char **); static int readcmd (int, char **);
static int returncmd (int, char **); static int returncmd (int, char **);
static int setcmd (int, char **); static int setcmd (int, char **);
@ -1653,9 +1651,7 @@ static const struct builtincmd builtincmds[] = {
{ BUILTIN_REGULAR "let", letcmd }, { BUILTIN_REGULAR "let", letcmd },
#endif #endif
{ BUILTIN_ASSIGN "local", localcmd }, { BUILTIN_ASSIGN "local", localcmd },
#ifndef CONFIG_PWD
{ BUILTIN_NOSPEC "pwd", pwdcmd }, { BUILTIN_NOSPEC "pwd", pwdcmd },
#endif
{ BUILTIN_REGULAR "read", readcmd }, { BUILTIN_REGULAR "read", readcmd },
{ BUILTIN_SPEC_ASSG "readonly", exportcmd }, { BUILTIN_SPEC_ASSG "readonly", exportcmd },
{ BUILTIN_SPECIAL "return", returncmd }, { BUILTIN_SPECIAL "return", returncmd },
@ -1736,7 +1732,6 @@ static int forkshell (struct job *, const union node *, int);
static int waitforjob (struct job *); static int waitforjob (struct job *);
static int docd (char *, int); static int docd (char *, int);
static char *getcomponent (void);
static void updatepwd (const char *); static void updatepwd (const char *);
static void getpwd (void); static void getpwd (void);
@ -1744,7 +1739,6 @@ static char *padvance (const char **, const char *);
static char nullstr[1]; /* zero length string */ static char nullstr[1]; /* zero length string */
static char *curdir = nullstr; /* current working directory */ static char *curdir = nullstr; /* current working directory */
static char *cdcomppath;
static int static int
cdcmd(argc, argv) cdcmd(argc, argv)
@ -1801,58 +1795,15 @@ cdcmd(argc, argv)
*/ */
static int static int
docd(dest, print) docd(char *dest, int print)
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)); 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; INTOFF;
if (chdir(dest) < 0) { if (chdir(dest) < 0) {
INTON; INTON;
return -1; return -1;
} }
updatepwd(badstat ? NULL : dest); updatepwd(dest);
INTON; INTON;
if (print && iflag) if (print && iflag)
printf(snlfmt, curdir); 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 * 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 * cd command. We also call hashcd to let the routines in exec.c know
@ -1897,62 +1822,25 @@ static void hashcd (void);
static void static void
updatepwd(const char *dir) updatepwd(const char *dir)
{ {
char *new;
char *p;
size_t len;
hashcd(); /* update command hash table */ hashcd(); /* update command hash table */
/* /* If our argument is NULL, we don't know the current directory */
* 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 (dir == NULL || curdir == nullstr) { if (dir == NULL || curdir == nullstr) {
setpwd(0, 1); setpwd(0, 1);
return; return;
} }
len = strlen(dir); setpwd(dir, 1);
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);
} }
#ifndef CONFIG_PWD
static int static int
pwdcmd(argc, argv) pwdcmd(int argc, char **argv)
int argc;
char **argv;
{ {
printf(snlfmt, curdir); printf(snlfmt, curdir);
return 0; return 0;
} }
#endif
/* /* Ask system the current directory */
* Find out what the current directory is. If we already know the current
* directory, this routine returns immediately.
*/
static void static void
getpwd(void) getpwd(void)
{ {
@ -1964,19 +1852,22 @@ getpwd(void)
static void static void
setpwd(const char *val, int setold) setpwd(const char *val, int setold)
{ {
char *cated = NULL;
if (setold) { if (setold) {
setvar("OLDPWD", curdir, VEXPORT); setvar("OLDPWD", curdir, VEXPORT);
} }
INTOFF; INTOFF;
if (curdir != nullstr) { if (curdir != nullstr) {
if(val!=NULL && *val != '/')
val = cated = concat_path_file(curdir, val);
free(curdir); free(curdir);
curdir = nullstr;
} }
if (!val) { if (!val)
getpwd(); getpwd();
} else { else
curdir = savestr(val); curdir = simplify_path(val);
} free(cated);
INTON; INTON;
setvar("PWD", curdir, VEXPORT); setvar("PWD", curdir, VEXPORT);
} }
@ -5950,6 +5841,7 @@ init(void) {
/* from cd.c: */ /* from cd.c: */
{ {
curdir = nullstr;
setpwd(0, 0); setpwd(0, 0);
} }
@ -7939,7 +7831,6 @@ readcmdfile(const char *name)
* search for the file, which is necessary to find sub-commands. * search for the file, which is necessary to find sub-commands.
*/ */
static inline char * static inline char *
find_dot_file(char *mybasename) find_dot_file(char *mybasename)
{ {
@ -9633,7 +9524,7 @@ static union node *list (int);
static union node *andor (void); static union node *andor (void);
static union node *pipeline (void); static union node *pipeline (void);
static union node *command (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 parsefname (void);
static void parseheredoc (void); static void parseheredoc (void);
static char peektoken (void); static char peektoken (void);
@ -9816,7 +9707,7 @@ pipeline() {
static union node * static union node *
command() { command(void) {
union node *n1, *n2; union node *n1, *n2;
union node *ap, **app; union node *ap, **app;
union node *cp, **cpp; union node *cp, **cpp;
@ -10005,7 +9896,7 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : ""));
synexpect(-1); synexpect(-1);
case TWORD: case TWORD:
tokpushback++; tokpushback++;
n1 = simplecmd(); n1 = simplecmd(rpp, redir);
return n1; return n1;
default: default:
synexpect(-1); synexpect(-1);
@ -10035,18 +9926,25 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : ""));
static union node * static union node *
simplecmd() { simplecmd(union node **rpp, union node *redir) {
union node *args, **app; union node *args, **app;
union node *n = NULL; union node *n = NULL;
union node *vars, **vpp; union node *vars, **vpp;
union node **rpp, *redir; union node **orig_rpp;
args = NULL; args = NULL;
app = &args; app = &args;
vars = NULL; vars = NULL;
vpp = &vars; 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; 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; checkalias = 2;
for (;;) { for (;;) {
@ -10073,7 +9971,7 @@ simplecmd() {
case TLP: case TLP:
if ( if (
args && app == &args->narg.next && args && app == &args->narg.next &&
!vars && !redir !vars && rpp == orig_rpp
) { ) {
/* We have a function */ /* We have a function */
if (readtoken() != TRP) if (readtoken() != TRP)
@ -10459,7 +10357,6 @@ breakloop:
} }
#endif #endif
/* /*
* If eofmark is NULL, read a word or a redirection symbol. If eofmark * 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 * 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> * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin. * 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) static int timescmd (int argc, char **argv)
{ {