- {
- c = getcwd (buf, PATH_MAX);
- if (!c && errno == ENOENT)
- {
- fail = 1;
- break;
- }
- if (c || ! (errno == ERANGE || is_ENAMETOOLONG (errno)))
- {
- fail = 2;
- break;
- }
- }
+ {
+ struct stat sb;
+
+ c = getcwd (buf, PATH_MAX);
+ if (!c && errno == ENOENT)
+ {
+ fail = 11;
+ break;
+ }
+ if (c)
+ {
+ fail = 31;
+ break;
+ }
+ if (! (errno == ERANGE || is_ENAMETOOLONG (errno)))
+ {
+ fail = 21;
+ break;
+ }
+
+ /* Our replacement needs to be able to stat() long ../../paths,
+ so generate a path larger than PATH_MAX to check,
+ avoiding the replacement if we can't stat(). */
+ c = getcwd (buf, cwd_len + 1);
+ if (c && !AT_FDCWD && stat (c, &sb) != 0 && is_ENAMETOOLONG (errno))
+ {
+ fail = 32;
+ break;
+ }
+ }