diff options
author | stefanf <stefanf@FreeBSD.org> | 2009-11-21 14:53:22 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2009-11-21 14:53:22 +0000 |
commit | 611f554046960f02aad56a185bf34a2d7c8b7d27 (patch) | |
tree | 2e5be40b435683fb3f40a9daab19c74d95d12db4 | |
parent | f225be7d75ed32bd8b760dadf4febdd70444731c (diff) | |
download | FreeBSD-src-611f554046960f02aad56a185bf34a2d7c8b7d27.zip FreeBSD-src-611f554046960f02aad56a185bf34a2d7c8b7d27.tar.gz |
Handle current work directories of arbitrary length. The argument to cd
continues to be limited by PATH_MAX (1024).
Obtained from: NetBSD
PR: 104456
-rw-r--r-- | bin/sh/cd.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 4abe91e..66c1908 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -70,7 +70,7 @@ STATIC int docd(char *, int, int); STATIC char *getcomponent(void); STATIC char *findcwd(char *); STATIC void updatepwd(char *); -STATIC char *getpwd2(char *, size_t); +STATIC char *getpwd2(void); STATIC char *curdir = NULL; /* current working directory */ STATIC char *prevdir; /* previous working directory */ @@ -263,10 +263,8 @@ findcwd(char *dir) * any more because we traversed a symbolic link or something * we couldn't stat(). */ - if (dir == NULL || curdir == NULL) { - p = stalloc(PATH_MAX); - return getpwd2(p, PATH_MAX); - } + if (dir == NULL || curdir == NULL) + return getpwd2(); cdcomppath = stalloc(strlen(dir) + 1); scopy(dir, cdcomppath); STARTSTACKSTR(new); @@ -313,7 +311,7 @@ updatepwd(char *dir) int pwdcmd(int argc, char **argv) { - char buf[PATH_MAX]; + char *p; int ch, phys; optreset = 1; optind = 1; opterr = 0; /* initialize getopt */ @@ -341,9 +339,9 @@ pwdcmd(int argc, char **argv) out1str(curdir); out1c('\n'); } else { - if (getcwd(buf, sizeof(buf)) == NULL) + if ((p = getpwd2()) == NULL) error(".: %s", strerror(errno)); - out1str(buf); + out1str(p); out1c('\n'); } @@ -356,36 +354,45 @@ pwdcmd(int argc, char **argv) char * getpwd(void) { - char buf[PATH_MAX]; char *p; if (curdir) return curdir; - p = getpwd2(buf, sizeof(buf)); + p = getpwd2(); if (p != NULL) curdir = savestr(p); return curdir; } +#define MAXPWD 256 + /* * Return the current directory. */ STATIC char * -getpwd2(char *buf, size_t size) +getpwd2(void) { - if (getcwd(buf, size) == NULL) { - char *pwd = getenv("PWD"); - struct stat stdot, stpwd; - - if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && - stat(pwd, &stpwd) != -1 && - stdot.st_dev == stpwd.st_dev && - stdot.st_ino == stpwd.st_ino) { + struct stat stdot, stpwd; + char *pwd; + int i; + + for (i = MAXPWD;; i *= 2) { + pwd = stalloc(i); + if (getcwd(pwd, i) != NULL) return pwd; - } - return NULL; + stunalloc(pwd); + if (errno != ERANGE) + break; + } + + pwd = getenv("PWD"); + if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && + stat(pwd, &stpwd) != -1 && + stdot.st_dev == stpwd.st_dev && + stdot.st_ino == stpwd.st_ino) { + return pwd; } - return buf; + return NULL; } |