diff options
author | ache <ache@FreeBSD.org> | 2012-06-04 21:34:49 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2012-06-04 21:34:49 +0000 |
commit | a2a055b43c9c828fe12942279a5f4dd1c4588547 (patch) | |
tree | c77650aafa54d84d399cadefdd15e5e570dddf44 /lib | |
parent | 569112bb5fd7beb1c4786c4e8ab5d98339b64ca6 (diff) | |
download | FreeBSD-src-a2a055b43c9c828fe12942279a5f4dd1c4588547.zip FreeBSD-src-a2a055b43c9c828fe12942279a5f4dd1c4588547.tar.gz |
1) IEEE Std 1003.1-2008, "errno" section, is explicit that
"The setting of errno after a successful call to a function is
unspecified unless the description of that function specifies that
errno shall not be modified."
However, free() in IEEE Std 1003.1-2008 does not mention its interaction
with errno, so MAY modify it after successful call
(it depends on particular free() implementation, OS-specific, etc.).
So, save errno across free() calls to make code portable and
POSIX-conformant.
2) Remove unused serrno assignment.
MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/stdlib/realpath.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index ffbf8ec..185dbb6 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -65,7 +65,6 @@ realpath(const char * __restrict path, char * __restrict resolved) errno = ENOENT; return (NULL); } - serrno = errno; if (resolved == NULL) { resolved = malloc(PATH_MAX); if (resolved == NULL) @@ -83,9 +82,11 @@ realpath(const char * __restrict path, char * __restrict resolved) left_len = strlcpy(left, path + 1, sizeof(left)); } else { if (getcwd(resolved, PATH_MAX) == NULL) { - if (m) + if (m) { + serrno = errno; free(resolved); - else { + errno = serrno; + } else { resolved[0] = '.'; resolved[1] = '\0'; } @@ -143,8 +144,11 @@ realpath(const char * __restrict path, char * __restrict resolved) * occurence to not implement lookahead. */ if (lstat(resolved, &sb) != 0) { - if (m) + if (m) { + serrno = errno; free(resolved); + errno = serrno; + } return (NULL); } if (!S_ISDIR(sb.st_mode)) { @@ -184,8 +188,11 @@ realpath(const char * __restrict path, char * __restrict resolved) if (lstat(resolved, &sb) != 0) { if (errno != ENOENT || p != NULL) errno = ENOTDIR; - if (m) + if (m) { + serrno = errno; free(resolved); + errno = serrno; + } return (NULL); } if (S_ISLNK(sb.st_mode)) { @@ -197,8 +204,11 @@ realpath(const char * __restrict path, char * __restrict resolved) } slen = readlink(resolved, symlink, sizeof(symlink) - 1); if (slen < 0) { - if (m) + if (m) { + serrno = errno; free(resolved); + errno = serrno; + } return (NULL); } symlink[slen] = '\0'; |