From a3483db55f6ed39ed1ca42f7cceb7fb4a3fa7535 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 24 Oct 2001 08:01:06 +0000 Subject: Patch from vodz: 1) complete true: $ > /tmp/tmpfile 2) the builtin pwd now does not unwrap symlinks 3) reduce 680 bytes --- shell/ash.c | 163 +++++++++++------------------------------------------------- 1 file changed, 30 insertions(+), 133 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 9cc2208..8544d81 100644 --- a/shell/ash.c +++ b/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); @@ -1861,32 +1812,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 * that the current directory has changed. @@ -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 * 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) { -- cgit v1.1