summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2012-06-04 21:34:49 +0000
committerache <ache@FreeBSD.org>2012-06-04 21:34:49 +0000
commita2a055b43c9c828fe12942279a5f4dd1c4588547 (patch)
treec77650aafa54d84d399cadefdd15e5e570dddf44 /lib
parent569112bb5fd7beb1c4786c4e8ab5d98339b64ca6 (diff)
downloadFreeBSD-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.c22
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';
OpenPOWER on IntegriCloud