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