1 --- getcwd.c.orig 2006-01-19 18:35:45.000000000 -0800
2 +++ getcwd.c 2006-02-08 17:53:41.000000000 -0800
4 (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
5 (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
7 -extern int __getcwd(char *, size_t);
9 + * If __getcwd() ever becomes a syscall, we can remove this workaround.
10 + * The problem here is that fcntl() assumes a buffer of size MAXPATHLEN,
11 + * if size is less than MAXPATHLEN, we need to use a temporary buffer
12 + * and see if it fits. We also have to assume that open() or fcntl()
13 + * don't fail with errno=ERANGE.
16 +__getcwd(char *buf, size_t size)
19 + struct stat dot, pt;
22 + if ((fd = open(".", O_RDONLY)) < 0)
24 + if (fstat(fd, &dot) < 0) {
30 + /* check that the device and inode are non-zero, otherwise punt */
31 + if (dot.st_dev == 0 || dot.st_ino == 0) {
36 + if (size < MAXPATHLEN) {
37 + /* the hard case; allocate a buffer of size MAXPATHLEN to use */
38 + b = (char *)alloca(MAXPATHLEN);
41 + errno = ENOMEM; /* make sure it isn't ERANGE */
47 + err = fcntl(fd, F_GETPATH, b);
56 + * now double-check that the path returned by fcntl() has the same
57 + * device and inode number as '.'.
59 + if (stat(b, &pt) < 0)
62 + * Since dot.st_dev and dot.st_ino are non-zero, we don't need to
63 + * separately test for pt.st_dev and pt.st_ino being non-zero, because
64 + * they have to match
66 + if (dot.st_dev != pt.st_dev || dot.st_ino != pt.st_ino) {
71 + * For the case where we allocated a buffer, check that it can fit
72 + * in the real buffer, and copy it over.
74 + if (size < MAXPATHLEN) {
75 + if (strlen(b) >= size) {
90 - if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
91 + if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL)
95 if (__getcwd(pt, ept - pt) == 0) {
98 - ept = pt + strlen(pt) - 1;
107 + } else if (errno == ERANGE) /* failed because buffer too small */
113 - * Allocate bytes (1024 - malloc space) for the string of "../"'s.
114 + * Allocate bytes MAXPATHLEN) for the string of "../"'s.
115 * Should always be enough (it's 340 levels). If it's not, allocate
116 * as necessary. Special case the first stat, it's ".", not "..".
118 - if ((up = malloc(upsize = 1024 - 4)) == NULL)
119 + if ((up = malloc(upsize = MAXPATHLEN)) == NULL)
121 eup = up + MAXPATHLEN;