diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-10-24 08:01:06 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-10-24 08:01:06 +0000 |
commit | a3483db55f6ed39ed1ca42f7cceb7fb4a3fa7535 (patch) | |
tree | f179ffc2c44c1da582c617b67004355a2f877372 | |
parent | 3cd2760ba1b235f3ead9feaaa1d3c41def3fb3bc (diff) | |
download | busybox-w32-a3483db55f6ed39ed1ca42f7cceb7fb4a3fa7535.tar.gz busybox-w32-a3483db55f6ed39ed1ca42f7cceb7fb4a3fa7535.tar.bz2 busybox-w32-a3483db55f6ed39ed1ca42f7cceb7fb4a3fa7535.zip |
Patch from vodz:
1) complete true: $ > /tmp/tmpfile
2) the builtin pwd now does not unwrap symlinks
3) reduce 680 bytes
-rw-r--r-- | shell/ash.c | 163 |
1 files changed, 30 insertions, 133 deletions
diff --git a/shell/ash.c b/shell/ash.c index 9cc2208ab..8544d8131 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -1556,9 +1556,7 @@ static int hashcmd (int, char **); | |||
1556 | static int helpcmd (int, char **); | 1556 | static int helpcmd (int, char **); |
1557 | static int jobscmd (int, char **); | 1557 | static int jobscmd (int, char **); |
1558 | static int localcmd (int, char **); | 1558 | static int localcmd (int, char **); |
1559 | #ifndef CONFIG_PWD | ||
1560 | static int pwdcmd (int, char **); | 1559 | static int pwdcmd (int, char **); |
1561 | #endif | ||
1562 | static int readcmd (int, char **); | 1560 | static int readcmd (int, char **); |
1563 | static int returncmd (int, char **); | 1561 | static int returncmd (int, char **); |
1564 | static int setcmd (int, char **); | 1562 | static int setcmd (int, char **); |
@@ -1653,9 +1651,7 @@ static const struct builtincmd builtincmds[] = { | |||
1653 | { BUILTIN_REGULAR "let", letcmd }, | 1651 | { BUILTIN_REGULAR "let", letcmd }, |
1654 | #endif | 1652 | #endif |
1655 | { BUILTIN_ASSIGN "local", localcmd }, | 1653 | { BUILTIN_ASSIGN "local", localcmd }, |
1656 | #ifndef CONFIG_PWD | ||
1657 | { BUILTIN_NOSPEC "pwd", pwdcmd }, | 1654 | { BUILTIN_NOSPEC "pwd", pwdcmd }, |
1658 | #endif | ||
1659 | { BUILTIN_REGULAR "read", readcmd }, | 1655 | { BUILTIN_REGULAR "read", readcmd }, |
1660 | { BUILTIN_SPEC_ASSG "readonly", exportcmd }, | 1656 | { BUILTIN_SPEC_ASSG "readonly", exportcmd }, |
1661 | { BUILTIN_SPECIAL "return", returncmd }, | 1657 | { BUILTIN_SPECIAL "return", returncmd }, |
@@ -1736,7 +1732,6 @@ static int forkshell (struct job *, const union node *, int); | |||
1736 | static int waitforjob (struct job *); | 1732 | static int waitforjob (struct job *); |
1737 | 1733 | ||
1738 | static int docd (char *, int); | 1734 | static int docd (char *, int); |
1739 | static char *getcomponent (void); | ||
1740 | static void updatepwd (const char *); | 1735 | static void updatepwd (const char *); |
1741 | static void getpwd (void); | 1736 | static void getpwd (void); |
1742 | 1737 | ||
@@ -1744,7 +1739,6 @@ static char *padvance (const char **, const char *); | |||
1744 | 1739 | ||
1745 | static char nullstr[1]; /* zero length string */ | 1740 | static char nullstr[1]; /* zero length string */ |
1746 | static char *curdir = nullstr; /* current working directory */ | 1741 | static char *curdir = nullstr; /* current working directory */ |
1747 | static char *cdcomppath; | ||
1748 | 1742 | ||
1749 | static int | 1743 | static int |
1750 | cdcmd(argc, argv) | 1744 | cdcmd(argc, argv) |
@@ -1801,58 +1795,15 @@ cdcmd(argc, argv) | |||
1801 | */ | 1795 | */ |
1802 | 1796 | ||
1803 | static int | 1797 | static int |
1804 | docd(dest, print) | 1798 | docd(char *dest, int print) |
1805 | char *dest; | ||
1806 | int print; | ||
1807 | { | 1799 | { |
1808 | char *p; | ||
1809 | char *q; | ||
1810 | char *component; | ||
1811 | struct stat statb; | ||
1812 | int first; | ||
1813 | int badstat; | ||
1814 | |||
1815 | TRACE(("docd(\"%s\", %d) called\n", dest, print)); | 1800 | TRACE(("docd(\"%s\", %d) called\n", dest, print)); |
1816 | |||
1817 | /* | ||
1818 | * Check each component of the path. If we find a symlink or | ||
1819 | * something we can't stat, clear curdir to force a getcwd() | ||
1820 | * next time we get the value of the current directory. | ||
1821 | */ | ||
1822 | badstat = 0; | ||
1823 | cdcomppath = sstrdup(dest); | ||
1824 | STARTSTACKSTR(p); | ||
1825 | if (*dest == '/') { | ||
1826 | STPUTC('/', p); | ||
1827 | cdcomppath++; | ||
1828 | } | ||
1829 | first = 1; | ||
1830 | while ((q = getcomponent()) != NULL) { | ||
1831 | if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) | ||
1832 | continue; | ||
1833 | if (! first) | ||
1834 | STPUTC('/', p); | ||
1835 | first = 0; | ||
1836 | component = q; | ||
1837 | while (*q) | ||
1838 | STPUTC(*q++, p); | ||
1839 | if (equal(component, "..")) | ||
1840 | continue; | ||
1841 | STACKSTRNUL(p); | ||
1842 | if ((lstat(stackblock(), &statb) < 0) | ||
1843 | || (S_ISLNK(statb.st_mode))) { | ||
1844 | /* print = 1; */ | ||
1845 | badstat = 1; | ||
1846 | break; | ||
1847 | } | ||
1848 | } | ||
1849 | |||
1850 | INTOFF; | 1801 | INTOFF; |
1851 | if (chdir(dest) < 0) { | 1802 | if (chdir(dest) < 0) { |
1852 | INTON; | 1803 | INTON; |
1853 | return -1; | 1804 | return -1; |
1854 | } | 1805 | } |
1855 | updatepwd(badstat ? NULL : dest); | 1806 | updatepwd(dest); |
1856 | INTON; | 1807 | INTON; |
1857 | if (print && iflag) | 1808 | if (print && iflag) |
1858 | printf(snlfmt, curdir); | 1809 | printf(snlfmt, curdir); |
@@ -1861,32 +1812,6 @@ docd(dest, print) | |||
1861 | 1812 | ||
1862 | 1813 | ||
1863 | /* | 1814 | /* |
1864 | * Get the next component of the path name pointed to by cdcomppath. | ||
1865 | * This routine overwrites the string pointed to by cdcomppath. | ||
1866 | */ | ||
1867 | |||
1868 | static char * | ||
1869 | getcomponent() { | ||
1870 | char *p; | ||
1871 | char *start; | ||
1872 | |||
1873 | if ((p = cdcomppath) == NULL) | ||
1874 | return NULL; | ||
1875 | start = cdcomppath; | ||
1876 | while (*p != '/' && *p != '\0') | ||
1877 | p++; | ||
1878 | if (*p == '\0') { | ||
1879 | cdcomppath = NULL; | ||
1880 | } else { | ||
1881 | *p++ = '\0'; | ||
1882 | cdcomppath = p; | ||
1883 | } | ||
1884 | return start; | ||
1885 | } | ||
1886 | |||
1887 | |||
1888 | |||
1889 | /* | ||
1890 | * Update curdir (the name of the current directory) in response to a | 1815 | * Update curdir (the name of the current directory) in response to a |
1891 | * cd command. We also call hashcd to let the routines in exec.c know | 1816 | * cd command. We also call hashcd to let the routines in exec.c know |
1892 | * that the current directory has changed. | 1817 | * that the current directory has changed. |
@@ -1897,62 +1822,25 @@ static void hashcd (void); | |||
1897 | static void | 1822 | static void |
1898 | updatepwd(const char *dir) | 1823 | updatepwd(const char *dir) |
1899 | { | 1824 | { |
1900 | char *new; | ||
1901 | char *p; | ||
1902 | size_t len; | ||
1903 | |||
1904 | hashcd(); /* update command hash table */ | 1825 | hashcd(); /* update command hash table */ |
1905 | 1826 | ||
1906 | /* | 1827 | /* If our argument is NULL, we don't know the current directory */ |
1907 | * If our argument is NULL, we don't know the current directory | ||
1908 | * any more because we traversed a symbolic link or something | ||
1909 | * we couldn't stat(). | ||
1910 | */ | ||
1911 | if (dir == NULL || curdir == nullstr) { | 1828 | if (dir == NULL || curdir == nullstr) { |
1912 | setpwd(0, 1); | 1829 | setpwd(0, 1); |
1913 | return; | 1830 | return; |
1914 | } | 1831 | } |
1915 | len = strlen(dir); | 1832 | setpwd(dir, 1); |
1916 | cdcomppath = sstrdup(dir); | ||
1917 | STARTSTACKSTR(new); | ||
1918 | if (*dir != '/') { | ||
1919 | p = curdir; | ||
1920 | while (*p) | ||
1921 | STPUTC(*p++, new); | ||
1922 | if (p[-1] == '/') | ||
1923 | STUNPUTC(new); | ||
1924 | } | ||
1925 | while ((p = getcomponent()) != NULL) { | ||
1926 | if (equal(p, "..")) { | ||
1927 | while (new > stackblock() && (STUNPUTC(new), *new) != '/'); | ||
1928 | } else if (*p != '\0' && ! equal(p, ".")) { | ||
1929 | STPUTC('/', new); | ||
1930 | while (*p) | ||
1931 | STPUTC(*p++, new); | ||
1932 | } | ||
1933 | } | ||
1934 | if (new == stackblock()) | ||
1935 | STPUTC('/', new); | ||
1936 | STACKSTRNUL(new); | ||
1937 | setpwd(stackblock(), 1); | ||
1938 | } | 1833 | } |
1939 | 1834 | ||
1940 | 1835 | ||
1941 | #ifndef CONFIG_PWD | ||
1942 | static int | 1836 | static int |
1943 | pwdcmd(argc, argv) | 1837 | pwdcmd(int argc, char **argv) |
1944 | int argc; | ||
1945 | char **argv; | ||
1946 | { | 1838 | { |
1947 | printf(snlfmt, curdir); | 1839 | printf(snlfmt, curdir); |
1948 | return 0; | 1840 | return 0; |
1949 | } | 1841 | } |
1950 | #endif | ||
1951 | 1842 | ||
1952 | /* | 1843 | /* Ask system the current directory */ |
1953 | * Find out what the current directory is. If we already know the current | ||
1954 | * directory, this routine returns immediately. | ||
1955 | */ | ||
1956 | static void | 1844 | static void |
1957 | getpwd(void) | 1845 | getpwd(void) |
1958 | { | 1846 | { |
@@ -1964,19 +1852,22 @@ getpwd(void) | |||
1964 | static void | 1852 | static void |
1965 | setpwd(const char *val, int setold) | 1853 | setpwd(const char *val, int setold) |
1966 | { | 1854 | { |
1855 | char *cated = NULL; | ||
1856 | |||
1967 | if (setold) { | 1857 | if (setold) { |
1968 | setvar("OLDPWD", curdir, VEXPORT); | 1858 | setvar("OLDPWD", curdir, VEXPORT); |
1969 | } | 1859 | } |
1970 | INTOFF; | 1860 | INTOFF; |
1971 | if (curdir != nullstr) { | 1861 | if (curdir != nullstr) { |
1862 | if(val!=NULL && *val != '/') | ||
1863 | val = cated = concat_path_file(curdir, val); | ||
1972 | free(curdir); | 1864 | free(curdir); |
1973 | curdir = nullstr; | ||
1974 | } | 1865 | } |
1975 | if (!val) { | 1866 | if (!val) |
1976 | getpwd(); | 1867 | getpwd(); |
1977 | } else { | 1868 | else |
1978 | curdir = savestr(val); | 1869 | curdir = simplify_path(val); |
1979 | } | 1870 | free(cated); |
1980 | INTON; | 1871 | INTON; |
1981 | setvar("PWD", curdir, VEXPORT); | 1872 | setvar("PWD", curdir, VEXPORT); |
1982 | } | 1873 | } |
@@ -5950,6 +5841,7 @@ init(void) { | |||
5950 | 5841 | ||
5951 | /* from cd.c: */ | 5842 | /* from cd.c: */ |
5952 | { | 5843 | { |
5844 | curdir = nullstr; | ||
5953 | setpwd(0, 0); | 5845 | setpwd(0, 0); |
5954 | } | 5846 | } |
5955 | 5847 | ||
@@ -7939,7 +7831,6 @@ readcmdfile(const char *name) | |||
7939 | * search for the file, which is necessary to find sub-commands. | 7831 | * search for the file, which is necessary to find sub-commands. |
7940 | */ | 7832 | */ |
7941 | 7833 | ||
7942 | |||
7943 | static inline char * | 7834 | static inline char * |
7944 | find_dot_file(char *mybasename) | 7835 | find_dot_file(char *mybasename) |
7945 | { | 7836 | { |
@@ -9633,7 +9524,7 @@ static union node *list (int); | |||
9633 | static union node *andor (void); | 9524 | static union node *andor (void); |
9634 | static union node *pipeline (void); | 9525 | static union node *pipeline (void); |
9635 | static union node *command (void); | 9526 | static union node *command (void); |
9636 | static union node *simplecmd (void); | 9527 | static union node *simplecmd(union node **rpp, union node *redir); |
9637 | static void parsefname (void); | 9528 | static void parsefname (void); |
9638 | static void parseheredoc (void); | 9529 | static void parseheredoc (void); |
9639 | static char peektoken (void); | 9530 | static char peektoken (void); |
@@ -9816,7 +9707,7 @@ pipeline() { | |||
9816 | 9707 | ||
9817 | 9708 | ||
9818 | static union node * | 9709 | static union node * |
9819 | command() { | 9710 | command(void) { |
9820 | union node *n1, *n2; | 9711 | union node *n1, *n2; |
9821 | union node *ap, **app; | 9712 | union node *ap, **app; |
9822 | union node *cp, **cpp; | 9713 | union node *cp, **cpp; |
@@ -10005,7 +9896,7 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
10005 | synexpect(-1); | 9896 | synexpect(-1); |
10006 | case TWORD: | 9897 | case TWORD: |
10007 | tokpushback++; | 9898 | tokpushback++; |
10008 | n1 = simplecmd(); | 9899 | n1 = simplecmd(rpp, redir); |
10009 | return n1; | 9900 | return n1; |
10010 | default: | 9901 | default: |
10011 | synexpect(-1); | 9902 | synexpect(-1); |
@@ -10035,18 +9926,25 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
10035 | 9926 | ||
10036 | 9927 | ||
10037 | static union node * | 9928 | static union node * |
10038 | simplecmd() { | 9929 | simplecmd(union node **rpp, union node *redir) { |
10039 | union node *args, **app; | 9930 | union node *args, **app; |
10040 | union node *n = NULL; | 9931 | union node *n = NULL; |
10041 | union node *vars, **vpp; | 9932 | union node *vars, **vpp; |
10042 | union node **rpp, *redir; | 9933 | union node **orig_rpp; |
10043 | 9934 | ||
10044 | args = NULL; | 9935 | args = NULL; |
10045 | app = &args; | 9936 | app = &args; |
10046 | vars = NULL; | 9937 | vars = NULL; |
10047 | vpp = &vars; | 9938 | vpp = &vars; |
10048 | redir = NULL; | 9939 | |
9940 | /* If we don't have any redirections already, then we must reset | ||
9941 | rpp to be the address of the local redir variable. */ | ||
9942 | if (redir == 0) | ||
10049 | rpp = &redir; | 9943 | rpp = &redir; |
9944 | /* We save the incoming value, because we need this for shell | ||
9945 | functions. There can not be a redirect or an argument between | ||
9946 | the function name and the open parenthesis. */ | ||
9947 | orig_rpp = rpp; | ||
10050 | 9948 | ||
10051 | checkalias = 2; | 9949 | checkalias = 2; |
10052 | for (;;) { | 9950 | for (;;) { |
@@ -10073,7 +9971,7 @@ simplecmd() { | |||
10073 | case TLP: | 9971 | case TLP: |
10074 | if ( | 9972 | if ( |
10075 | args && app == &args->narg.next && | 9973 | args && app == &args->narg.next && |
10076 | !vars && !redir | 9974 | !vars && rpp == orig_rpp |
10077 | ) { | 9975 | ) { |
10078 | /* We have a function */ | 9976 | /* We have a function */ |
10079 | if (readtoken() != TRP) | 9977 | if (readtoken() != TRP) |
@@ -10459,7 +10357,6 @@ breakloop: | |||
10459 | } | 10357 | } |
10460 | #endif | 10358 | #endif |
10461 | 10359 | ||
10462 | |||
10463 | /* | 10360 | /* |
10464 | * If eofmark is NULL, read a word or a redirection symbol. If eofmark | 10361 | * If eofmark is NULL, read a word or a redirection symbol. If eofmark |
10465 | * is not NULL, read a here document. In the latter case, eofmark is the | 10362 | * 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) | |||
12730 | /* | 12627 | /* |
12731 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> | 12628 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> |
12732 | * This file contains code for the times builtin. | 12629 | * This file contains code for the times builtin. |
12733 | * $Id: ash.c,v 1.29 2001/10/24 05:00:16 andersen Exp $ | 12630 | * $Id: ash.c,v 1.30 2001/10/24 08:01:06 andersen Exp $ |
12734 | */ | 12631 | */ |
12735 | static int timescmd (int argc, char **argv) | 12632 | static int timescmd (int argc, char **argv) |
12736 | { | 12633 | { |