unix: guard against clobbering errno in uv__free()

Libuv expects that free() does not clobber errno.  The system allocator
honors that assumption but custom allocators may not be so careful.

PR-URL: https://github.com/libuv/libuv/pull/837
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Ben Noordhuis 2016-04-18 12:20:17 +02:00
parent d03abfd400
commit 322de63a9b
3 changed files with 15 additions and 7 deletions

View File

@ -292,7 +292,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
size = sizeof(cpuspeed);
if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) {
SAVE_ERRNO(uv__free(*cpu_infos));
uv__free(*cpu_infos);
return -errno;
}
@ -301,7 +301,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
*/
size = sizeof(maxcpus);
if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
SAVE_ERRNO(uv__free(*cpu_infos));
uv__free(*cpu_infos);
return -errno;
}
@ -314,8 +314,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}
if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
SAVE_ERRNO(uv__free(cp_times));
SAVE_ERRNO(uv__free(*cpu_infos));
uv__free(cp_times);
uv__free(*cpu_infos);
return -errno;
}

View File

@ -247,7 +247,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
which[1] = HW_CPUSPEED;
size = sizeof(cpuspeed);
if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
SAVE_ERRNO(uv__free(*cpu_infos));
uv__free(*cpu_infos);
return -errno;
}
@ -258,7 +258,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
which[2] = i;
size = sizeof(info);
if (sysctl(which, 3, &info, &size, NULL, 0)) {
SAVE_ERRNO(uv__free(*cpu_infos));
uv__free(*cpu_infos);
return -errno;
}

View File

@ -22,10 +22,11 @@
#include "uv.h"
#include "uv-common.h"
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h> /* NULL */
#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* memset */
@ -75,7 +76,14 @@ void* uv__malloc(size_t size) {
}
void uv__free(void* ptr) {
int saved_errno;
/* Libuv expects that free() does not clobber errno. The system allocator
* honors that assumption but custom allocators may not be so careful.
*/
saved_errno = errno;
uv__allocator.local_free(ptr);
errno = saved_errno;
}
void* uv__calloc(size_t count, size_t size) {