Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_common.h
Go to the documentation of this file.
1
8#ifndef __NILOREA_COMMONS__
9#define __NILOREA_COMMONS__
10
11#ifdef __cplusplus
12extern "C"
13{
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
49#define __EXTENSIONS__
50
51#if defined(__GNUC__) && __GNUC__ >= 7
53#define FALL_THROUGH __attribute__ ((fallthrough))
54#else
56#define FALL_THROUGH /* fall through */ \
57 ((void)0)
58#endif /* __GNUC__ >= 7 */
59
60#if defined( _WIN32 ) || defined( _WIN64 )
61#if defined( _WIN64 )
63#define ENV_64BITS
64#else
66#define ENV_32BITS
67#endif
68#endif
69
70#if !defined( ENV_32BITS ) || !defined( ENV_64BITS )
71#if defined( __GNUC__ )
72#if defined( __x86_64__ ) || defined( __ppc64__ )
74#define __ENVBITS __ENV_64BITS
75#else
77#define __ENVBITS __ENV_32BITS
78#endif
79#endif
80#endif
81
83#define BYTEORDER_LITTLE_ENDIAN 0 // Little endian machine.
85#define BYTEORDER_BIG_ENDIAN 1 // Big endian machine.
86
87
88#ifndef BYTEORDER_ENDIAN
89 // Detect with GCC 4.6's macro.
90#if defined(__BYTE_ORDER__)
91#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
92#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
93#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
94#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
95#else
96#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
97#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
98#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
99#endif
100 // Detect with GLIBC's endian.h.
101#elif defined(__GLIBC__)
102#include <endian.h>
103#if (__BYTE_ORDER == __LITTLE_ENDIAN)
104#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
105#elif (__BYTE_ORDER == __BIG_ENDIAN)
106#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
107#else
108#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
109#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
110#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
111#endif
112 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro.
113#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
114#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
115#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
116#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
117 // Detect with architecture macros.
118#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
119#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
120#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__)
121#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
122#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
123#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
124#else
125#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
126#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
127#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
128#endif
129#endif
130
131#if defined( __windows__ )
132 /* typedefine for unsigned category for basic native types */
134 typedef unsigned int uint;
136 typedef unsigned long ulong;
138 typedef unsigned short ushort;
140 typedef unsigned char uchar;
141#endif
142
144#ifdef _MSVC_VER
145#define FORCE_INLINE __forceinline
146#elif defined( __linux__ ) || defined( __windows__ )
147#define FORCE_INLINE static inline __attribute__((always_inline))
148#else
149#define FORCE_INLINE static inline __attribute__((always_inline))
150#endif
151
153#ifndef true
154#define true (1==1)
155#endif
156
158#ifndef TRUE
159#define TRUE true
160#endif
161
163#ifndef false
164#define false (1==0)
165#endif
166
168#ifndef FALSE
169#define FALSE false
170#endif
171
173#ifndef EMPTY
174#define EMPTY 2
175#endif
176
177
178
180#define _str( __PTR ) ((__PTR)?(__PTR):"NULL")
182#define _strp( __PTR ) ((__PTR)?(__PTR):NULL)
184#define _strw( __PTR ) ((__PTR)?(__PTR):" ")
186#define _nstr( __PTR ) ((__PTR&&__PTR->data)?(__PTR->data):"NULL")
188#define _nstrp( __PTR ) ((__PTR&&__PTR->data)?(__PTR->data):NULL)
189
191#define Malloc( __ptr , __struct , __size ) \
192 { \
193 int __n_errno = 0 ; \
194 int64_t __byte_size = __size ; \
195 if( __byte_size <= 0 ) __byte_size = 16; \
196 errno= 0 ;\
197 __ptr = ( __struct *)calloc( __byte_size , sizeof( __struct ) ); \
198 __n_errno = errno ;\
199 if( ! __ptr ) \
200 { \
201 n_log( LOG_ERR , "( %s *)calloc( %ld , sizeof( %s ) ) %s at line %d of %s \n", #__ptr , __size , #__struct , (__n_errno==0)?"malloc error":strerror( __n_errno ) , __LINE__ , __FILE__); \
202 } \
203 }
204
206#define Alloca( __ptr , __size ) \
207 { \
208 int __n_errno = 0 ; \
209 int64_t __byte_size = __size ; \
210 if( __byte_size <= 0 ) __byte_size = 16 ; \
211 errno= 0 ;\
212 __ptr = alloca( __byte_size ); \
213 __n_errno = errno ;\
214 if( ! __ptr ) \
215 { \
216 n_log( LOG_ERR , "%s=alloca( %d ) %s at line %d of %s \n", #__ptr , __size , (__n_errno==0)?"alloca error":strerror( __n_errno ) , __LINE__ , __FILE__); \
217 } \
218 else \
219 { \
220 memset( __ptr , 0 , __byte_size ); \
221 } \
222 }
223
225#define Realloc( __ptr, __struct , __size ) \
226 { \
227 int __n_errno = 0 ; \
228 int64_t __byte_size = __size * sizeof( __struct ); \
229 if( __byte_size <= 0 ) __byte_size = 16 ; \
230 errno= 0 ;\
231 void *__new_ptr = ( __struct *)realloc( __ptr , __byte_size ); \
232 __n_errno = errno ; \
233 if( !__new_ptr ) \
234 { \
235 n_log( LOG_ERR , "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s \n", #__ptr , #__struct , __size , (__n_errno==0)?"realloc error":strerror( __n_errno ) , __LINE__ , __FILE__);\
236 } \
237 else \
238 { \
239 __ptr = __new_ptr ; \
240 } \
241 }
242
244#define Reallocz( __ptr, __struct , __old_size , __size ) \
245 { \
246 int __n_errno = 0 ; \
247 size_t __byte_size = __size * sizeof( __struct ); \
248 if( __byte_size <= 0 ) __byte_size = 16 ; \
249 errno= 0 ;\
250 void *__new_ptr = ( __struct *)realloc( __ptr , __byte_size ); \
251 __n_errno = errno ; \
252 if( !__new_ptr ) \
253 { \
254 n_log( LOG_ERR , "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s \n", #__ptr , #__struct , __size , (__n_errno==0)?"realloc error":strerror( __n_errno ) , __LINE__ , __FILE__);\
255 } \
256 else \
257 { \
258 __ptr = __new_ptr ; \
259 if( __byte_size > __old_size ) memset( ( __ptr + __old_size ) , 0 , __byte_size - __old_size ); \
260 } \
261 }
262
264#define Free( __ptr ) \
265 if ( __ptr )\
266 {\
267 free( __ptr );\
268 __ptr = NULL;\
269 }\
270 else\
271 {\
272 n_log( LOG_DEBUG , "Free( %s ) already done or NULL at line %d of %s \n", #__ptr , __LINE__ , __FILE__ );\
273 }
274
276#define FreeNoLog( __ptr )\
277 if ( __ptr )\
278 {\
279 free( __ptr );\
280 __ptr = NULL;\
281 }
282
284#define __n_assert( __ptr , __ret ) \
285 if( !(__ptr) ) \
286 { \
287 n_log( LOG_DEBUG , "if( !(%s) ) assert at line %d of %s" , #__ptr , __LINE__ , __FILE__ ); \
288 __ret ; \
289 }
290
292#define CALL_RETRY(retvar, expression) do { \
293 retvar = (expression); \
294} while (retvar == -1 && errno == EINTR);
295
297#define next_odd( __val ) ( (__val)%2 == 0 ) ? (__val) : ( __val + 1 )
298
300#define next_even( __val ) ( (__val)%2 == 0 ) ? (__val + 1) : ( __val )
301
302
304#define init_error_check() \
305 static int ___error__check_flag = FALSE ;
306
308#define ifnull if( !
309
311#define ifzero if( 0 ==
312
314#define iffalse if( FALSE ==
315
317#define iftrue if( TRUE ==
318
320#define checkerror() if( ___error__check_flag == TRUE ) \
321{ n_log( LOG_ERR , "checkerror return false at line %d of %s" , __LINE__ , __FILE__ ); \
322goto error ; \
323}
324
326#define endif ){ ___error__check_flag = TRUE ; n_log( LOG_ERR , "First err was at line %d of %s" , __LINE__ , __FILE__ );}
327
329#define get_error() \
330(___error__check_flag == TRUE)
331
333#define equal_if( __a , __cond , __b ) if( (__a) __cond (__b) ){ __a = __b ; }
334
335 //#define RWLOCK_DEBUG 1
336#ifdef RWLOCK_DEBUG
338#define RWLOCK_LOGLEVEL LOG_DEBUG
339#else
341#define RWLOCK_LOGLEVEL LOG_NULL
342#endif
343
345#define init_lock( __rwlock_mutex ) \
346 ({ \
347 pthread_rwlockattr_t __attr ; \
348 pthread_rwlockattr_init( &__attr ); \
349 int __ret = 0 ; \
350 do \
351 { \
352 n_log( RWLOCK_LOGLEVEL , "init_lock %s" , #__rwlock_mutex ); \
353 __rwlock_mutex = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER ; \
354 __ret = pthread_rwlock_init( &(__rwlock_mutex) , &__attr ); \
355 if( __ret != 0 ) \
356 { \
357 n_log( LOG_ERR , "Error %s while initializing %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
358 } \
359 pthread_rwlockattr_destroy( &__attr ); \
360 } while( 0 ); \
361 __ret ; \
362 })
363
365#define read_lock( __rwlock_mutex ) \
366 ({ \
367 int __ret = 0 ; \
368 do \
369 { \
370 n_log( RWLOCK_LOGLEVEL , "read lock %s" , #__rwlock_mutex ); \
371 __ret = pthread_rwlock_rdlock( &(__rwlock_mutex) ); \
372 if( __ret != 0 ) \
373 { \
374 n_log( LOG_ERR , "Error %s while read locking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
375 } \
376 } while( 0 ); \
377 __ret ; \
378 })
379
381#define write_lock( __rwlock_mutex ) \
382 ({ \
383 int __ret = 0 ; \
384 do \
385 { \
386 n_log( RWLOCK_LOGLEVEL , "write lock %s" , #__rwlock_mutex ); \
387 __ret = pthread_rwlock_wrlock( &(__rwlock_mutex) ); \
388 if( __ret != 0 ) \
389 { \
390 n_log( LOG_ERR , "Error %s while write locking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
391 } \
392 } while( 0 ); \
393 __ret ; \
394 })
395
397#define unlock( __rwlock_mutex ) \
398 ({ \
399 int __ret = 0 ; \
400 do \
401 { \
402 n_log( RWLOCK_LOGLEVEL , "unlock lock %s" , #__rwlock_mutex ); \
403 __ret = pthread_rwlock_unlock( &(__rwlock_mutex) ); \
404 if( __ret != 0 ) \
405 { \
406 n_log( LOG_ERR , "Error %s while unlocking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
407 } \
408 } while( 0 ); \
409 __ret ; \
410 })
412#define rw_lock_destroy( __rwlock_mutex ) \
413 ({ \
414 int __ret = 0 ; \
415 do \
416 { \
417 n_log( RWLOCK_LOGLEVEL , "destroy lock %s" , #__rwlock_mutex ); \
418 __ret = pthread_rwlock_destroy( &(__rwlock_mutex) ); \
419 if( __ret != 0 ) \
420 { \
421 n_log( LOG_ERR , "Error %s while destroying %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
422 } \
423 } while( 0 ); \
424 __ret ; \
425 })
426
428#define SET 1234
430#define GET 4321
432#define DEFAULT 1000
434#define RUNNING 1001
436#define STOPWANTED 1002
438#define STOPPED 1003
440#define PAUSED 1004
441
443#define randomize() { srand((unsigned)time(NULL)); rand(); }
444
445#ifndef MIN
447#define MIN(a,b) (((a)<(b))?(a):(b))
448#endif
449#ifndef MAX
451#define MAX(a,b) (((a)>(b))?(a):(b))
452#endif
453
454
456#define CONCAT_BUILDER(a, b) a ## b
458#define CONCAT(a, b) CONCAT_BUILDER(a, b)
459
460#if( BYTEORDER_ENDIAN == BYTEORDER_LITTLE_ENDIAN )
462# define htonll(x) (x)
464# define ntohll(x) (x)
465#else
467# define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
469# define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
470#endif
471
472 /* exit and print log to stderr */
473 void n_abort( char const *format, ... );
474
475 int get_computer_name( char *computer_name , size_t len );
476
477 /* get running program name */
478 char *get_prog_name( void );
479
480 /* get running program directory */
481 char *get_prog_dir( void );
482
483 /* test file presence*/
484 int file_exist( const char *filename );
485
486 /* shortcut for popen usage */
487 int n_popen( char *cmd, int read_buf_size, void **nstr_output, int *ret );
488
489 /* log environnement */
490 void log_environment( int loglevel );
491
492#ifndef __windows__
493 /* reap zombie processes */
494 void sigchld_handler( int sig );
495 /* install signal SIGCHLD handler */
498#define N_DAEMON_NO_CLOSE 2
500#define N_DAEMON_NO_STD_REDIRECT 4
502#define N_DAEMON_NO_DOUBLE_FORK 8
504#define N_DAEMON_NO_SETSID 16
506#define N_DAEMON_NO_UMASK 32
508#define N_DAEMON_NO_CHDIR 64
510#define N_DAEMON_NO_SIGCHLD_IGN 128
512#define N_DAEMON_NO_SIGCHLD_HANDLER 256
513 /* daemonize */
514 int n_daemonize( void );
515 /* daemonize */
516 int n_daemonize_ex( int mode );
517 /* non blocking system call */
518 pid_t system_nb(const char * command, int * infp, int * outfp);
519#endif
520
521 /* reconstruct hidden string */
522 void N_HIDE_STR(char *buf, ...);
523
524 char *n_get_file_extension(char path[]);
529#ifdef __cplusplus
530 }
531#endif
532
533#endif // header guard
534
void log_environment(int loglevel)
log environment in syslog
Definition n_common.c:273
char * get_prog_name(void)
get current program name
Definition n_common.c:147
void N_HIDE_STR(char *buf,...)
store a hidden version of a string
Definition n_common.c:496
int get_computer_name(char *computer_name, size_t len)
abort program with a text
Definition n_common.c:60
void sigchld_handler(int sig)
Handles SIGCHLD issues when forking.
Definition n_common.c:238
pid_t system_nb(const char *command, int *infp, int *outfp)
Non blocking system call.
Definition n_common.c:417
char * n_get_file_extension(char path[])
get extension of path+filename
Definition n_common.c:519
int n_popen(char *cmd, int read_buf_size, void **nstr_output, int *ret)
launch a command abd return output and status
Definition n_common.c:187
char * get_prog_dir(void)
get current program running directory
Definition n_common.c:111
int n_daemonize_ex(int mode)
Daemonize program.
Definition n_common.c:296
void n_abort(char const *format,...)
abort program with a text
Definition n_common.c:40
int sigchld_handler_installer()
install signal SIGCHLD handler to reap zombie processes
Definition n_common.c:253
int n_daemonize(void)
Daemonize program.
Definition n_common.c:286
int file_exist(const char *filename)
test if file exist and if it's readable
Definition n_common.c:94
Macro to build enums and their tostring counterparts, a reduced version of https://github....
Generic log system.