Lely core libraries 2.3.4
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) && !LELY_NO_MALLOC
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 LELY_HAVE_POSIX_MEMALIGN
40#if !LELY_NO_ERRNO
41#include <errno.h>
42#endif
43#else
44#include <stdint.h>
45#endif
46
47void *
48aligned_alloc(size_t alignment, size_t size)
49{
50#if _WIN32
51 if (!size)
52 return NULL;
53 return _aligned_malloc(size, alignment);
54#elif LELY_HAVE_POSIX_MEMALIGN
55 void *ptr = NULL;
56 int errc = posix_memalign(&ptr, alignment, size);
57 if (errc) {
58#if !LELY_NO_ERRNO
59 errno = errc;
60#endif
61 return NULL;
62 }
63 return ptr;
64 // clang-format off
65#else // !_WIN32 && !LELY_HAVE_POSIX_MEMALIGN
66 // Check if the alignment is a multiple if sizeof(void *) that is also a
67 // power of two
68 if ((alignment & (alignment - 1)) || alignment < sizeof(void *))
69 return NULL;
70 // clang-format on
71 if (!size)
72 return NULL;
73
74 // malloc() is guaranteed to return a pointer aligned to at at least
75 // sizeof(void *), the minimum value of 'alignment'. We therefore need
76 // at most 'alignment' extra bytes.
77 void *ptr = malloc(size + alignment);
78 if (!ptr)
79 return NULL;
80 // Align the pointer.
81 void *aligned_ptr = (void *)(((uintptr_t)(char *)ptr + alignment - 1)
82 & ~(uintptr_t)(alignment - 1));
83 // Store the pointer obtained from malloc() right before the memory
84 // region we return to the user.
85 ((void **)aligned_ptr)[-1] = ptr;
86
87 return aligned_ptr;
88#endif // !_WIN32 && !LELY_HAVE_POSIX_MEMALIGN
89}
90
91#ifndef __USE_ISOC11
92
93void
94aligned_free(void *ptr)
95{
96#if _WIN32
97 _aligned_free(ptr);
98#elif LELY_HAVE_POSIX_MEMALIGN
99 free(ptr);
100#else
101 if (ptr)
102 free(((void **)ptr)[-1]);
103#endif
104}
105
106#endif // !__USE_ISOC11
107
108#endif // !(__STDC_VERSION__ >= 201112L) && !LELY_NO_MALLOC
109
110#if _WIN32 && !LELY_NO_STDIO
111
112#include <lely/libc/stdio.h>
113
114#include <errno.h>
115
116int
117setenv(const char *envname, const char *envval, int overwrite)
118{
119 if (!envname) {
120 errno = EINVAL;
121 return -1;
122 }
123
124 if (!overwrite && getenv(envname))
125 return 0;
126
127 for (const char *cp = envname; *cp; cp++) {
128 if (*cp == '=') {
129 errno = EINVAL;
130 return -1;
131 }
132 }
133
134 char *string = NULL;
135 if (asprintf(&string, "%s=%s", envname, envval) < 0)
136 return -1;
137
138 if (_putenv(string)) {
139 int errsv = errno;
140 free(string);
141 errno = errsv;
142 return -1;
143 }
144
145 free(string);
146 return 0;
147}
148
149#endif // _WIN32
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:106
void aligned_free(void *ptr)
Causes the space at ptr to be deallocated, that is, made available for further allocation.
Definition stdlib.c:94
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:48
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....