]>
Commit | Line | Data |
---|---|---|
70ad1dc8 A |
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> | |
507116e3 | 50 | #include <os/stdio.h> |
70ad1dc8 A |
51 | #include <dispatch/private.h> |
52 | ||
53 | #include <stdlib.h> | |
e1ee4b85 | 54 | #include <limits.h> |
70ad1dc8 A |
55 | #include <sys/types.h> |
56 | #include <sys/cdefs.h> | |
507116e3 | 57 | #include <sys/syslimits.h> |
70ad1dc8 | 58 | |
e1ee4b85 A |
59 | #if DARWIN_TAPI |
60 | #include "tapi.h" | |
61 | #endif | |
62 | ||
70ad1dc8 A |
63 | __BEGIN_DECLS; |
64 | ||
65 | /*! | |
66 | * @function __os_temporary_resource_shortage | |
67 | * A function whose purpose is to appear in stack traces to indicate transient | |
68 | * resource shortage conditions. Do not call. | |
69 | */ | |
70 | DARWIN_API_AVAILABLE_20170407 | |
71 | OS_EXPORT OS_NOT_TAIL_CALLED | |
72 | void | |
73 | __os_temporary_resource_shortage(void); | |
74 | ||
75 | /*! | |
76 | * @functiongroup | |
77 | * Internal inline definitions. | |
78 | */ | |
79 | DARWIN_API_AVAILABLE_20170407 | |
80 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1) | |
81 | static inline void * | |
82 | _os_malloc_loop(size_t size) | |
83 | { | |
84 | void *ptr = NULL; | |
85 | while (!(ptr = malloc(size))) { | |
86 | __os_temporary_resource_shortage(); | |
87 | } | |
88 | return ptr; | |
89 | } | |
90 | ||
91 | DARWIN_API_AVAILABLE_20170407 | |
92 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1) | |
93 | static inline void * | |
94 | _os_malloc_known(size_t size) | |
95 | { | |
96 | return malloc(size); | |
97 | } | |
98 | ||
99 | DARWIN_API_AVAILABLE_20170407 | |
100 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2) | |
101 | static inline void * | |
102 | _os_calloc_loop(size_t cnt, size_t size) | |
103 | { | |
104 | void *ptr = NULL; | |
105 | while (!(ptr = calloc(cnt, size))) { | |
106 | __os_temporary_resource_shortage(); | |
107 | } | |
108 | return ptr; | |
109 | } | |
110 | ||
111 | DARWIN_API_AVAILABLE_20170407 | |
112 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2) | |
113 | static inline void * | |
114 | _os_calloc_known(size_t cnt, size_t size) | |
115 | { | |
116 | return calloc(cnt, size); | |
117 | } | |
118 | ||
119 | DARWIN_API_AVAILABLE_20170407 | |
120 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC | |
121 | static inline char * | |
122 | _os_strdup_loop(const char *str) | |
123 | { | |
124 | char *ptr = NULL; | |
125 | while (!(ptr = strdup(str))) { | |
126 | __os_temporary_resource_shortage(); | |
127 | } | |
128 | return ptr; | |
129 | } | |
130 | ||
131 | DARWIN_API_AVAILABLE_20170407 | |
132 | OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC | |
133 | static inline char * | |
134 | _os_strdup_known(const char *str) | |
135 | { | |
136 | return strdup(str); | |
137 | } | |
138 | ||
507116e3 A |
139 | #define __os_requires_experimental_libtrace \ |
140 | _Pragma("GCC error \"requires OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE\"") | |
141 | ||
70ad1dc8 A |
142 | /*! |
143 | * @function os_malloc | |
144 | * Wrapper around malloc(3) which guarantees that the allocation succeeds. | |
145 | * | |
146 | * @param __size | |
147 | * The size of the allocation. | |
148 | * | |
149 | * @result | |
150 | * A new object that the caller is responsible for free(3)ing. | |
151 | * | |
152 | * This routine will never return NULL. If the size of the allocation is known | |
153 | * at compile-time, a failure to allocate the object will abort the caller. If | |
154 | * the size is not known at compile-time, the routine will retry until it is | |
155 | * successful. | |
156 | */ | |
507116e3 | 157 | #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE) |
70ad1dc8 A |
158 | #define os_malloc(__size) ({ \ |
159 | void *ptr = NULL; \ | |
160 | size_t _size = (__size); \ | |
161 | if (__builtin_constant_p(__size) || !_dispatch_is_multithreaded()) { \ | |
162 | ptr = _os_malloc_known(_size); \ | |
163 | os_assert_malloc("known-constant allocation", ptr, _size); \ | |
164 | } else { \ | |
165 | ptr = _os_malloc_loop(_size); \ | |
166 | } \ | |
167 | (ptr); \ | |
168 | }) | |
507116e3 A |
169 | #else |
170 | #define os_malloc(__size) __os_requires_experimental_libtrace | |
171 | #endif | |
70ad1dc8 A |
172 | |
173 | /*! | |
174 | * @function os_calloc | |
175 | * Wrapper around calloc(3) which guarantees that the allocation succeeds. | |
176 | * | |
177 | * @param __cnt | |
178 | * The number of elements to allocate. | |
179 | * | |
180 | * @param __size | |
181 | * The size of each element to allocate. | |
182 | * | |
183 | * @result | |
184 | * A new object that the caller is responsible for free(3)ing. | |
185 | * | |
186 | * This routine will never return NULL. If the size of the allocation is known | |
187 | * at compile-time, a failure to allocate the object will abort the caller. If | |
188 | * the size is not known at compile-time, the routine will retry until it is | |
189 | * successful. | |
190 | */ | |
507116e3 | 191 | #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE) |
70ad1dc8 A |
192 | #define os_calloc(__cnt, __size) ({ \ |
193 | void *ptr = NULL; \ | |
194 | size_t _size = (__size); \ | |
a9aaacca | 195 | size_t _cnt = (__cnt); \ |
70ad1dc8 A |
196 | if ((__builtin_constant_p(__cnt) && __builtin_constant_p(__size)) || \ |
197 | !_dispatch_is_multithreaded()) { \ | |
198 | ptr = _os_calloc_known(_cnt, _size); \ | |
199 | os_assert_malloc("known-constant allocation", ptr, _size); \ | |
200 | } else { \ | |
201 | ptr = _os_calloc_loop(_cnt, _size); \ | |
202 | } \ | |
203 | (ptr); \ | |
204 | }) | |
507116e3 A |
205 | #else |
206 | #define os_calloc(__size) __os_requires_experimental_libtrace | |
207 | #endif | |
70ad1dc8 A |
208 | |
209 | /*! | |
210 | * @function os_strdup | |
211 | * A wrapper around strdup(3) which guarantees that the string duplication | |
212 | * succeeds. | |
213 | * | |
214 | * @param __str | |
215 | * The string to duplicate. | |
216 | * | |
217 | * @result | |
218 | * A new string that the caller is responsible for free(3)ing. | |
219 | * | |
220 | * This routine will never return NULL. If the given string is a compile-time | |
221 | * constant, a failure to duplicate it will abort the caller. If the string is | |
222 | * not a compile-time constant, the routine will retry until it is successful. | |
223 | * | |
224 | * @discussion | |
225 | * strdup(3) is found in the string(3) API family, but this interface is in the | |
226 | * stdlib.h header because its semantic changes are solely related to the manner | |
227 | * in which memory is allocated. | |
228 | */ | |
507116e3 | 229 | #if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE) |
70ad1dc8 A |
230 | #define os_strdup(__str) ({ \ |
231 | char *ptr = NULL; \ | |
232 | const char *_str = (__str); \ | |
233 | if (__builtin_constant_p(__str) || !_dispatch_is_multithreaded()) { \ | |
234 | ptr = _os_strdup_known(_str); \ | |
235 | os_assert_malloc("known-constant allocation", ptr, strlen(_str)); \ | |
236 | } else { \ | |
237 | ptr = _os_strdup_loop(_str); \ | |
238 | } \ | |
239 | (ptr); \ | |
240 | }) | |
507116e3 A |
241 | #else |
242 | #define os_strdup(__size) __os_requires_experimental_libtrace | |
243 | #endif | |
70ad1dc8 | 244 | |
e1ee4b85 A |
245 | /*! |
246 | * @function os_setflag | |
247 | * Sets the given flag in a manner which is compatible with strongly-typed | |
248 | * enumerations. | |
249 | * | |
250 | * @param _bf | |
251 | * The bitfield in which to set the flag. | |
252 | * | |
253 | * @param _f | |
254 | * The flag to set. | |
255 | * | |
256 | * @result | |
257 | * The result of setting {@link _f} in {@link _bf}. | |
258 | */ | |
259 | #define os_setflag(_bf, _f) (typeof(_bf))((_bf) & (_f)) | |
260 | ||
261 | /*! | |
262 | * @function os_clrflag | |
263 | * Clears the given flag in a manner which is compatible with strongly-typed | |
264 | * enumerations. | |
265 | * | |
266 | * @param _bf | |
267 | * The bitfield in which to clear the flag. | |
268 | * | |
269 | * @param _f | |
270 | * The flag to clear. | |
271 | * | |
272 | * @result | |
273 | * The result of clearing {@link _f} from {@link _bf}. | |
274 | * | |
275 | * @discussion | |
276 | * clrbit() will produce errors when given types smaller than a pointer such as | |
277 | * int because it casts to char *; thus this implementation is required to deal | |
278 | * properly with flags defined via {@link OS_OPTIONS} or similar. | |
279 | */ | |
280 | #define os_clrflag(_bf, _f) (typeof(_bf))((_bf) & (typeof(_bf))(~(_f))) | |
281 | ||
282 | /*! | |
283 | * @function switch_posix | |
284 | * Macro which expands to a switch() statement for handling both the success | |
285 | * case as well as errno values set by POSIX and POSIX-y APIs that return -1 and | |
286 | * set errno. | |
287 | * | |
288 | * @example | |
289 | * | |
290 | * int ret = dup(fd); | |
291 | * switch_posix (ret) { | |
292 | * case 0: | |
293 | * // success | |
294 | * break; | |
295 | * case EINTR: | |
296 | * // interrupted system call | |
297 | * break; | |
298 | * case EBADF: | |
299 | * // bad file descriptor | |
300 | * break; | |
301 | * } | |
302 | * | |
303 | * @discussion | |
304 | * This statement cannot be used with APIs that return positive values on | |
305 | * failure. | |
306 | */ | |
307 | #define switch_posix(_ret) if ((_ret) < 0 || (errno = 0, 1)) switch (errno) | |
308 | ||
309 | /*! | |
310 | * @function size_unsigned | |
311 | * Converts a signed size quantity into an unsigned size quantity after | |
312 | * verifying the former can be represented as the latter. | |
313 | * | |
314 | * @param ss | |
315 | * The signed size quantity. | |
316 | * | |
317 | * @result | |
318 | * The unsigned representation of {@link ss}. | |
319 | * | |
320 | * @discussion | |
321 | * This routine is useful for passing a signed value (such as the size of a file | |
322 | * from a stat(2) structure) into a routine which accepts unsigned input | |
323 | * (e.g. write(2)). | |
324 | */ | |
325 | OS_ALWAYS_INLINE OS_WARN_RESULT | |
326 | static inline size_t | |
327 | size_unsigned(ssize_t ss) | |
328 | { | |
329 | if (ss < 0) { | |
330 | os_crash("value not representable as size_t"); | |
331 | } | |
332 | return (size_t)ss; | |
333 | } | |
334 | ||
335 | /*! | |
336 | * @function size_signed | |
337 | * Converts an unsigned size quantity into a signed size quantity after | |
338 | * verifying the former can be represented as the latter. | |
339 | * | |
340 | * @param un | |
341 | * The unsigned size quantity. | |
342 | * | |
343 | * @result | |
344 | * The signed representation of {@link un}. | |
345 | * | |
346 | * @discussion | |
347 | * This routine is useful for comparing an unsigned value (such as a number of | |
348 | * bytes) to the result of a routine which returns a signed type but only ever | |
349 | * returns a negative number in the event of an error (e.g. read(2)). | |
350 | */ | |
351 | OS_ALWAYS_INLINE OS_WARN_RESULT | |
352 | static inline ssize_t | |
353 | size_signed(size_t un) | |
354 | { | |
355 | if (un > SSIZE_MAX) { | |
356 | os_crash("value not representable as ssize_t"); | |
357 | } | |
358 | return (ssize_t)un; | |
359 | } | |
360 | ||
70ad1dc8 A |
361 | /*! |
362 | * @function os_localtime_file | |
363 | * A routine to generate a time stamp that is suitable for embedding in a file | |
364 | * name. | |
365 | * | |
366 | * @param buff | |
367 | * A pointer to a buffer where the resulting time stamp will be stored. | |
368 | * | |
369 | * @discussion | |
370 | * The resulting time stamp will not include characters which require escaping | |
371 | * in shells, such as spaces. The current implementation format is | |
372 | * | |
373 | * YYYY-MM-DD_HH.MM.SS.us | |
374 | * | |
375 | * e.g. | |
376 | * | |
377 | * 2017-04-24_12.45.15.045609 | |
378 | */ | |
379 | DARWIN_API_AVAILABLE_20170407 | |
380 | OS_EXPORT | |
381 | void | |
507116e3 | 382 | os_localtime_file(char buff[static 32]); |
70ad1dc8 A |
383 | |
384 | /*! | |
385 | * @function os_simple_hash | |
386 | * An implementation of a simple non-cryptographic hashing algorithm. | |
387 | * | |
388 | * @param buff | |
389 | * A pointer to the buffer to hash. | |
390 | * | |
391 | * @param len | |
392 | * The length of the buffer. | |
393 | * | |
394 | * @result | |
395 | * The hashed value of the input. | |
396 | * | |
397 | * @discussion | |
398 | * This routine is meant to be used as a simple way to obtain a value that can | |
399 | * be used to choose a bucket in a simple hash table. Do not attach security | |
507116e3 | 400 | * assumptions to the output of this routine. Do not assume that the computed |
70ad1dc8 A |
401 | * hash is stable between hosts, OS versions, or boot sessions. |
402 | */ | |
403 | DARWIN_API_AVAILABLE_20170407 | |
404 | OS_EXPORT OS_NONNULL1 | |
405 | uint64_t | |
406 | os_simple_hash(const void *buff, size_t len); | |
407 | ||
507116e3 A |
408 | /*! |
409 | * @function os_simple_hash_with_seed | |
410 | * A seeded variant of os_simple_hash. | |
411 | * | |
412 | * @param buff | |
413 | * A pointer to the buffer to hash. | |
414 | * | |
415 | * @param len | |
416 | * The length of the buffer. | |
417 | * | |
418 | * @param seed | |
419 | * The seed value for the hash. | |
420 | * | |
421 | * @result | |
422 | * The hashed value of the input. | |
423 | * | |
424 | * @discussion | |
425 | * Usually, hashing the same buffer with different seeds will produce | |
426 | * different hash values. | |
427 | * All the same considerations of {@link os_simple_hash} apply. | |
428 | */ | |
429 | DARWIN_API_AVAILABLE_20181020 | |
430 | OS_EXPORT OS_NONNULL1 | |
431 | uint64_t | |
432 | os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed); | |
433 | ||
70ad1dc8 A |
434 | /*! |
435 | * @function os_simple_hash_string | |
436 | * An implementation of a simple non-cryptographic hashing algorithm. | |
437 | * | |
438 | * @param string | |
439 | * A pointer to the null-terminated string to hash. | |
440 | * | |
441 | * @result | |
442 | * The hashed value of the input. | |
443 | * | |
444 | * @discussion | |
445 | * This routine is the moral equivalent of a call to | |
446 | * | |
507116e3 | 447 | * os_simple_hash(buff, strlen(buff)); |
70ad1dc8 A |
448 | * |
449 | * All the same considerations of {@link os_simple_hash} apply. | |
450 | */ | |
451 | DARWIN_API_AVAILABLE_20170407 | |
452 | OS_EXPORT OS_NONNULL1 | |
453 | uint64_t | |
454 | os_simple_hash_string(const char *string); | |
455 | ||
507116e3 A |
456 | /*! |
457 | * @function os_simple_hash_string_with_seed | |
458 | * A seeded variant of os_simple_hash_string. | |
459 | * | |
460 | * @param string | |
461 | * A pointer to the null-terminated string to hash. | |
462 | * | |
463 | * @result | |
464 | * The hashed value of the input. | |
465 | * | |
466 | * @discussion | |
467 | * Usually, hashing the same string with different seeds will produce | |
468 | * different hash values. | |
469 | * All the same considerations of {@link os_simple_hash_string} apply. | |
470 | */ | |
471 | DARWIN_API_AVAILABLE_20181020 | |
472 | OS_EXPORT OS_NONNULL1 | |
473 | uint64_t | |
474 | os_simple_hash_string_with_seed(const char *string, uint64_t seed); | |
475 | ||
476 | /*! | |
477 | * @function realpath_np | |
478 | * Obtains a fully-resolved representation of the path to the file represented | |
479 | * by the given descriptor. | |
480 | * | |
481 | * @param fd | |
482 | * The file descriptor whose path is to be obtained. | |
483 | * | |
484 | * @param buff | |
485 | * The buffer in which to write the path. | |
486 | * | |
487 | * @result | |
488 | * On success, zero is returned. Otherwise, the implementation may return any | |
489 | * error that can be returned by fcntl(2). | |
490 | */ | |
491 | DARWIN_API_AVAILABLE_20180727 | |
492 | OS_EXPORT OS_WARN_RESULT | |
493 | errno_t | |
494 | realpath_np(os_fd_t fd, char buff[static PATH_MAX]); | |
495 | ||
e1ee4b85 A |
496 | /*! |
497 | * @function memdup_np | |
498 | * Copies the given range of bytes into a new allocation. | |
499 | * | |
500 | * @param _new | |
501 | * Upon successful return, a pointer to a new allocation which has had the given | |
502 | * source bytes copied into it. The caller is responsible for calling free(3) on | |
503 | * this object when it is no longer needed. | |
504 | * | |
505 | * @param src | |
506 | * The bytes to copy. | |
507 | * | |
508 | * @param len | |
509 | * The number of bytes to copy. | |
510 | * | |
511 | * @result | |
512 | * On success, zero is returned. Otherwise, the implementation may return any | |
513 | * error that can be returned by malloc(3). | |
514 | */ | |
515 | DARWIN_API_AVAILABLE_20190830 | |
516 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 | |
517 | errno_t | |
518 | memdup_np(void **_new, const void *src, size_t len); | |
519 | ||
520 | /*! | |
521 | * @function memdup2_np | |
522 | * Variant of {@link memdup_np} which guarantees that memory duplication will | |
523 | * either succeed or not return (terminating the caller). | |
524 | * | |
525 | * @param src | |
526 | * The bytes to copy. | |
527 | * | |
528 | * @param len | |
529 | * The number of bytes to copy. | |
530 | * | |
531 | * @result | |
532 | * On success, a pointer to the new allocation which has had the given source | |
533 | * bytes copied into it. The caller is responsible for calling free(3) on this | |
534 | * object when it is no longer needed. | |
535 | */ | |
536 | DARWIN_API_AVAILABLE_20190830 | |
537 | OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1 | |
538 | void * | |
539 | memdup2_np(const void *src, size_t len); | |
540 | ||
70ad1dc8 A |
541 | __END_DECLS; |
542 | ||
543 | #endif // __DARWIN_STDLIB_H |