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 
47 void *
48 aligned_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 
93 void
94 aligned_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 
116 int
117 setenv(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
aligned_alloc
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
libc.h
stdio.h
stdint.h
asprintf
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
stdlib.h
aligned_free
void aligned_free(void *ptr)
Causes the space at ptr to be deallocated, that is, made available for further allocation.
Definition: stdlib.c:94