Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libc/gen/getcwd.c,v retrieving revision 1.36.2.3 retrieving revision 1.37 diff -u -p -r1.36.2.3 -r1.37 --- src/lib/libc/gen/getcwd.c 2006/01/01 23:12:36 1.36.2.3 +++ src/lib/libc/gen/getcwd.c 2005/07/04 20:44:47 1.37 @@ -1,4 +1,4 @@ -/* $NetBSD: getcwd.c,v 1.36.2.3 2006/01/01 23:12:36 riz Exp $ */ +/* $NetBSD: getcwd.c,v 1.37 2005/07/04 20:44:47 elad Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1995 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)getcwd.c 8.5 (Berkeley) 2/7/95"; #else -__RCSID("$NetBSD: getcwd.c,v 1.36.2.3 2006/01/01 23:12:36 riz Exp $"); +__RCSID("$NetBSD: getcwd.c,v 1.37 2005/07/04 20:44:47 elad Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -69,7 +69,7 @@ char * realpath(const char *path, char *resolved) { struct stat sb; - int idx = 0, n, nlnk = 0; + int idx = 0, n, nlnk = 0, serrno = errno; const char *q; char *p, wbuf[2][MAXPATHLEN]; size_t len; @@ -159,6 +159,16 @@ loop: * target to unresolved path. */ if (lstat(resolved, &sb) == -1) { + /* Allow nonexistent component if this is the last one. */ + if ((*q == 0 || (*q == '/' && *(q + 1) == 0)) + && errno == ENOENT) { + errno = serrno; + return (resolved); + } + return (NULL); + } + if (*q == '/' && !S_ISDIR(sb.st_mode)) { + errno = ENOTDIR; return (NULL); } if (S_ISLNK(sb.st_mode)) { @@ -188,10 +198,6 @@ loop: p = resolved; goto loop; } - if (*q == '/' && !S_ISDIR(sb.st_mode)) { - errno = ENOTDIR; - return (NULL); - } /* Advance both resolved and unresolved path. */ p += 1 + q - path;