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
This commit is contained in:
Andrey A. Chernov 2012-06-04 21:34:49 +00:00
parent 10ee2f9a87
commit 96700463ec

View File

@ -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';