summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstefanf <stefanf@FreeBSD.org>2009-11-21 14:53:22 +0000
committerstefanf <stefanf@FreeBSD.org>2009-11-21 14:53:22 +0000
commit611f554046960f02aad56a185bf34a2d7c8b7d27 (patch)
tree2e5be40b435683fb3f40a9daab19c74d95d12db4
parentf225be7d75ed32bd8b760dadf4febdd70444731c (diff)
downloadFreeBSD-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.c51
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;
}
OpenPOWER on IntegriCloud