2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
20 * \brief Utility functions
23 #ifndef _ASTERISK_UTILS_H
24 #define _ASTERISK_UTILS_H
26 #include "asterisk/network.h"
28 #include <time.h> /* we want to override localtime_r */
32 #include "asterisk/lock.h"
33 #include "asterisk/time.h"
34 #include "asterisk/logger.h"
35 #include "asterisk/localtime.h"
36 #include "asterisk/stringfields.h"
41 It is very important to use only unsigned variables to hold
42 bit flags, as otherwise you can fall prey to the compiler's
43 sign-extension antics if you try to use the top two bits in
46 The flag macros below use a set of compiler tricks to verify
47 that the caller is using an "unsigned int" variable to hold
48 the flags, and nothing else. If the caller uses any other
49 type of variable, a warning message similar to this:
51 warning: comparison of distinct pointer types lacks cast
54 The "dummy" variable below is used to make these comparisons.
56 Also note that at -O2 or above, this type-safety checking
57 does _not_ produce any additional object code at all.
61 extern unsigned int __unsigned_int_flags_dummy;
63 #define ast_test_flag(p,flag) ({ \
64 typeof ((p)->flags) __p = (p)->flags; \
65 typeof (__unsigned_int_flags_dummy) __x = 0; \
66 (void) (&__p == &__x); \
67 ((p)->flags & (flag)); \
70 #define ast_set_flag(p,flag) do { \
71 typeof ((p)->flags) __p = (p)->flags; \
72 typeof (__unsigned_int_flags_dummy) __x = 0; \
73 (void) (&__p == &__x); \
74 ((p)->flags |= (flag)); \
77 #define ast_clear_flag(p,flag) do { \
78 typeof ((p)->flags) __p = (p)->flags; \
79 typeof (__unsigned_int_flags_dummy) __x = 0; \
80 (void) (&__p == &__x); \
81 ((p)->flags &= ~(flag)); \
84 #define ast_copy_flags(dest,src,flagz) do { \
85 typeof ((dest)->flags) __d = (dest)->flags; \
86 typeof ((src)->flags) __s = (src)->flags; \
87 typeof (__unsigned_int_flags_dummy) __x = 0; \
88 (void) (&__d == &__x); \
89 (void) (&__s == &__x); \
90 (dest)->flags &= ~(flagz); \
91 (dest)->flags |= ((src)->flags & (flagz)); \
94 #define ast_set2_flag(p,value,flag) do { \
95 typeof ((p)->flags) __p = (p)->flags; \
96 typeof (__unsigned_int_flags_dummy) __x = 0; \
97 (void) (&__p == &__x); \
99 (p)->flags |= (flag); \
101 (p)->flags &= ~(flag); \
104 #define ast_set_flags_to(p,flag,value) do { \
105 typeof ((p)->flags) __p = (p)->flags; \
106 typeof (__unsigned_int_flags_dummy) __x = 0; \
107 (void) (&__p == &__x); \
108 (p)->flags &= ~(flag); \
109 (p)->flags |= (value); \
113 /* The following 64-bit flag code can most likely be erased after app_dial
114 is reorganized to either reduce the large number of options, or handle
115 them in some other way. At the time of this writing, app_dial would be
116 the only user of 64-bit option flags */
118 extern uint64_t __unsigned_int_flags_dummy64;
120 #define ast_test_flag64(p,flag) ({ \
121 typeof ((p)->flags) __p = (p)->flags; \
122 typeof (__unsigned_int_flags_dummy64) __x = 0; \
123 (void) (&__p == &__x); \
124 ((p)->flags & (flag)); \
127 #define ast_set_flag64(p,flag) do { \
128 typeof ((p)->flags) __p = (p)->flags; \
129 typeof (__unsigned_int_flags_dummy64) __x = 0; \
130 (void) (&__p == &__x); \
131 ((p)->flags |= (flag)); \
134 #define ast_clear_flag64(p,flag) do { \
135 typeof ((p)->flags) __p = (p)->flags; \
136 typeof (__unsigned_int_flags_dummy64) __x = 0; \
137 (void) (&__p == &__x); \
138 ((p)->flags &= ~(flag)); \
141 #define ast_copy_flags64(dest,src,flagz) do { \
142 typeof ((dest)->flags) __d = (dest)->flags; \
143 typeof ((src)->flags) __s = (src)->flags; \
144 typeof (__unsigned_int_flags_dummy64) __x = 0; \
145 (void) (&__d == &__x); \
146 (void) (&__s == &__x); \
147 (dest)->flags &= ~(flagz); \
148 (dest)->flags |= ((src)->flags & (flagz)); \
151 #define ast_set2_flag64(p,value,flag) do { \
152 typeof ((p)->flags) __p = (p)->flags; \
153 typeof (__unsigned_int_flags_dummy64) __x = 0; \
154 (void) (&__p == &__x); \
156 (p)->flags |= (flag); \
158 (p)->flags &= ~(flag); \
161 #define ast_set_flags_to64(p,flag,value) do { \
162 typeof ((p)->flags) __p = (p)->flags; \
163 typeof (__unsigned_int_flags_dummy64) __x = 0; \
164 (void) (&__p == &__x); \
165 (p)->flags &= ~(flag); \
166 (p)->flags |= (value); \
170 /* Non-type checking variations for non-unsigned int flags. You
171 should only use non-unsigned int flags where required by
172 protocol etc and if you know what you're doing :) */
173 #define ast_test_flag_nonstd(p,flag) \
174 ((p)->flags & (flag))
176 #define ast_set_flag_nonstd(p,flag) do { \
177 ((p)->flags |= (flag)); \
180 #define ast_clear_flag_nonstd(p,flag) do { \
181 ((p)->flags &= ~(flag)); \
184 #define ast_copy_flags_nonstd(dest,src,flagz) do { \
185 (dest)->flags &= ~(flagz); \
186 (dest)->flags |= ((src)->flags & (flagz)); \
189 #define ast_set2_flag_nonstd(p,value,flag) do { \
191 (p)->flags |= (flag); \
193 (p)->flags &= ~(flag); \
196 #define AST_FLAGS_ALL UINT_MAX
198 /*! \brief Structure used to handle boolean flags */
203 /*! \brief Structure used to handle a large number of boolean flags == used only in app_dial? */
213 /*! \brief Thread-safe gethostbyname function to use in Asterisk */
214 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
216 /*! \brief Produces MD5 hash based on input string */
217 void ast_md5_hash(char *output, const char *input);
218 /*! \brief Produces SHA1 hash based on input string */
219 void ast_sha1_hash(char *output, const char *input);
220 /*! \brief Produces SHA1 hash based on input string, stored in uint8_t array */
221 void ast_sha1_hash_uint(uint8_t *digest, const char *input);
223 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
226 #define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
228 #define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
230 #define SWAP(a,b) do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
233 * \brief Encode data in base64
234 * \param dst the destination buffer
235 * \param src the source data to be encoded
236 * \param srclen the number of bytes present in the source buffer
237 * \param max the maximum number of bytes to write into the destination
238 * buffer, *including* the terminating NULL character.
240 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
243 * \brief Decode data from base64
244 * \param dst the destination buffer
245 * \param src the source buffer
246 * \param max The maximum number of bytes to write into the destination
247 * buffer. Note that this function will not ensure that the
248 * destination buffer is NULL terminated. So, in general,
249 * this parameter should be sizeof(dst) - 1.
251 int ast_base64decode(unsigned char *dst, const char *src, int max);
253 #define AST_URI_ALPHANUM (1 << 0)
254 #define AST_URI_MARK (1 << 1)
255 #define AST_URI_UNRESERVED (AST_URI_ALPHANUM | AST_URI_MARK)
256 #define AST_URI_LEGACY_SPACE (1 << 2)
258 #define AST_URI_SIP_USER_UNRESERVED (1 << 20)
260 extern const struct ast_flags ast_uri_http;
261 extern const struct ast_flags ast_uri_http_legacy;
262 extern const struct ast_flags ast_uri_sip_user;
265 * \brief Turn text string to URI-encoded %XX version
267 * This function encodes characters according to the rules presented in RFC
268 * 2396 and/or RFC 3261 section 19.1.2 and section 25.1.
270 * Outbuf needs to have more memory allocated than the instring to have room
271 * for the expansion. Every byte that is converted is replaced by three ASCII
274 * \param string string to be converted
275 * \param outbuf resulting encoded string
276 * \param buflen size of output buffer
277 * \param spec flags describing how the encoding should be performed
278 * \return a pointer to the uri encoded string
280 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec);
283 * \brief Decode URI, URN, URL (overwrite string)
285 * \note The ast_uri_http_legacy decode spec flag will cause this function to
288 * \param s string to be decoded
289 * \param spec flags describing how the decoding should be performed
291 void ast_uri_decode(char *s, struct ast_flags spec);
294 \brief Escape reserved characters for use in XML.
296 If \a outbuf is too short, the output string will be truncated.
297 Regardless, the output will always be null terminated.
299 \param string String to be converted
300 \param outbuf Resulting encoded string
301 \param buflen Size of output buffer
302 \return 0 for success
303 \return -1 if buflen is too short.
305 int ast_xml_escape(const char *string, char *outbuf, size_t buflen);
308 * \brief Escape characters found in a quoted string.
310 * \note This function escapes quoted characters based on the 'qdtext' set of
311 * allowed characters from RFC 3261 section 25.1.
313 * \param string string to be escaped
314 * \param outbuf resulting escaped string
315 * \param buflen size of output buffer
316 * \return a pointer to the escaped string
318 char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
320 static force_inline void ast_slinear_saturated_add(short *input, short *value)
324 res = (int) *input + *value;
327 else if (res < -32768)
330 *input = (short) res;
333 static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
337 res = (int) *input - *value;
340 else if (res < -32768)
343 *input = (short) res;
346 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
350 res = (int) *input * *value;
353 else if (res < -32768)
356 *input = (short) res;
359 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
367 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
369 int ast_utils_init(void);
370 int ast_wait_for_input(int fd, int ms);
373 * \brief Try to write string, but wait no more than ms milliseconds
376 * \note If you are calling ast_carefulwrite, it is assumed that you are calling
377 * it on a file descriptor that _DOES_ have NONBLOCK set. This way,
378 * there is only one system call made to do a write, unless we actually
379 * have a need to wait. This way, we get better performance.
381 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
384 * \brief Write data to a file stream with a timeout
386 * \param f the file stream to write to
387 * \param fd the file description to poll on to know when the file stream can
388 * be written to without blocking.
389 * \param s the buffer to write from
390 * \param len the number of bytes to write
391 * \param timeoutms The maximum amount of time to block in this function trying
392 * to write, specified in milliseconds.
394 * \note This function assumes that the associated file stream has been set up
400 int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
403 * Thread management support (should be moved to lock.h or a different header)
406 #define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
408 #if defined(LOW_MEMORY)
409 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
411 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
414 void ast_register_thread(char *name);
415 void ast_unregister_thread(void *id);
417 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
418 void *data, size_t stacksize, const char *file, const char *caller,
419 int line, const char *start_fn);
421 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
422 void *data, size_t stacksize, const char *file, const char *caller,
423 int line, const char *start_fn);
425 #define ast_pthread_create(a, b, c, d) \
426 ast_pthread_create_stack(a, b, c, d, \
427 0, __FILE__, __FUNCTION__, __LINE__, #c)
429 #define ast_pthread_create_detached(a, b, c, d) \
430 ast_pthread_create_detached_stack(a, b, c, d, \
431 0, __FILE__, __FUNCTION__, __LINE__, #c)
433 #define ast_pthread_create_background(a, b, c, d) \
434 ast_pthread_create_stack(a, b, c, d, \
435 AST_BACKGROUND_STACKSIZE, \
436 __FILE__, __FUNCTION__, __LINE__, #c)
438 #define ast_pthread_create_detached_background(a, b, c, d) \
439 ast_pthread_create_detached_stack(a, b, c, d, \
440 AST_BACKGROUND_STACKSIZE, \
441 __FILE__, __FUNCTION__, __LINE__, #c)
443 /* End of thread management support */
446 * \brief Replace '^' in a string with ','
447 * \param s String within which to replace characters
449 void ast_replace_subargument_delimiter(char *s);
452 * \brief Process a string to find and replace characters
453 * \param start The string to analyze
454 * \param find The character to find
455 * \param replace_with The character that will replace the one we are looking for
457 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
459 long int ast_random(void);
462 * \brief Returns a random number between 0.0 and 1.0, inclusive.
465 #define ast_random_double() (((double)ast_random()) / RAND_MAX)
468 * \brief free() wrapper
470 * ast_free_ptr should be used when a function pointer for free() needs to be passed
471 * as the argument to a function. Otherwise, astmm will cause seg faults.
473 #ifdef __AST_DEBUG_MALLOC
474 static void ast_free_ptr(void *ptr) attribute_unused;
475 static void ast_free_ptr(void *ptr)
480 #define ast_free free
481 #define ast_free_ptr ast_free
484 #ifndef __AST_DEBUG_MALLOC
486 #define MALLOC_FAILURE_MSG \
487 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
489 * \brief A wrapper for malloc()
491 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
492 * message in the case that the allocation fails.
494 * The argument and return value are the same as malloc()
496 #define ast_malloc(len) \
497 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
500 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
504 if (!(p = malloc(len)))
512 * \brief A wrapper for calloc()
514 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
515 * message in the case that the allocation fails.
517 * The arguments and return value are the same as calloc()
519 #define ast_calloc(num, len) \
520 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
523 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
527 if (!(p = calloc(num, len)))
535 * \brief A wrapper for calloc() for use in cache pools
537 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
538 * message in the case that the allocation fails. When memory debugging is in use,
539 * the memory allocated by this function will be marked as 'cache' so it can be
540 * distinguished from normal memory allocations.
542 * The arguments and return value are the same as calloc()
544 #define ast_calloc_cache(num, len) \
545 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
548 * \brief A wrapper for realloc()
550 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
551 * message in the case that the allocation fails.
553 * The arguments and return value are the same as realloc()
555 #define ast_realloc(p, len) \
556 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
559 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
563 if (!(newp = realloc(p, len)))
571 * \brief A wrapper for strdup()
573 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
574 * message in the case that the allocation fails.
576 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
577 * argument is provided, ast_strdup will return NULL without generating any
578 * kind of error log message.
580 * The argument and return value are the same as strdup()
582 #define ast_strdup(str) \
583 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
586 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
591 if (!(newstr = strdup(str)))
600 * \brief A wrapper for strndup()
602 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
603 * message in the case that the allocation fails.
605 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
606 * string to duplicate. If a NULL argument is provided, ast_strdup will return
607 * NULL without generating any kind of error log message.
609 * The arguments and return value are the same as strndup()
611 #define ast_strndup(str, len) \
612 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
615 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
620 if (!(newstr = strndup(str, len)))
629 * \brief A wrapper for asprintf()
631 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
632 * message in the case that the allocation fails.
634 * The arguments and return value are the same as asprintf()
636 #define ast_asprintf(ret, fmt, ...) \
637 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
639 int __attribute__((format(printf, 5, 6)))
640 _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
643 * \brief A wrapper for vasprintf()
645 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
646 * message in the case that the allocation fails.
648 * The arguments and return value are the same as vasprintf()
650 #define ast_vasprintf(ret, fmt, ap) \
651 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
654 __attribute__((format(printf, 5, 0)))
655 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
659 if ((res = vasprintf(ret, fmt, ap)) == -1)
666 #endif /* AST_DEBUG_MALLOC */
669 \brief call __builtin_alloca to ensure we get gcc builtin semantics
670 \param size The size of the buffer we want allocated
672 This macro will attempt to allocate memory from the stack. If it fails
673 you won't get a NULL returned, but a SEGFAULT if you're lucky.
675 #define ast_alloca(size) __builtin_alloca(size)
677 #if !defined(ast_strdupa) && defined(__GNUC__)
679 * \brief duplicate a string in memory from the stack
680 * \param s The string to duplicate
682 * This macro will duplicate the given string. It returns a pointer to the stack
683 * allocatted memory for the new string.
685 #define ast_strdupa(s) \
688 const char *__old = (s); \
689 size_t __len = strlen(__old) + 1; \
690 char *__new = __builtin_alloca(__len); \
691 memcpy (__new, __old, __len); \
697 * \brief Disable PMTU discovery on a socket
698 * \param sock The socket to manipulate
701 * On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
702 * bit set. This is supposedly done to allow the application to do PMTU
703 * discovery, but Asterisk does not do this.
705 * Because of this, UDP packets sent by Asterisk that are larger than the MTU
706 * of any hop in the path will be lost. This function can be called on a socket
707 * to ensure that the DF bit will not be set.
709 void ast_enable_packet_fragmentation(int sock);
712 * \brief Recursively create directory path
713 * \param path The directory path to create
714 * \param mode The permissions with which to try to create the directory
715 * \return 0 on success or an error code otherwise
717 * Creates a directory path, creating parent directories as needed.
719 int ast_mkdir(const char *path, int mode);
721 #define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
724 /* Definition for Digest authorization */
725 struct ast_http_digest {
726 AST_DECLARE_STRING_FIELDS(
727 AST_STRING_FIELD(username);
728 AST_STRING_FIELD(nonce);
729 AST_STRING_FIELD(uri);
730 AST_STRING_FIELD(realm);
731 AST_STRING_FIELD(domain);
732 AST_STRING_FIELD(response);
733 AST_STRING_FIELD(cnonce);
734 AST_STRING_FIELD(opaque);
735 AST_STRING_FIELD(nc);
737 int qop; /* Flag set to 1, if we send/recv qop="quth" */
741 * \brief Parse digest authorization header.
742 * \return Returns -1 if we have no auth or something wrong with digest.
743 * \note This function may be used for Digest request and responce header.
744 * request arg is set to nonzero, if we parse Digest Request.
745 * pedantic arg can be set to nonzero if we need to do addition Digest check.
747 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
751 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function);
752 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
753 static void force_inline _ast_assert(int condition, const char *condition_str, const char *file, int line, const char *function)
755 if (__builtin_expect(!condition, 1)) {
756 __ast_assert_failed(condition, condition_str, file, line, function);
760 #define ast_assert(a)
764 * \brief Force a crash if DO_CRASH is defined.
766 * \note If DO_CRASH is not defined then the function returns.
770 void ast_do_crash(void);
772 #include "asterisk/strings.h"
775 * \brief Return the number of bytes used in the alignment of type.
777 * \return The number of bytes required for alignment.
779 * This is really just __alignof__(), but tucked away in this header so we
780 * don't have to look at the nasty underscores in the source.
782 #define ast_alignof(type) __alignof__(type)
785 * \brief Increase offset so it is a multiple of the required alignment of type.
786 * \param offset The value that should be increased.
787 * \param type The data type that offset should be aligned to.
788 * \return The smallest multiple of alignof(type) larger than or equal to offset.
789 * \see ast_make_room_for()
791 * Many systems prefer integers to be stored on aligned on memory locations.
792 * This macro will increase an offset so a value of the supplied type can be
793 * safely be stored on such a memory location.
796 * ast_align_for(0x17, int64_t) ==> 0x18
797 * ast_align_for(0x18, int64_t) ==> 0x18
798 * ast_align_for(0x19, int64_t) ==> 0x20
800 * Don't mind the ugliness, the compiler will optimize it.
802 #define ast_align_for(offset, type) (((offset + __alignof__(type) - 1) / __alignof__(type)) * __alignof__(type))
805 * \brief Increase offset by the required alignment of type and make sure it is
806 * a multiple of said alignment.
807 * \param offset The value that should be increased.
808 * \param type The data type that room should be reserved for.
809 * \return The smallest multiple of alignof(type) larger than or equal to offset
810 * plus alignof(type).
811 * \see ast_align_for()
813 * A use case for this is when prepending length fields of type int to a buffer.
814 * If you keep the offset a multiple of the alignment of the integer type,
815 * a next block of length+buffer will have the length field automatically
819 * ast_make_room_for(0x17, int64_t) ==> 0x20
820 * ast_make_room_for(0x18, int64_t) ==> 0x20
821 * ast_make_room_for(0x19, int64_t) ==> 0x28
823 * Don't mind the ugliness, the compiler will optimize it.
825 #define ast_make_room_for(offset, type) (((offset + (2 * __alignof__(type) - 1)) / __alignof__(type)) * __alignof__(type))
828 * \brief An Entity ID is essentially a MAC address, brief and unique
831 unsigned char eid[6];
832 } __attribute__((__packed__));
837 * This is set in asterisk.conf, or determined automatically by taking the mac
838 * address of an Ethernet interface on the system.
840 extern struct ast_eid ast_eid_default;
843 * \brief Fill in an ast_eid with the default eid of this machine
846 void ast_set_default_eid(struct ast_eid *eid);
849 * \brief Convert an EID to a string
852 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
855 * \brief Convert a string into an EID
857 * This function expects an EID in the format:
860 * \return 0 success, non-zero failure
863 int ast_str_to_eid(struct ast_eid *eid, const char *s);
866 * \brief Compare two EIDs
868 * \return 0 if the two are the same, non-zero otherwise
871 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
874 * \brief Get current thread ID
875 * \return the ID if platform is supported, else -1
877 int ast_get_tid(void);
880 * \brief Resolve a binary to a full pathname
881 * \param binary Name of the executable to resolve
882 * \param fullpath Buffer to hold the complete pathname
883 * \param fullpath_size Size of \a fullpath
884 * \retval NULL \a binary was not found or the environment variable PATH is not set
885 * \return \a fullpath
887 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
890 * \brief Declare a variable that will call a destructor function when it goes out of scope.
892 * Resource Allocation Is Initialization (RAII) variable declaration.
895 * \param vartype The type of the variable
896 * \param varname The name of the variable
897 * \param initval The initial value of the variable
898 * \param dtor The destructor function of type' void func(vartype *)'
901 * void mything_cleanup(struct mything *t)
904 * ast_free(t->stuff);
908 * void do_stuff(const char *name)
910 * RAII_VAR(struct mything *, thing, mything_alloc(name), mything_cleanup);
915 * \note This macro is especially useful for working with ao2 objects. A common idiom
916 * would be a function that needed to look up an ao2 object and might have several error
917 * conditions after the allocation that would normally need to unref the ao2 object.
918 * With RAII_VAR, it is possible to just return and leave the cleanup to the destructor
919 * function. For example:
922 * void do_stuff(const char *name)
924 * RAII_VAR(struct mything *, thing, find_mything(name), ao2_cleanup);
931 * do_stuff_with_thing(thing);
935 #define RAII_VAR(vartype, varname, initval, dtor) \
936 /* Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774 */ \
937 auto void _dtor_ ## varname (vartype * v); \
938 void _dtor_ ## varname (vartype * v) { dtor(*v); } \
939 vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
941 #endif /* _ASTERISK_UTILS_H */