]> git.saurik.com Git - apple/libc.git/blob - libdarwin/h/stdlib.h
25d524e020f94370c9205b2979bf4e262b1aaf62
[apple/libc.git] / libdarwin / h / stdlib.h
1 /*
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*!
25 * @header
26 * Non-standard, Darwin-specific additions to the stdlib(3) family of APIs.
27 *
28 * The os_malloc() and os_strdup() routines are wrappers to be used for small,
29 * fixed-size allocations, the assumption being that such allocation should
30 * always succeed absent other critical problems. Thus, if the requested size is
31 * is a compile-time constant, the return value is asserted to be non-NULL.
32 * Otherwise, for sizes that are not known at compile-time, the implementations
33 * loop until the allocation succeeds, assuming the failure to be due to
34 * transient resource shortages. The implementation will not loop if the program
35 * has not become multi-threaded, under the assertion that there would be no
36 * point since no other thread could possibly free up resources for the calling
37 * thread to use. Thus, in a single-threaded program, all allocations will
38 * be treated like small, fixed-size allocations and be expected to succeed.
39 *
40 * These wrappers should not be used for large allocations whose bounds cannot
41 * be determined at compile-time. For such allocations, malloc(3), calloc(3), et
42 * al. (with appropriate error handling) are the appropriate interfaces.
43 */
44 #ifndef __DARWIN_STDLIB_H
45 #define __DARWIN_STDLIB_H
46
47 #include <os/base.h>
48 #include <os/api.h>
49 #include <os/assumes.h>
50 #include <os/stdio.h>
51 #include <dispatch/private.h>
52
53 #include <stdlib.h>
54 #include <sys/types.h>
55 #include <sys/cdefs.h>
56 #include <sys/syslimits.h>
57
58 __BEGIN_DECLS;
59
60 /*!
61 * @function __os_temporary_resource_shortage
62 * A function whose purpose is to appear in stack traces to indicate transient
63 * resource shortage conditions. Do not call.
64 */
65 DARWIN_API_AVAILABLE_20170407
66 OS_EXPORT OS_NOT_TAIL_CALLED
67 void
68 __os_temporary_resource_shortage(void);
69
70 /*!
71 * @functiongroup
72 * Internal inline definitions.
73 */
74 DARWIN_API_AVAILABLE_20170407
75 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1)
76 static inline void *
77 _os_malloc_loop(size_t size)
78 {
79 void *ptr = NULL;
80 while (!(ptr = malloc(size))) {
81 __os_temporary_resource_shortage();
82 }
83 return ptr;
84 }
85
86 DARWIN_API_AVAILABLE_20170407
87 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1)
88 static inline void *
89 _os_malloc_known(size_t size)
90 {
91 return malloc(size);
92 }
93
94 DARWIN_API_AVAILABLE_20170407
95 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2)
96 static inline void *
97 _os_calloc_loop(size_t cnt, size_t size)
98 {
99 void *ptr = NULL;
100 while (!(ptr = calloc(cnt, size))) {
101 __os_temporary_resource_shortage();
102 }
103 return ptr;
104 }
105
106 DARWIN_API_AVAILABLE_20170407
107 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2)
108 static inline void *
109 _os_calloc_known(size_t cnt, size_t size)
110 {
111 return calloc(cnt, size);
112 }
113
114 DARWIN_API_AVAILABLE_20170407
115 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC
116 static inline char *
117 _os_strdup_loop(const char *str)
118 {
119 char *ptr = NULL;
120 while (!(ptr = strdup(str))) {
121 __os_temporary_resource_shortage();
122 }
123 return ptr;
124 }
125
126 DARWIN_API_AVAILABLE_20170407
127 OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC
128 static inline char *
129 _os_strdup_known(const char *str)
130 {
131 return strdup(str);
132 }
133
134 #define __os_requires_experimental_libtrace \
135 _Pragma("GCC error \"requires OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE\"")
136
137 /*!
138 * @function os_malloc
139 * Wrapper around malloc(3) which guarantees that the allocation succeeds.
140 *
141 * @param __size
142 * The size of the allocation.
143 *
144 * @result
145 * A new object that the caller is responsible for free(3)ing.
146 *
147 * This routine will never return NULL. If the size of the allocation is known
148 * at compile-time, a failure to allocate the object will abort the caller. If
149 * the size is not known at compile-time, the routine will retry until it is
150 * successful.
151 */
152 #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
153 #define os_malloc(__size) ({ \
154 void *ptr = NULL; \
155 size_t _size = (__size); \
156 if (__builtin_constant_p(__size) || !_dispatch_is_multithreaded()) { \
157 ptr = _os_malloc_known(_size); \
158 os_assert_malloc("known-constant allocation", ptr, _size); \
159 } else { \
160 ptr = _os_malloc_loop(_size); \
161 } \
162 (ptr); \
163 })
164 #else
165 #define os_malloc(__size) __os_requires_experimental_libtrace
166 #endif
167
168 /*!
169 * @function os_calloc
170 * Wrapper around calloc(3) which guarantees that the allocation succeeds.
171 *
172 * @param __cnt
173 * The number of elements to allocate.
174 *
175 * @param __size
176 * The size of each element to allocate.
177 *
178 * @result
179 * A new object that the caller is responsible for free(3)ing.
180 *
181 * This routine will never return NULL. If the size of the allocation is known
182 * at compile-time, a failure to allocate the object will abort the caller. If
183 * the size is not known at compile-time, the routine will retry until it is
184 * successful.
185 */
186 #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
187 #define os_calloc(__cnt, __size) ({ \
188 void *ptr = NULL; \
189 size_t _size = (__size); \
190 size_t _cnt = (__size); \
191 if ((__builtin_constant_p(__cnt) && __builtin_constant_p(__size)) || \
192 !_dispatch_is_multithreaded()) { \
193 ptr = _os_calloc_known(_cnt, _size); \
194 os_assert_malloc("known-constant allocation", ptr, _size); \
195 } else { \
196 ptr = _os_calloc_loop(_cnt, _size); \
197 } \
198 (ptr); \
199 })
200 #else
201 #define os_calloc(__size) __os_requires_experimental_libtrace
202 #endif
203
204 /*!
205 * @function os_strdup
206 * A wrapper around strdup(3) which guarantees that the string duplication
207 * succeeds.
208 *
209 * @param __str
210 * The string to duplicate.
211 *
212 * @result
213 * A new string that the caller is responsible for free(3)ing.
214 *
215 * This routine will never return NULL. If the given string is a compile-time
216 * constant, a failure to duplicate it will abort the caller. If the string is
217 * not a compile-time constant, the routine will retry until it is successful.
218 *
219 * @discussion
220 * strdup(3) is found in the string(3) API family, but this interface is in the
221 * stdlib.h header because its semantic changes are solely related to the manner
222 * in which memory is allocated.
223 */
224 #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
225 #define os_strdup(__str) ({ \
226 char *ptr = NULL; \
227 const char *_str = (__str); \
228 if (__builtin_constant_p(__str) || !_dispatch_is_multithreaded()) { \
229 ptr = _os_strdup_known(_str); \
230 os_assert_malloc("known-constant allocation", ptr, strlen(_str)); \
231 } else { \
232 ptr = _os_strdup_loop(_str); \
233 } \
234 (ptr); \
235 })
236 #else
237 #define os_strdup(__size) __os_requires_experimental_libtrace
238 #endif
239
240 /*!
241 * @function os_localtime_file
242 * A routine to generate a time stamp that is suitable for embedding in a file
243 * name.
244 *
245 * @param buff
246 * A pointer to a buffer where the resulting time stamp will be stored.
247 *
248 * @discussion
249 * The resulting time stamp will not include characters which require escaping
250 * in shells, such as spaces. The current implementation format is
251 *
252 * YYYY-MM-DD_HH.MM.SS.us
253 *
254 * e.g.
255 *
256 * 2017-04-24_12.45.15.045609
257 */
258 DARWIN_API_AVAILABLE_20170407
259 OS_EXPORT
260 void
261 os_localtime_file(char buff[static 32]);
262
263 /*!
264 * @function os_simple_hash
265 * An implementation of a simple non-cryptographic hashing algorithm.
266 *
267 * @param buff
268 * A pointer to the buffer to hash.
269 *
270 * @param len
271 * The length of the buffer.
272 *
273 * @result
274 * The hashed value of the input.
275 *
276 * @discussion
277 * This routine is meant to be used as a simple way to obtain a value that can
278 * be used to choose a bucket in a simple hash table. Do not attach security
279 * assumptions to the output of this routine. Do not assume that the computed
280 * hash is stable between hosts, OS versions, or boot sessions.
281 */
282 DARWIN_API_AVAILABLE_20170407
283 OS_EXPORT OS_NONNULL1
284 uint64_t
285 os_simple_hash(const void *buff, size_t len);
286
287 /*!
288 * @function os_simple_hash_with_seed
289 * A seeded variant of os_simple_hash.
290 *
291 * @param buff
292 * A pointer to the buffer to hash.
293 *
294 * @param len
295 * The length of the buffer.
296 *
297 * @param seed
298 * The seed value for the hash.
299 *
300 * @result
301 * The hashed value of the input.
302 *
303 * @discussion
304 * Usually, hashing the same buffer with different seeds will produce
305 * different hash values.
306 * All the same considerations of {@link os_simple_hash} apply.
307 */
308 DARWIN_API_AVAILABLE_20181020
309 OS_EXPORT OS_NONNULL1
310 uint64_t
311 os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed);
312
313 /*!
314 * @function os_simple_hash_string
315 * An implementation of a simple non-cryptographic hashing algorithm.
316 *
317 * @param string
318 * A pointer to the null-terminated string to hash.
319 *
320 * @result
321 * The hashed value of the input.
322 *
323 * @discussion
324 * This routine is the moral equivalent of a call to
325 *
326 * os_simple_hash(buff, strlen(buff));
327 *
328 * All the same considerations of {@link os_simple_hash} apply.
329 */
330 DARWIN_API_AVAILABLE_20170407
331 OS_EXPORT OS_NONNULL1
332 uint64_t
333 os_simple_hash_string(const char *string);
334
335 /*!
336 * @function os_simple_hash_string_with_seed
337 * A seeded variant of os_simple_hash_string.
338 *
339 * @param string
340 * A pointer to the null-terminated string to hash.
341 *
342 * @result
343 * The hashed value of the input.
344 *
345 * @discussion
346 * Usually, hashing the same string with different seeds will produce
347 * different hash values.
348 * All the same considerations of {@link os_simple_hash_string} apply.
349 */
350 DARWIN_API_AVAILABLE_20181020
351 OS_EXPORT OS_NONNULL1
352 uint64_t
353 os_simple_hash_string_with_seed(const char *string, uint64_t seed);
354
355 /*!
356 * @function realpath_np
357 * Obtains a fully-resolved representation of the path to the file represented
358 * by the given descriptor.
359 *
360 * @param fd
361 * The file descriptor whose path is to be obtained.
362 *
363 * @param buff
364 * The buffer in which to write the path.
365 *
366 * @result
367 * On success, zero is returned. Otherwise, the implementation may return any
368 * error that can be returned by fcntl(2).
369 */
370 DARWIN_API_AVAILABLE_20180727
371 OS_EXPORT OS_WARN_RESULT
372 errno_t
373 realpath_np(os_fd_t fd, char buff[static PATH_MAX]);
374
375 __END_DECLS;
376
377 #endif // __DARWIN_STDLIB_H