mirror of
https://git.musl-libc.org/git/musl
synced 2025-03-20 09:33:08 +03:00
implement "low hanging fruit" from C11
based on Gregor's patch sent to the list. includes: - stdalign.h - removing gets in C11 mode - adding aligned_alloc and adjusting other functions to use it - adding 'x' flag to fopen for exclusive mode
This commit is contained in:
parent
b5289fd749
commit
9bff7c133e
15
include/stdalign.h
Normal file
15
include/stdalign.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _STDALIGN_H
|
||||
#define _STDALIGN_H
|
||||
|
||||
/* this whole header only works in C11 or with compiler extensions */
|
||||
#if __STDC_VERSION__ < 201112L && defined( __GNUC__)
|
||||
#define _Alignas(t) __attribute__((__aligned__(t)))
|
||||
#define _Alignof(t) __alignof__(t)
|
||||
#endif
|
||||
|
||||
#define alignas _Alignas
|
||||
#define alignof _Alignof
|
||||
#define __alignas_is_defined 1
|
||||
#define __alignof_is_defined 1
|
||||
|
||||
#endif
|
@ -90,7 +90,9 @@ int putc(int, FILE *);
|
||||
int putchar(int);
|
||||
|
||||
char *fgets(char *, int, FILE *);
|
||||
#if __STDC_VERSION__ < 201112L
|
||||
char *gets(char *);
|
||||
#endif
|
||||
|
||||
int fputs(const char *, FILE *);
|
||||
int puts(const char *);
|
||||
|
@ -38,6 +38,7 @@ void *malloc (size_t);
|
||||
void *calloc (size_t, size_t);
|
||||
void *realloc (void *, size_t);
|
||||
void free (void *);
|
||||
void *aligned_alloc(size_t alignment, size_t size);
|
||||
|
||||
void abort (void);
|
||||
int atexit (void (*) (void));
|
||||
|
51
src/malloc/aligned_alloc.c
Normal file
51
src/malloc/aligned_alloc.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* This function should work with most dlmalloc-like chunk bookkeeping
|
||||
* systems, but it's only guaranteed to work with the native implementation
|
||||
* used in this library. */
|
||||
|
||||
void *aligned_alloc(size_t align, size_t len)
|
||||
{
|
||||
unsigned char *mem, *new, *end;
|
||||
size_t header, footer;
|
||||
|
||||
if ((align & -align & -sizeof(void *)) != align) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > SIZE_MAX - align) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (align <= 4*sizeof(size_t)) {
|
||||
if (!(mem = malloc(len)))
|
||||
return NULL;
|
||||
return mem;
|
||||
}
|
||||
|
||||
if (!(mem = malloc(len + align-1)))
|
||||
return NULL;
|
||||
|
||||
header = ((size_t *)mem)[-1];
|
||||
end = mem + (header & -8);
|
||||
footer = ((size_t *)end)[-2];
|
||||
new = (void *)((uintptr_t)mem + align-1 & -align);
|
||||
|
||||
if (!(header & 7)) {
|
||||
((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
|
||||
((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
|
||||
return new;
|
||||
}
|
||||
|
||||
((size_t *)mem)[-1] = header&7 | new-mem;
|
||||
((size_t *)new)[-2] = footer&7 | new-mem;
|
||||
((size_t *)new)[-1] = header&7 | end-new;
|
||||
((size_t *)end)[-2] = footer&7 | end-new;
|
||||
|
||||
if (new != mem) free(mem);
|
||||
return new;
|
||||
}
|
@ -3,11 +3,5 @@
|
||||
|
||||
void *memalign(size_t align, size_t len)
|
||||
{
|
||||
void *mem;
|
||||
int ret;
|
||||
if ((ret = posix_memalign(&mem, align, len))) {
|
||||
errno = ret;
|
||||
return 0;
|
||||
}
|
||||
return mem;
|
||||
return aligned_alloc(align, len);
|
||||
}
|
||||
|
@ -1,47 +1,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* This function should work with most dlmalloc-like chunk bookkeeping
|
||||
* systems, but it's only guaranteed to work with the native implementation
|
||||
* used in this library. */
|
||||
|
||||
int posix_memalign(void **res, size_t align, size_t len)
|
||||
{
|
||||
unsigned char *mem, *new, *end;
|
||||
size_t header, footer;
|
||||
|
||||
if ((align & -align & -sizeof(void *)) != align) return EINVAL;
|
||||
if (len > SIZE_MAX - align) return ENOMEM;
|
||||
|
||||
if (align <= 4*sizeof(size_t)) {
|
||||
if (!(mem = malloc(len)))
|
||||
return errno;
|
||||
*res = mem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mem = malloc(len + align-1)))
|
||||
return errno;
|
||||
|
||||
header = ((size_t *)mem)[-1];
|
||||
end = mem + (header & -8);
|
||||
footer = ((size_t *)end)[-2];
|
||||
new = (void *)((uintptr_t)mem + align-1 & -align);
|
||||
|
||||
if (!(header & 7)) {
|
||||
((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
|
||||
((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
|
||||
*res = new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
((size_t *)mem)[-1] = header&7 | new-mem;
|
||||
((size_t *)new)[-2] = footer&7 | new-mem;
|
||||
((size_t *)new)[-1] = header&7 | end-new;
|
||||
((size_t *)end)[-2] = footer&7 | end-new;
|
||||
|
||||
if (new != mem) free(mem);
|
||||
*res = new;
|
||||
void *mem = aligned_alloc(align, len);
|
||||
if (!mem) return errno;
|
||||
*res = mem;
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ FILE *fopen(const char *filename, const char *mode)
|
||||
FILE *f;
|
||||
int fd;
|
||||
int flags;
|
||||
int plus = !!strchr(mode, '+');
|
||||
|
||||
/* Check for valid initial mode character */
|
||||
if (!strchr("rwa", *mode)) {
|
||||
@ -14,9 +13,10 @@ FILE *fopen(const char *filename, const char *mode)
|
||||
}
|
||||
|
||||
/* Compute the flags to pass to open() */
|
||||
if (plus) flags = O_RDWR;
|
||||
if (strchr(mode, '+')) flags = O_RDWR;
|
||||
else if (*mode == 'r') flags = O_RDONLY;
|
||||
else flags = O_WRONLY;
|
||||
if (strchr(mode, 'x')) flags |= O_EXCL;
|
||||
if (*mode != 'r') flags |= O_CREAT;
|
||||
if (*mode == 'w') flags |= O_TRUNC;
|
||||
if (*mode == 'a') flags |= O_APPEND;
|
||||
|
Loading…
x
Reference in New Issue
Block a user