From a2a055b43c9c828fe12942279a5f4dd1c4588547 Mon Sep 17 00:00:00 2001 From: ache Date: Mon, 4 Jun 2012 21:34:49 +0000 Subject: 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 --- lib/libc/stdlib/realpath.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'lib/libc/stdlib/realpath.c') 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'; -- cgit v1.1