提交 9bff7c13 编写于 作者: R Rich Felker

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
上级 b5289fd7
#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));
......
#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);
}
#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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册