1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** Macros to do safe string operations to avoid buffer overflows **
9 ** Macros for memory allocation, feeing and error handling **
11 \*****************************************************************************/
14 /* safe strcpy/strncpy */
16 #define SCPY(dst, src) scpy((char *)dst, src, sizeof(dst))
17 static inline void scpy(char *dst, const char *src, unsigned int siz)
19 strncpy(dst, src, siz);
23 /* safe strcat/strncat */
25 #define SCAT(dst, src) scat((char *)dst, src, sizeof(dst))
26 static inline void scat(char *dst, const char *src, unsigned int siz)
28 strncat(dst, src, siz-strlen(dst)-1);
32 /* safe concat of a byte */
34 #define SCCAT(dst, src) sccat((char *)dst, src, sizeof(dst))
35 static inline void sccat(char *dst, char chr, unsigned int siz)
37 if (strlen(dst) < siz-1)
39 dst[strlen(dst)+1] = '\0';
40 dst[strlen(dst)] = chr;
44 /* safe sprintf/snprintf */
46 #define SPRINT(dst, fmt, arg...) sprint((char *)dst, sizeof(dst), fmt, ## arg)
47 static inline void sprint(char *dst, unsigned int siz, const char *fmt, ...)
52 vsnprintf(dst, siz, fmt, args);
62 #define UPRINT sprintf
63 #define UNPRINT snprintf
64 #define VUNPRINT vsnprintf
66 #define FATAL(fmt, arg...) _fatal(__FILE__, __FUNCTION__, __LINE__, fmt, ##arg)
67 /* fatal error with error message and exit */
68 static inline void _fatal(const char *file, const char *function, int line, const char *fmt, ...)
74 vsnprintf(buffer, sizeof(buffer), fmt, args);
76 buffer[sizeof(buffer)-1] = '\0';
77 fprintf(stderr, "FATAL ERROR in function %s/%s, line %d: %s", file, function, line, buffer);
78 fprintf(stderr, "This error is not recoverable, must exit here.\n");
80 debug(file, function, line, "FATAL", buffer);
81 debug(file, function, line, "FATAL", (char *)"This error is not recoverable, must exit here.\n");
86 /* memory allocation with setting to zero */
87 #define MALLOC(size) _malloc(size, __FILE__, __FUNCTION__, __LINE__)
88 static inline void *_malloc(unsigned int size, const char *file, const char *function, int line)
93 _fatal(file, function, line, "No memory for %d bytes.\n", size);
94 memset(addr, 0, size);
98 /* memory freeing with clearing memory to prevent using freed memory */
99 #define FREE(addr, size) _free(addr, size)
100 static inline void _free(void *addr, int size)
103 memset(addr, 0, size);
107 /* fill buffer and be sure that it's result is 0-terminated, also remove newline */
108 #define GETLINE(buffer, fp) _getline(buffer, sizeof(buffer), fp)
109 static inline char *_getline(char *buffer, int size, FILE *fp)
111 if (!fgets(buffer, size-1, fp))
113 buffer[size-1] = '\0';
116 if (buffer[strlen(buffer)-1] == '\n')
117 buffer[strlen(buffer)-1] = '\0';
118 if (buffer[strlen(buffer)-1] == '\r')
119 buffer[strlen(buffer)-1] = '\0';