Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_common.h
Go to the documentation of this file.
1
9#ifndef __NILOREA_COMMONS__
10#define __NILOREA_COMMONS__
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
21#include <sys/types.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <malloc.h>
25#include <errno.h>
26#include <string.h>
27#include <strings.h>
28#include <stdint.h>
29#include <nilorea/n_log.h>
30#include <nilorea/n_enum.h>
31
33#if defined(_WIN32) || defined(_WIN64)
34#ifndef __windows__
35#define __windows__
36#endif
37#ifndef WEXITSTATUS
38#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
39#endif
40#ifndef WIFEXITED
41#define WIFEXITED(w) (((w) & 0xff) == 0)
42#endif
43#else
44#include <alloca.h>
45#include <signal.h>
46#endif
47
48#if defined(__GNUC__) && __GNUC__ >= 7
50#define FALL_THROUGH __attribute__((fallthrough))
51#else
53#define FALL_THROUGH /* fall through */ \
54 ((void)0)
55#endif /* __GNUC__ >= 7 */
56
57#if defined(_WIN32) || defined(_WIN64)
58#if defined(_WIN64)
60#define ENV_64BITS
61#else
63#define ENV_32BITS
64#endif
65#endif
66
67#if !defined(ENV_32BITS) || !defined(ENV_64BITS)
68#if defined(__GNUC__)
69#if defined(__x86_64__) || defined(__ppc64__)
71#define __ENVBITS __ENV_64BITS
72#else
74#define __ENVBITS __ENV_32BITS
75#endif
76#endif
77#endif
78
80#define BYTEORDER_LITTLE_ENDIAN 0 // Little endian machine.
82#define BYTEORDER_BIG_ENDIAN 1 // Big endian machine.
83
84#ifndef BYTEORDER_ENDIAN
85// Detect with GCC 4.6's macro.
86#if defined(__BYTE_ORDER__)
87#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
88#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
89#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
90#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
91#else
92#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
93#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
94#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
95#endif
96// Detect with GLIBC's endian.h.
97#elif defined(__GLIBC__)
98#include <endian.h>
99#if (__BYTE_ORDER == __LITTLE_ENDIAN)
100#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
101#elif (__BYTE_ORDER == __BIG_ENDIAN)
102#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
103#else
104#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
105#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
106#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
107#endif
108// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro.
109#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
110#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
111#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
112#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
113// Detect with architecture macros.
114#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
115#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
116#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
117#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
118#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
119#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
120#else
121#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
122#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
123#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
124#endif
125#endif
126
127#if defined(__windows__)
128/* typedefine for unsigned category for basic native types */
130typedef unsigned int uint;
132typedef unsigned long ulong;
134typedef unsigned short ushort;
136typedef unsigned char uchar;
137#endif
138
140#ifdef _MSVC_VER
141#define FORCE_INLINE __forceinline
142#elif defined(__linux__) || defined(__windows__)
143#define FORCE_INLINE static inline __attribute__((always_inline))
144#else
145#define FORCE_INLINE static inline __attribute__((always_inline))
146#endif
147
149#ifndef true
150#define true (1 == 1)
151#endif
152
154#ifndef TRUE
155#define TRUE true
156#endif
157
159#ifndef false
160#define false (1 == 0)
161#endif
162
164#ifndef FALSE
165#define FALSE false
166#endif
167
169#ifndef EMPTY
170#define EMPTY 2
171#endif
172
174#define _str(__PTR) ((__PTR) ? (__PTR) : "NULL")
176#define _strp(__PTR) ((__PTR) ? (__PTR) : NULL)
178#define _strw(__PTR) ((__PTR) ? (__PTR) : " ")
180#define _nstr(__PTR) ((__PTR && __PTR->data) ? (__PTR->data) : "NULL")
182#define _nstrp(__PTR) ((__PTR && __PTR->data) ? (__PTR->data) : NULL)
183
185#define Malloc(__ptr, __struct, __size) \
186 { \
187 int __n_errno = 0; \
188 errno = 0; \
189 __ptr = (__struct*)calloc(__size, sizeof(__struct)); \
190 __n_errno = errno; \
191 if (!__ptr) { \
192 n_log(LOG_ERR, "( %s *)calloc( %ld , sizeof( %s ) ) %s at line %d of %s", #__ptr, __size, #__struct, (__n_errno == 0) ? "malloc error" : strerror(__n_errno), __LINE__, __FILE__); \
193 } \
194 }
195
197#define Alloca(__ptr, __size) \
198 { \
199 int __n_errno = 0; \
200 errno = 0; \
201 __ptr = alloca(__size); \
202 __n_errno = errno; \
203 if (!__ptr) { \
204 n_log(LOG_ERR, "%s=alloca( %d ) %s at line %d of %s", #__ptr, __size, (__n_errno == 0) ? "alloca error" : strerror(__n_errno), __LINE__, __FILE__); \
205 } else { \
206 memset(__ptr, 0, __size); \
207 } \
208 }
209
211#define Realloc(__ptr, __struct, __size) \
212 { \
213 int __n_errno = 0; \
214 errno = 0; \
215 void* __new_ptr = (__struct*)realloc(__ptr, __size * sizeof(__struct)); \
216 __n_errno = errno; \
217 if (!__new_ptr) { \
218 n_log(LOG_ERR, "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s", #__ptr, #__struct, __size, (__n_errno == 0) ? "realloc error" : strerror(__n_errno), __LINE__, __FILE__); \
219 } else { \
220 __ptr = __new_ptr; \
221 } \
222 }
223
225#define Reallocz(__ptr, __struct, __old_size, __size) \
226 { \
227 int __n_errno = 0; \
228 errno = 0; \
229 void* __new_ptr = (__struct*)realloc(__ptr, __size); \
230 __n_errno = errno; \
231 if (!__new_ptr) { \
232 n_log(LOG_ERR, "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s", #__ptr, #__struct, __size, (__n_errno == 0) ? "realloc error" : strerror(__n_errno), __LINE__, __FILE__); \
233 } else { \
234 __ptr = __new_ptr; \
235 if (__size > __old_size) memset((__ptr + __old_size), 0, __size - __old_size); \
236 } \
237 }
238
240#define Free(__ptr) \
241 if (__ptr) { \
242 free(__ptr); \
243 __ptr = NULL; \
244 } else { \
245 n_log(LOG_DEBUG, "Free( %s ) already done or NULL at line %d of %s", #__ptr, __LINE__, __FILE__); \
246 }
247
249#define FreeNoLog(__ptr) \
250 if (__ptr) { \
251 free(__ptr); \
252 __ptr = NULL; \
253 }
254
256#define __n_assert(__ptr, __ret) \
257 if (!(__ptr)) { \
258 n_log(LOG_DEBUG, "if( !(%s) ) assert at line %d of %s", #__ptr, __LINE__, __FILE__); \
259 __ret; \
260 }
261
263#define CALL_RETRY(__retvar, __expression, __max_tries, __delay) ({ \
264 int __nb_retries = 0; \
265 do { \
266 __retvar = (__expression); \
267 __nb_retries++; \
268 if (__retvar == -1 && errno == EINTR && __nb_retries < __max_tries) \
269 usleep(__delay); \
270 } while (__retvar == -1 && errno == EINTR && __nb_retries < __max_tries); \
271 __nb_retries; \
272})
273
275#define next_odd(__val) ((__val) % 2 == 0) ? (__val) : (__val + 1)
276
278#define next_even(__val) ((__val) % 2 == 0) ? (__val + 1) : (__val)
279
281#define init_error_check() \
282 static int ___error__check_flag = FALSE;
283
285#define ifnull if( !
286
288#define ifzero if( 0 ==
289
291#define iffalse if( FALSE ==
292
294#define iftrue if( TRUE ==
295
297#define checkerror() \
298 if (___error__check_flag == TRUE) { \
299 n_log(LOG_ERR, "checkerror return false at line %d of %s", __LINE__, __FILE__); \
300 goto error; \
301 }
302
304#define endif ){ \
305 ___error__check_flag = TRUE; \
306 n_log(LOG_ERR, "First err was at line %d of %s", __LINE__, __FILE__); \
307 }
308
310#define get_error() \
311 (___error__check_flag == TRUE)
312
314#define equal_if(__a, __cond, __b) \
315 if ((__a)__cond(__b)) { \
316 __a = __b; \
317 }
318
319// #define RWLOCK_DEBUG 1
320#ifdef RWLOCK_DEBUG
322#define RWLOCK_LOGLEVEL LOG_DEBUG
323#else
325#define RWLOCK_LOGLEVEL LOG_NULL
326#endif
327
329#define init_lock(__rwlock_mutex) \
330 ({ \
331 pthread_rwlockattr_t __attr; \
332 pthread_rwlockattr_init(&__attr); \
333 int __ret = 0; \
334 do { \
335 n_log(RWLOCK_LOGLEVEL, "init_lock %s", #__rwlock_mutex); \
336 __rwlock_mutex = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER; \
337 __ret = pthread_rwlock_init(&(__rwlock_mutex), &__attr); \
338 if (__ret != 0) { \
339 n_log(LOG_ERR, "Error %s while initializing %s at %s:%s:%d", strerror(__ret), #__rwlock_mutex, __FILE__, __func__, __LINE__); \
340 } \
341 pthread_rwlockattr_destroy(&__attr); \
342 } while (0); \
343 __ret; \
344 })
345
347#define read_lock(__rwlock_mutex) \
348 ({ \
349 int __ret = 0; \
350 do { \
351 n_log(RWLOCK_LOGLEVEL, "read lock %s", #__rwlock_mutex); \
352 __ret = pthread_rwlock_rdlock(&(__rwlock_mutex)); \
353 if (__ret != 0) { \
354 n_log(LOG_ERR, "Error %s while read locking %s at %s:%s:%d", strerror(__ret), #__rwlock_mutex, __FILE__, __func__, __LINE__); \
355 } \
356 } while (0); \
357 __ret; \
358 })
359
361#define write_lock(__rwlock_mutex) \
362 ({ \
363 int __ret = 0; \
364 do { \
365 n_log(RWLOCK_LOGLEVEL, "write lock %s", #__rwlock_mutex); \
366 __ret = pthread_rwlock_wrlock(&(__rwlock_mutex)); \
367 if (__ret != 0) { \
368 n_log(LOG_ERR, "Error %s while write locking %s at %s:%s:%d", strerror(__ret), #__rwlock_mutex, __FILE__, __func__, __LINE__); \
369 } \
370 } while (0); \
371 __ret; \
372 })
373
375#define unlock(__rwlock_mutex) \
376 ({ \
377 int __ret = 0; \
378 do { \
379 n_log(RWLOCK_LOGLEVEL, "unlock lock %s", #__rwlock_mutex); \
380 __ret = pthread_rwlock_unlock(&(__rwlock_mutex)); \
381 if (__ret != 0) { \
382 n_log(LOG_ERR, "Error %s while unlocking %s at %s:%s:%d", strerror(__ret), #__rwlock_mutex, __FILE__, __func__, __LINE__); \
383 } \
384 } while (0); \
385 __ret; \
386 })
388#define rw_lock_destroy(__rwlock_mutex) \
389 ({ \
390 int __ret = 0; \
391 do { \
392 n_log(RWLOCK_LOGLEVEL, "destroy lock %s", #__rwlock_mutex); \
393 __ret = pthread_rwlock_destroy(&(__rwlock_mutex)); \
394 if (__ret != 0) { \
395 n_log(LOG_ERR, "Error %s while destroying %s at %s:%s:%d", strerror(__ret), #__rwlock_mutex, __FILE__, __func__, __LINE__); \
396 } \
397 } while (0); \
398 __ret; \
399 })
400
402#define SET 1234
404#define GET 4321
406#define DEFAULT 1000
408#define RUNNING 1001
410#define STOPWANTED 1002
412#define STOPPED 1003
414#define PAUSED 1004
415
417#define randomize() \
418 { \
419 srand((unsigned)time(NULL)); \
420 rand(); \
421 }
422
423#ifndef MIN
425#define MIN(a, b) (((a) < (b)) ? (a) : (b))
426#endif
427#ifndef MAX
429#define MAX(a, b) (((a) > (b)) ? (a) : (b))
430#endif
431
433#define CONCAT_BUILDER(a, b) a##b
435#define CONCAT(a, b) CONCAT_BUILDER(a, b)
436
437#if (BYTEORDER_ENDIAN == BYTEORDER_BIG_ENDIAN)
439#ifndef htonll
440#define htonll(x) (x)
441#endif
443#ifndef ntohll
444#define ntohll(x) (x)
445#endif
446#else
448#ifndef htonll
449#define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
450#endif
452#ifndef ntohll
453#define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
454#endif
455#endif
456
457/* exit and print log to stderr */
458void n_abort(char const* format, ...);
459
460int get_computer_name(char* computer_name, size_t len);
461
462/* get running program name */
463char* get_prog_name(void);
464
465/* get running program directory */
466char* get_prog_dir(void);
467
468/* test file presence*/
469int file_exist(const char* filename);
470
471/* shortcut for popen usage */
472int n_popen(char* cmd, size_t read_buf_size, void** nstr_output, int* ret);
473
474/* log environnement */
475void log_environment(int loglevel);
476
477#ifndef __windows__
478/* reap zombie processes */
479void sigchld_handler(int sig);
480/* install signal SIGCHLD handler */
483#define N_DAEMON_NO_CLOSE 2
485#define N_DAEMON_NO_STD_REDIRECT 4
487#define N_DAEMON_NO_DOUBLE_FORK 8
489#define N_DAEMON_NO_SETSID 16
491#define N_DAEMON_NO_UMASK 32
493#define N_DAEMON_NO_CHDIR 64
495#define N_DAEMON_NO_SIGCHLD_IGN 128
497#define N_DAEMON_NO_SIGCHLD_HANDLER 256
498/* daemonize */
499int n_daemonize(void);
500/* daemonize */
501int n_daemonize_ex(int mode);
502/* non blocking system call */
503pid_t system_nb(const char* command, int* infp, int* outfp);
504#endif
505
506/* reconstruct hidden string */
507void N_HIDE_STR(char* buf, ...);
508
509char* n_get_file_extension(char path[]);
514#ifdef __cplusplus
515}
516#endif
517
518#endif // header guard
int mode
Network for managing conenctions.
Definition ex_network.c:22
void log_environment(int loglevel)
log environment variables in syslog
Definition n_common.c:244
char * get_prog_name(void)
get current program name
Definition n_common.c:128
void N_HIDE_STR(char *buf,...)
store a hidden version of a string
Definition n_common.c:430
int get_computer_name(char *computer_name, size_t len)
abort program with a text
Definition n_common.c:56
void sigchld_handler(int sig)
Handles SIGCHLD issues when forking.
Definition n_common.c:213
pid_t system_nb(const char *command, int *infp, int *outfp)
Non blocking system call.
Definition n_common.c:362
char * n_get_file_extension(char path[])
get extension of path+filename
Definition n_common.c:451
char * get_prog_dir(void)
get current program running directory
Definition n_common.c:96
int n_daemonize_ex(int mode)
Daemonize program.
Definition n_common.c:264
void n_abort(char const *format,...)
htonl for 64 bits numbers
Definition n_common.c:39
int sigchld_handler_installer()
install signal SIGCHLD handler to reap zombie processes
Definition n_common.c:227
int n_daemonize(void)
Daemonize program.
Definition n_common.c:255
int file_exist(const char *filename)
test if file exist and if it's readable
Definition n_common.c:83
int n_popen(char *cmd, size_t read_buf_size, void **nstr_output, int *ret)
launch a command abd return output and status
Definition n_common.c:163
Macro to build enums and their tostring counterparts, a reduced version of https://github....
Generic log system.