Lely core libraries  2.2.5
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 
45 void *
46 aligned_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 
89 void
90 aligned_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 
112 int
113 setenv(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
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:46
libc.h
errnum
errnum
The platform-independent error numbers.
Definition: errnum.h:74
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:103
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:90