Lely core libraries 1.9.2
stdlib.c
Go to the documentation of this file.
1
23#include "libc.h"
24#include <lely/libc/stdlib.h>
25
26#if !(__STDC_VERSION__ >= 201112L)
27
28#ifndef LELY_HAVE_POSIX_MEMALIGN
29#if _POSIX_C_SOURCE >= 200112L
30#define LELY_HAVE_POSIX_MEMALIGN 1
31#if defined(__NEWLIB__) && !defined(__rtems__)
32#undef LELY_HAVE_POSIX_MEMALIGN
33#endif
34#endif
35#endif
36
37#if _WIN32
38#include <malloc.h>
39#elif defined(LELY_HAVE_POSIX_MEMALIGN)
40#include <errno.h>
41#else
42#include <stdint.h>
43#endif
44
45void *
46aligned_alloc(size_t alignment, size_t size)
47{
48#if _WIN32
49 if (!size)
50 return NULL;
51 return _aligned_malloc(size, alignment);
52#elif LELY_HAVE_POSIX_MEMALIGN
53 void *ptr = NULL;
54 int errnum = posix_memalign(&ptr, alignment, size);
55 if (errnum) {
56 errno = errnum;
57 return NULL;
58 }
59 return ptr;
60 // clang-format off
61#else // !_WIN32 && !LELY_HAVE_POSIX_MEMALIGN
62 // Check if the alignment is a multiple if sizeof(void *) that is also a
63 // power of two
64 if ((alignment & (alignment - 1)) || alignment < sizeof(void *))
65 return NULL;
66 // clang-format on
67 if (!size)
68 return NULL;
69
70 // malloc() is guaranteed to return a pointer aligned to at at least
71 // sizeof(void *), the minimum value of 'alignment'. We therefore need
72 // at most 'alignment' extra bytes.
73 void *ptr = malloc(size + alignment);
74 if (!ptr)
75 return NULL;
76 // Align the pointer.
77 void *aligned_ptr = (void *)(((uintptr_t)(char *)ptr + alignment - 1)
78 & ~(uintptr_t)(alignment - 1));
79 // Store the pointer obtained from malloc() right before the memory
80 // region we return to the user.
81 ((void **)aligned_ptr)[-1] = ptr;
82
83 return aligned_ptr;
84#endif // !_WIN32 && !LELY_HAVE_POSIX_MEMALIGN
85}
86
87#ifndef __USE_ISOC11
88
89void
90aligned_free(void *ptr)
91{
92#if _WIN32
93 _aligned_free(ptr);
94#elif LELY_HAVE_POSIX_MEMALIGN
95 free(ptr);
96#else
97 if (ptr)
98 free(((void **)ptr)[-1]);
99#endif
100}
101
102#endif // !__USE_ISOC11
103
104#endif // !(__STDC_VERSION__ >= 201112L)
105
106#if _WIN32
107
108#include <lely/libc/stdio.h>
109
110#include <errno.h>
111
112int
113setenv(const char *envname, const char *envval, int overwrite)
114{
115 if (!envname) {
116 errno = EINVAL;
117 return -1;
118 }
119
120 if (!overwrite && getenv(envname))
121 return 0;
122
123 for (const char *cp = envname; *cp; cp++) {
124 if (*cp == '=') {
125 errno = EINVAL;
126 return -1;
127 }
128 }
129
130 char *string = NULL;
131 if (asprintf(&string, "%s=%s", envname, envval) < 0)
132 return -1;
133
134 if (_putenv(string)) {
135 int errsv = errno;
136 free(string);
137 errno = errsv;
138 return -1;
139 }
140
141 free(string);
142 return 0;
143}
144
145#endif // _WIN32
errnum
The platform-independent error numbers.
Definition: errnum.h:74
This is the internal header file of the C11 and POSIX compatibility library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint....
This header file is part of the C11 and POSIX compatibility library; it includes <stdio....
int asprintf(char **strp, const char *fmt,...)
Equivalent to sprintf(), except that it allocates a string large enough to hold the output,...
Definition: stdio.c:103
void aligned_free(void *ptr)
Causes the space at ptr to be deallocated, that is, made available for further allocation.
Definition: stdlib.c:90
void * aligned_alloc(size_t alignment, size_t size)
Allocates space for an object whose alignment is specified by alignment, whose size is specified by s...
Definition: stdlib.c:46
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....