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