pki: Also check for MAX_COMMANDS when building getopt_long arguments
[strongswan.git] / src / libstrongswan / utils / utils.h
1 /*
2 * Copyright (C) 2008-2014 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /**
18 * @defgroup utils_i utils
19 * @{ @ingroup utils
20 */
21
22 #ifndef UTILS_H_
23 #define UTILS_H_
24
25 #include <sys/types.h>
26 #include <stdlib.h>
27 #include <stddef.h>
28 #include <sys/time.h>
29 #include <string.h>
30
31 #ifdef WIN32
32 # include "windows.h"
33 #else
34 # define _GNU_SOURCE
35 # include <arpa/inet.h>
36 # include <sys/socket.h>
37 # include <netdb.h>
38 # include <netinet/in.h>
39 # include <sched.h>
40 #endif
41
42 /**
43 * strongSwan program return codes
44 */
45 #define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
46 #define SS_RC_DAEMON_INTEGRITY 65
47 #define SS_RC_INITIALIZATION_FAILED 66
48
49 #define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
50 #define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
51
52 /**
53 * Number of bits in a byte
54 */
55 #define BITS_PER_BYTE 8
56
57 /**
58 * Default length for various auxiliary text buffers
59 */
60 #define BUF_LEN 512
61
62 /**
63 * General purpose boolean type.
64 */
65 #ifdef HAVE_STDBOOL_H
66 # include <stdbool.h>
67 #else
68 # ifndef HAVE__BOOL
69 # define _Bool signed char
70 # endif /* HAVE__BOOL */
71 # define bool _Bool
72 # define false 0
73 # define true 1
74 # define __bool_true_false_are_defined 1
75 #endif /* HAVE_STDBOOL_H */
76 #ifndef FALSE
77 # define FALSE false
78 #endif /* FALSE */
79 #ifndef TRUE
80 # define TRUE true
81 #endif /* TRUE */
82
83 #include "enum.h"
84 #include "utils/strerror.h"
85
86 /**
87 * Directory separator character in paths on this platform
88 */
89 #ifdef WIN32
90 # define DIRECTORY_SEPARATOR "\\"
91 #else
92 # define DIRECTORY_SEPARATOR "/"
93 #endif
94
95 /**
96 * Initialize utility functions
97 */
98 void utils_init();
99
100 /**
101 * Deinitialize utility functions
102 */
103 void utils_deinit();
104
105 /**
106 * Helper function that compares two strings for equality
107 */
108 static inline bool streq(const char *x, const char *y)
109 {
110 return strcmp(x, y) == 0;
111 }
112
113 /**
114 * Helper function that compares two strings for equality, length limited
115 */
116 static inline bool strneq(const char *x, const char *y, size_t len)
117 {
118 return strncmp(x, y, len) == 0;
119 }
120
121 /**
122 * Helper function that checks if a string starts with a given prefix
123 */
124 static inline bool strpfx(const char *x, const char *prefix)
125 {
126 return strneq(x, prefix, strlen(prefix));
127 }
128
129 /**
130 * Helper function that compares two strings for equality ignoring case
131 */
132 static inline bool strcaseeq(const char *x, const char *y)
133 {
134 return strcasecmp(x, y) == 0;
135 }
136
137 /**
138 * Helper function that compares two strings for equality ignoring case, length limited
139 */
140 static inline bool strncaseeq(const char *x, const char *y, size_t len)
141 {
142 return strncasecmp(x, y, len) == 0;
143 }
144
145 /**
146 * Helper function that checks if a string starts with a given prefix
147 */
148 static inline bool strcasepfx(const char *x, const char *prefix)
149 {
150 return strncaseeq(x, prefix, strlen(prefix));
151 }
152
153 /**
154 * NULL-safe strdup variant
155 */
156 static inline char *strdupnull(const char *s)
157 {
158 return s ? strdup(s) : NULL;
159 }
160
161 /**
162 * Helper function that compares two binary blobs for equality
163 */
164 static inline bool memeq(const void *x, const void *y, size_t len)
165 {
166 return memcmp(x, y, len) == 0;
167 }
168
169 /**
170 * Macro gives back larger of two values.
171 */
172 #define max(x,y) ({ \
173 typeof(x) _x = (x); \
174 typeof(y) _y = (y); \
175 _x > _y ? _x : _y; })
176
177
178 /**
179 * Macro gives back smaller of two values.
180 */
181 #define min(x,y) ({ \
182 typeof(x) _x = (x); \
183 typeof(y) _y = (y); \
184 _x < _y ? _x : _y; })
185
186 /**
187 * Call destructor of an object, if object != NULL
188 */
189 #define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
190
191 /**
192 * Call offset destructor of an object, if object != NULL
193 */
194 #define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
195
196 /**
197 * Call function destructor of an object, if object != NULL
198 */
199 #define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
200
201 /**
202 * Debug macro to follow control flow
203 */
204 #define POS printf("%s, line %d\n", __FILE__, __LINE__)
205
206 /**
207 * Object allocation/initialization macro, using designated initializer.
208 */
209 #define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
210 *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
211
212 /**
213 * Method declaration/definition macro, providing private and public interface.
214 *
215 * Defines a method name with this as first parameter and a return value ret,
216 * and an alias for this method with a _ prefix, having the this argument
217 * safely casted to the public interface iface.
218 * _name is provided a function pointer, but will get optimized out by GCC.
219 */
220 #define METHOD(iface, name, ret, this, ...) \
221 static ret name(union {iface *_public; this;} \
222 __attribute__((transparent_union)), ##__VA_ARGS__); \
223 static typeof(name) *_##name = (typeof(name)*)name; \
224 static ret name(this, ##__VA_ARGS__)
225
226 /**
227 * Same as METHOD(), but is defined for two public interfaces.
228 */
229 #define METHOD2(iface1, iface2, name, ret, this, ...) \
230 static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
231 __attribute__((transparent_union)), ##__VA_ARGS__); \
232 static typeof(name) *_##name = (typeof(name)*)name; \
233 static ret name(this, ##__VA_ARGS__)
234
235 /**
236 * Callback declaration/definition macro, allowing casted first parameter.
237 *
238 * This is very similar to METHOD, but instead of casting the first parameter
239 * to a public interface, it uses a void*. This allows type safe definition
240 * of a callback function, while using the real type for the first parameter.
241 */
242 #define CALLBACK(name, ret, param1, ...) \
243 static ret _cb_##name(union {void *_generic; param1;} \
244 __attribute__((transparent_union)), ##__VA_ARGS__); \
245 static typeof(_cb_##name) *name = (typeof(_cb_##name)*)_cb_##name; \
246 static ret _cb_##name(param1, ##__VA_ARGS__)
247
248 /**
249 * Architecture independent bitfield definition helpers (at least with GCC).
250 *
251 * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
252 * BITFIELD2(u_int8_t,
253 * low: 4,
254 * high: 4,
255 * ) flags;
256 * The member defined first placed at bit 0.
257 */
258 #if BYTE_ORDER == LITTLE_ENDIAN
259 #define BITFIELD2(t, a, b,...) struct { t a; t b; __VA_ARGS__}
260 #define BITFIELD3(t, a, b, c,...) struct { t a; t b; t c; __VA_ARGS__}
261 #define BITFIELD4(t, a, b, c, d,...) struct { t a; t b; t c; t d; __VA_ARGS__}
262 #define BITFIELD5(t, a, b, c, d, e,...) struct { t a; t b; t c; t d; t e; __VA_ARGS__}
263 #elif BYTE_ORDER == BIG_ENDIAN
264 #define BITFIELD2(t, a, b,...) struct { t b; t a; __VA_ARGS__}
265 #define BITFIELD3(t, a, b, c,...) struct { t c; t b; t a; __VA_ARGS__}
266 #define BITFIELD4(t, a, b, c, d,...) struct { t d; t c; t b; t a; __VA_ARGS__}
267 #define BITFIELD5(t, a, b, c, d, e,...) struct { t e; t d; t c; t b; t a; __VA_ARGS__}
268 #endif
269
270 /**
271 * Macro to allocate a sized type.
272 */
273 #define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
274
275 /**
276 * Get the number of elements in an array
277 */
278 #define countof(array) (sizeof(array)/sizeof(array[0]))
279
280 /**
281 * Ignore result of functions tagged with warn_unused_result attributes
282 */
283 #define ignore_result(call) { if(call){}; }
284
285 /**
286 * Assign a function as a class method
287 */
288 #define ASSIGN(method, function) (method = (typeof(method))function)
289
290 /**
291 * time_t not defined
292 */
293 #define UNDEFINED_TIME 0
294
295 /**
296 * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
297 */
298 #define TIME_32_BIT_SIGNED_MAX 0x7fffffff
299
300 /**
301 * define some missing fixed width int types on OpenSolaris.
302 * TODO: since the uintXX_t types are defined by the C99 standard we should
303 * probably use those anyway
304 */
305 #if defined __sun || defined WIN32
306 #include <stdint.h>
307 typedef uint8_t u_int8_t;
308 typedef uint16_t u_int16_t;
309 typedef uint32_t u_int32_t;
310 typedef uint64_t u_int64_t;
311 #endif
312
313 typedef enum status_t status_t;
314
315 /**
316 * Return values of function calls.
317 */
318 enum status_t {
319 /**
320 * Call succeeded.
321 */
322 SUCCESS,
323
324 /**
325 * Call failed.
326 */
327 FAILED,
328
329 /**
330 * Out of resources.
331 */
332 OUT_OF_RES,
333
334 /**
335 * The suggested operation is already done
336 */
337 ALREADY_DONE,
338
339 /**
340 * Not supported.
341 */
342 NOT_SUPPORTED,
343
344 /**
345 * One of the arguments is invalid.
346 */
347 INVALID_ARG,
348
349 /**
350 * Something could not be found.
351 */
352 NOT_FOUND,
353
354 /**
355 * Error while parsing.
356 */
357 PARSE_ERROR,
358
359 /**
360 * Error while verifying.
361 */
362 VERIFY_ERROR,
363
364 /**
365 * Object in invalid state.
366 */
367 INVALID_STATE,
368
369 /**
370 * Destroy object which called method belongs to.
371 */
372 DESTROY_ME,
373
374 /**
375 * Another call to the method is required.
376 */
377 NEED_MORE,
378 };
379
380 /**
381 * enum_names for type status_t.
382 */
383 extern enum_name_t *status_names;
384
385 typedef enum tty_escape_t tty_escape_t;
386
387 /**
388 * Excape codes for tty colors
389 */
390 enum tty_escape_t {
391 /** text properties */
392 TTY_RESET,
393 TTY_BOLD,
394 TTY_UNDERLINE,
395 TTY_BLINKING,
396
397 /** foreground colors */
398 TTY_FG_BLACK,
399 TTY_FG_RED,
400 TTY_FG_GREEN,
401 TTY_FG_YELLOW,
402 TTY_FG_BLUE,
403 TTY_FG_MAGENTA,
404 TTY_FG_CYAN,
405 TTY_FG_WHITE,
406 TTY_FG_DEF,
407
408 /** background colors */
409 TTY_BG_BLACK,
410 TTY_BG_RED,
411 TTY_BG_GREEN,
412 TTY_BG_YELLOW,
413 TTY_BG_BLUE,
414 TTY_BG_MAGENTA,
415 TTY_BG_CYAN,
416 TTY_BG_WHITE,
417 TTY_BG_DEF,
418 };
419
420 /**
421 * Get the escape string for a given TTY color, empty string on non-tty fd
422 */
423 char* tty_escape_get(int fd, tty_escape_t escape);
424
425 /**
426 * deprecated pluto style return value:
427 * error message, NULL for success
428 */
429 typedef const char *err_t;
430
431 /**
432 * Handle struct timeval like an own type.
433 */
434 typedef struct timeval timeval_t;
435
436 /**
437 * Handle struct timespec like an own type.
438 */
439 typedef struct timespec timespec_t;
440
441 /**
442 * Handle struct chunk_t like an own type.
443 */
444 typedef struct sockaddr sockaddr_t;
445
446 /**
447 * Same as memcpy, but XORs src into dst instead of copy
448 */
449 void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
450
451 /**
452 * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
453 */
454 void memwipe_noinline(void *ptr, size_t n);
455
456 /**
457 * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
458 */
459 static inline void memwipe_inline(void *ptr, size_t n)
460 {
461 volatile char *c = (volatile char*)ptr;
462 size_t m, i;
463
464 /* byte wise until long aligned */
465 for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
466 {
467 c[i] = 0;
468 }
469 /* word wise */
470 if (n >= sizeof(long))
471 {
472 for (m = n - sizeof(long); i <= m; i += sizeof(long))
473 {
474 *(volatile long*)&c[i] = 0;
475 }
476 }
477 /* byte wise of the rest */
478 for (; i < n; i++)
479 {
480 c[i] = 0;
481 }
482 }
483
484 /**
485 * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
486 */
487 static inline void memwipe(void *ptr, size_t n)
488 {
489 if (!ptr)
490 {
491 return;
492 }
493 if (__builtin_constant_p(n))
494 {
495 memwipe_inline(ptr, n);
496 }
497 else
498 {
499 memwipe_noinline(ptr, n);
500 }
501 }
502
503 /**
504 * A variant of strstr with the characteristics of memchr, where haystack is not
505 * a null-terminated string but simply a memory area of length n.
506 */
507 void *memstr(const void *haystack, const char *needle, size_t n);
508
509 /**
510 * Replacement for memrchr(3) if it is not provided by the C library.
511 *
512 * @param s start of the memory area to search
513 * @param c character to search
514 * @param n length of memory area to search
515 * @return pointer to the found character or NULL
516 */
517 void *utils_memrchr(const void *s, int c, size_t n);
518
519 #ifndef HAVE_MEMRCHR
520 #define memrchr(s,c,n) utils_memrchr(s,c,n)
521 #endif
522
523 /**
524 * Translates the characters in the given string, searching for characters
525 * in 'from' and mapping them to characters in 'to'.
526 * The two characters sets 'from' and 'to' must contain the same number of
527 * characters.
528 */
529 char *translate(char *str, const char *from, const char *to);
530
531 /**
532 * Replaces all occurrences of search in the given string with replace.
533 *
534 * Allocates memory only if anything is replaced in the string. The original
535 * string is also returned if any of the arguments are invalid (e.g. if search
536 * is empty or any of them are NULL).
537 *
538 * @param str original string
539 * @param search string to search for and replace
540 * @param replace string to replace found occurrences with
541 * @return allocated string, if anything got replaced, str otherwise
542 */
543 char *strreplace(const char *str, const char *search, const char *replace);
544
545 /**
546 * Portable function to wait for SIGINT/SIGTERM (or equivalent).
547 */
548 void wait_sigint();
549
550 /**
551 * Like dirname(3) returns the directory part of the given null-terminated
552 * pathname, up to but not including the final '/' (or '.' if no '/' is found).
553 * Trailing '/' are not counted as part of the pathname.
554 *
555 * The difference is that it does this in a thread-safe manner (i.e. it does not
556 * use static buffers) and does not modify the original path.
557 *
558 * @param path original pathname
559 * @return allocated directory component
560 */
561 char *path_dirname(const char *path);
562
563 /**
564 * Like basename(3) returns the filename part of the given null-terminated path,
565 * i.e. the part following the final '/' (or '.' if path is empty or NULL).
566 * Trailing '/' are not counted as part of the pathname.
567 *
568 * The difference is that it does this in a thread-safe manner (i.e. it does not
569 * use static buffers) and does not modify the original path.
570 *
571 * @param path original pathname
572 * @return allocated filename component
573 */
574 char *path_basename(const char *path);
575
576 /**
577 * Check if a given path is absolute.
578 *
579 * @param path path to check
580 * @return TRUE if absolute, FALSE if relative
581 */
582 bool path_absolute(const char *path);
583
584 /**
585 * Creates a directory and all required parent directories.
586 *
587 * @param path path to the new directory
588 * @param mode permissions of the new directory/directories
589 * @return TRUE on success
590 */
591 bool mkdir_p(const char *path, mode_t mode);
592
593 #ifndef HAVE_CLOSEFROM
594 /**
595 * Close open file descriptors greater than or equal to lowfd.
596 *
597 * @param lowfd start closing file descriptors from here
598 */
599 void closefrom(int lowfd);
600 #endif
601
602 /**
603 * Get a timestamp from a monotonic time source.
604 *
605 * While the time()/gettimeofday() functions are affected by leap seconds
606 * and system time changes, this function returns ever increasing monotonic
607 * time stamps.
608 *
609 * @param tv timeval struct receiving monotonic timestamps, or NULL
610 * @return monotonic timestamp in seconds
611 */
612 time_t time_monotonic(timeval_t *tv);
613
614 /**
615 * Add the given number of milliseconds to the given timeval struct
616 *
617 * @param tv timeval struct to modify
618 * @param ms number of milliseconds
619 */
620 static inline void timeval_add_ms(timeval_t *tv, u_int ms)
621 {
622 tv->tv_usec += ms * 1000;
623 while (tv->tv_usec >= 1000000 /* 1s */)
624 {
625 tv->tv_usec -= 1000000;
626 tv->tv_sec++;
627 }
628 }
629
630 /**
631 * returns null
632 */
633 void *return_null();
634
635 /**
636 * No-Operation function
637 */
638 void nop();
639
640 /**
641 * returns TRUE
642 */
643 bool return_true();
644
645 /**
646 * returns FALSE
647 */
648 bool return_false();
649
650 /**
651 * returns FAILED
652 */
653 status_t return_failed();
654
655 /**
656 * returns SUCCESS
657 */
658 status_t return_success();
659
660 /**
661 * Write a 16-bit host order value in network order to an unaligned address.
662 *
663 * @param host host order 16-bit value
664 * @param network unaligned address to write network order value to
665 */
666 static inline void htoun16(void *network, u_int16_t host)
667 {
668 char *unaligned = (char*)network;
669
670 host = htons(host);
671 memcpy(unaligned, &host, sizeof(host));
672 }
673
674 /**
675 * Write a 32-bit host order value in network order to an unaligned address.
676 *
677 * @param host host order 32-bit value
678 * @param network unaligned address to write network order value to
679 */
680 static inline void htoun32(void *network, u_int32_t host)
681 {
682 char *unaligned = (char*)network;
683
684 host = htonl(host);
685 memcpy((char*)unaligned, &host, sizeof(host));
686 }
687
688 /**
689 * Write a 64-bit host order value in network order to an unaligned address.
690 *
691 * @param host host order 64-bit value
692 * @param network unaligned address to write network order value to
693 */
694 static inline void htoun64(void *network, u_int64_t host)
695 {
696 char *unaligned = (char*)network;
697
698 #ifdef be64toh
699 host = htobe64(host);
700 memcpy((char*)unaligned, &host, sizeof(host));
701 #else
702 u_int32_t high_part, low_part;
703
704 high_part = host >> 32;
705 high_part = htonl(high_part);
706 low_part = host & 0xFFFFFFFFLL;
707 low_part = htonl(low_part);
708
709 memcpy(unaligned, &high_part, sizeof(high_part));
710 unaligned += sizeof(high_part);
711 memcpy(unaligned, &low_part, sizeof(low_part));
712 #endif
713 }
714
715 /**
716 * Read a 16-bit value in network order from an unaligned address to host order.
717 *
718 * @param network unaligned address to read network order value from
719 * @return host order value
720 */
721 static inline u_int16_t untoh16(void *network)
722 {
723 char *unaligned = (char*)network;
724 u_int16_t tmp;
725
726 memcpy(&tmp, unaligned, sizeof(tmp));
727 return ntohs(tmp);
728 }
729
730 /**
731 * Read a 32-bit value in network order from an unaligned address to host order.
732 *
733 * @param network unaligned address to read network order value from
734 * @return host order value
735 */
736 static inline u_int32_t untoh32(void *network)
737 {
738 char *unaligned = (char*)network;
739 u_int32_t tmp;
740
741 memcpy(&tmp, unaligned, sizeof(tmp));
742 return ntohl(tmp);
743 }
744
745 /**
746 * Read a 64-bit value in network order from an unaligned address to host order.
747 *
748 * @param network unaligned address to read network order value from
749 * @return host order value
750 */
751 static inline u_int64_t untoh64(void *network)
752 {
753 char *unaligned = (char*)network;
754
755 #ifdef be64toh
756 u_int64_t tmp;
757
758 memcpy(&tmp, unaligned, sizeof(tmp));
759 return be64toh(tmp);
760 #else
761 u_int32_t high_part, low_part;
762
763 memcpy(&high_part, unaligned, sizeof(high_part));
764 unaligned += sizeof(high_part);
765 memcpy(&low_part, unaligned, sizeof(low_part));
766
767 high_part = ntohl(high_part);
768 low_part = ntohl(low_part);
769
770 return (((u_int64_t)high_part) << 32) + low_part;
771 #endif
772 }
773
774 /**
775 * Get the padding required to make size a multiple of alignment
776 */
777 static inline size_t pad_len(size_t size, size_t alignment)
778 {
779 size_t remainder;
780
781 remainder = size % alignment;
782 return remainder ? alignment - remainder : 0;
783 }
784
785 /**
786 * Round up size to be multiple of alignment
787 */
788 static inline size_t round_up(size_t size, size_t alignment)
789 {
790 return size + pad_len(size, alignment);
791 }
792
793 /**
794 * Round down size to be a multiple of alignment
795 */
796 static inline size_t round_down(size_t size, size_t alignment)
797 {
798 return size - (size % alignment);
799 }
800
801 /**
802 * Special type to count references
803 */
804 typedef u_int refcount_t;
805
806 /* use __atomic* built-ins with GCC 4.7 and newer */
807 #ifdef __GNUC__
808 # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
809 # define HAVE_GCC_ATOMIC_OPERATIONS
810 # endif
811 #endif
812
813 #ifdef HAVE_GCC_ATOMIC_OPERATIONS
814
815 #define ref_get(ref) __atomic_add_fetch(ref, 1, __ATOMIC_RELAXED)
816 /* The relaxed memory model works fine for increments as these (usually) don't
817 * change the state of refcounted objects. But here we have to ensure that we
818 * free the right stuff if ref counted objects are mutable. So we have to sync
819 * with other threads that call ref_put(). It would be sufficient to use
820 * __ATOMIC_RELEASE here and then call __atomic_thread_fence() with
821 * __ATOMIC_ACQUIRE if we reach 0, but since we don't have control over the use
822 * of ref_put() we have to make sure. */
823 #define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL))
824 #define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED)
825
826 #define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \
827 __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \
828 __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); })
829 #define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
830 #define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
831
832 #elif defined(HAVE_GCC_SYNC_OPERATIONS)
833
834 #define ref_get(ref) __sync_add_and_fetch(ref, 1)
835 #define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
836 #define ref_cur(ref) __sync_fetch_and_add(ref, 0)
837
838 #define cas_bool(ptr, oldval, newval) \
839 (__sync_bool_compare_and_swap(ptr, oldval, newval))
840 #define cas_ptr(ptr, oldval, newval) \
841 (__sync_bool_compare_and_swap(ptr, oldval, newval))
842
843 #else /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
844
845 /**
846 * Get a new reference.
847 *
848 * Increments the reference counter atomically.
849 *
850 * @param ref pointer to ref counter
851 * @return new value of ref
852 */
853 refcount_t ref_get(refcount_t *ref);
854
855 /**
856 * Put back a unused reference.
857 *
858 * Decrements the reference counter atomically and
859 * says if more references available.
860 *
861 * @param ref pointer to ref counter
862 * @return TRUE if no more references counted
863 */
864 bool ref_put(refcount_t *ref);
865
866 /**
867 * Get the current value of the reference counter.
868 *
869 * @param ref pointer to ref counter
870 * @return current value of ref
871 */
872 refcount_t ref_cur(refcount_t *ref);
873
874 /**
875 * Atomically replace value of ptr with newval if it currently equals oldval.
876 *
877 * @param ptr pointer to variable
878 * @param oldval old value of the variable
879 * @param newval new value set if possible
880 * @return TRUE if value equaled oldval and newval was written
881 */
882 bool cas_bool(bool *ptr, bool oldval, bool newval);
883
884 /**
885 * Atomically replace value of ptr with newval if it currently equals oldval.
886 *
887 * @param ptr pointer to variable
888 * @param oldval old value of the variable
889 * @param newval new value set if possible
890 * @return TRUE if value equaled oldval and newval was written
891 */
892 bool cas_ptr(void **ptr, void *oldval, void *newval);
893
894 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
895
896 #ifndef HAVE_FMEMOPEN
897 # ifdef HAVE_FUNOPEN
898 # define HAVE_FMEMOPEN
899 # define HAVE_FMEMOPEN_FALLBACK
900 # include <stdio.h>
901 /**
902 * fmemopen(3) fallback using BSD funopen.
903 *
904 * We could also provide one using fopencookie(), but should we have it we
905 * most likely have fmemopen().
906 *
907 * fseek() is currently not supported.
908 */
909 FILE *fmemopen(void *buf, size_t size, const char *mode);
910 # endif /* FUNOPEN */
911 #endif /* FMEMOPEN */
912
913 /**
914 * printf hook for time_t.
915 *
916 * Arguments are:
917 * time_t* time, bool utc
918 */
919 int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
920 const void *const *args);
921
922 /**
923 * printf hook for time_t deltas.
924 *
925 * Arguments are:
926 * time_t* begin, time_t* end
927 */
928 int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
929 const void *const *args);
930
931 /**
932 * printf hook for memory areas.
933 *
934 * Arguments are:
935 * u_char *ptr, u_int len
936 */
937 int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
938 const void *const *args);
939
940 #endif /** UTILS_H_ @}*/