oldmalloc: preserve errno across free
authorRich Felker <dalias@aerifal.cx>
Sat, 30 Jan 2021 22:28:08 +0000 (17:28 -0500)
committerRich Felker <dalias@aerifal.cx>
Sat, 30 Jan 2021 22:28:08 +0000 (17:28 -0500)
as an outcome of Austin Group issue #385, future versions of the
standard will require free not to alter the value of errno. save and
restore it individually around the calls to madvise and munmap so that
the cost is not imposed on calls to free that do not result in any
syscall.

src/malloc/oldmalloc/malloc.c

index a5cbdb6..25d00d4 100644 (file)
@@ -481,12 +481,14 @@ void __bin_chunk(struct chunk *self)
        if (size > RECLAIM && (size^(size-osize)) > size-osize) {
                uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
                uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
+               int e = errno;
 #if 1
                __madvise((void *)a, b-a, MADV_DONTNEED);
 #else
                __mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
                        MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
 #endif
+               errno = e;
        }
 
        unlock_bin(i);
@@ -499,7 +501,9 @@ static void unmap_chunk(struct chunk *self)
        size_t len = CHUNK_SIZE(self) + extra;
        /* Crash on double free */
        if (extra & 1) a_crash();
+       int e = errno;
        __munmap(base, len);
+       errno = e;
 }
 
 void free(void *p)