491 lines
11 KiB
C
491 lines
11 KiB
C
/*
|
|
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
*
|
|
* This program is free software: you can use, redistribute, and/or modify
|
|
* it under the terms of the Lesser GNU General Public License, version 3
|
|
* or later ("LGPL"), as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* You should have received a copy of the Lesser GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
//common_define.h
|
|
|
|
#ifndef _COMMON_DEFINE_H_
|
|
#define _COMMON_DEFINE_H_
|
|
|
|
#include <pthread.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
|
|
#ifdef WIN32
|
|
|
|
#include <windows.h>
|
|
#include <winsock.h>
|
|
typedef UINT in_addr_t;
|
|
#define FILE_SEPERATOR "\\"
|
|
#define THREAD_ENTRANCE_FUNC_DECLARE DWORD WINAPI
|
|
#define THREAD_RETURN_VALUE 0
|
|
typedef DWORD (WINAPI *ThreadEntranceFunc)(LPVOID lpThreadParameter);
|
|
#else
|
|
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <stdbool.h>
|
|
#include <inttypes.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
|
|
#ifdef OS_FREEBSD
|
|
//#include <sys/syscall.h>
|
|
#endif
|
|
|
|
#define FILE_SEPERATOR "/"
|
|
typedef int SOCKET;
|
|
#define closesocket close
|
|
#define INVALID_SOCKET -1
|
|
#define THREAD_ENTRANCE_FUNC_DECLARE void *
|
|
typedef void *LPVOID;
|
|
#define THREAD_RETURN_VALUE NULL
|
|
typedef void * (*ThreadEntranceFunc)(LPVOID lpThreadParameter);
|
|
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
|
|
#endif
|
|
|
|
#include "_os_define.h"
|
|
|
|
#ifdef OS_LINUX
|
|
#include <sys/prctl.h>
|
|
#endif
|
|
|
|
#ifdef OS_LINUX
|
|
#ifndef PTHREAD_MUTEX_ERRORCHECK
|
|
#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef OS_BITS
|
|
#if OS_BITS == 64
|
|
#define INT64_PRINTF_FORMAT "%ld"
|
|
#else
|
|
#define INT64_PRINTF_FORMAT "%lld"
|
|
#endif
|
|
#else
|
|
#define INT64_PRINTF_FORMAT "%lld"
|
|
#endif
|
|
|
|
#ifdef OFF_BITS
|
|
#if OFF_BITS == 64
|
|
#define OFF_PRINTF_FORMAT INT64_PRINTF_FORMAT
|
|
#else
|
|
#define OFF_PRINTF_FORMAT "%d"
|
|
#endif
|
|
#else
|
|
#define OFF_PRINTF_FORMAT INT64_PRINTF_FORMAT
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#define USE_SENDFILE
|
|
#endif
|
|
|
|
#define MAX_PATH_SIZE 256
|
|
#define LOG_FILE_DIR "logs"
|
|
#define CONF_FILE_DIR "conf"
|
|
#define DEFAULT_CONNECT_TIMEOUT 10
|
|
#define DEFAULT_NETWORK_TIMEOUT 30
|
|
#define DEFAULT_MAX_CONNECTONS 256
|
|
#define DEFAULT_WORK_THREADS 4
|
|
#define SYNC_LOG_BUFF_DEF_INTERVAL 10
|
|
#define TIME_NONE -1
|
|
|
|
#define IP_ADDRESS_SIZE 16
|
|
#define INFINITE_FILE_SIZE (256 * 1024LL * 1024 * 1024 * 1024 * 1024LL)
|
|
|
|
#define FILE_RESOURCE_TAG_STR "file://"
|
|
#define FILE_RESOURCE_TAG_LEN (sizeof(FILE_RESOURCE_TAG_STR) - 1)
|
|
|
|
#define IS_FILE_RESOURCE(filename) \
|
|
(strncasecmp(filename, FILE_RESOURCE_TAG_STR, \
|
|
FILE_RESOURCE_TAG_LEN) == 0)
|
|
|
|
#ifndef byte
|
|
#define byte signed char
|
|
#endif
|
|
|
|
#ifndef ubyte
|
|
#define ubyte unsigned char
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#ifndef INADDR_NONE
|
|
#define INADDR_NONE ((in_addr_t) 0xffffffff)
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef ECANCELED
|
|
#define ECANCELED 125
|
|
#endif
|
|
|
|
#ifndef ENONET
|
|
#define ENONET 64 /* Machine is not on the network */
|
|
#endif
|
|
|
|
#define compile_barrier() __asm__ __volatile__("" : : : "memory")
|
|
|
|
#define IS_UPPER_HEX(ch) ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F'))
|
|
#define IS_HEX_CHAR(ch) (IS_UPPER_HEX(ch) || (ch >= 'a' && ch <= 'f'))
|
|
#define FC_IS_DIGITAL(ch) (ch >= '0' && ch <= '9')
|
|
#define FC_IS_LETTER(ch) ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
|
|
#define FC_IS_UPPER_LETTER(ch) (ch >= 'A' && ch <= 'Z')
|
|
#define FC_IS_LOWER_LETTER(ch) (ch >= 'a' && ch <= 'z')
|
|
#define FC_MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
|
|
#define FC_MAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
|
|
#define FC_ABS(n) ((n) >= 0 ? (n) : -1 * (n))
|
|
#define FC_NEGATIVE(n) ((n) <= 0 ? (n) : -1 * (n))
|
|
|
|
#define FC_TIME_UNIT_SECOND 's' //second
|
|
#define FC_TIME_UNIT_MSECOND 'm' //millisecond
|
|
#define FC_TIME_UNIT_USECOND 'u' //microsecond
|
|
#define FC_TIME_UNIT_NSECOND 'n' //nanosecond
|
|
|
|
#define STRERROR(no) (strerror(no) != NULL ? strerror(no) : "Unkown error")
|
|
|
|
#if defined(OS_LINUX)
|
|
#if defined __USE_MISC || defined __USE_XOPEN2K8
|
|
#define st_atimensec st_atim.tv_nsec
|
|
#define st_mtimensec st_mtim.tv_nsec
|
|
#define st_ctimensec st_ctim.tv_nsec
|
|
#endif
|
|
#elif defined(OS_FREEBSD)
|
|
#define st_atimensec st_atimespec.tv_nsec
|
|
#define st_mtimensec st_mtimespec.tv_nsec
|
|
#define st_ctimensec st_ctimespec.tv_nsec
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
byte hour;
|
|
byte minute;
|
|
byte second;
|
|
} TimeInfo;
|
|
|
|
typedef struct
|
|
{
|
|
char major;
|
|
char minor;
|
|
char patch;
|
|
} Version;
|
|
|
|
typedef struct
|
|
{
|
|
char **strs;
|
|
int count;
|
|
} str_ptr_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
char *key;
|
|
char *value;
|
|
} KeyValuePair;
|
|
|
|
typedef struct
|
|
{
|
|
char *key;
|
|
char *value;
|
|
int key_len;
|
|
int value_len;
|
|
} KeyValuePairEx;
|
|
|
|
typedef struct
|
|
{
|
|
char *buff;
|
|
int alloc_size;
|
|
int length;
|
|
} BufferInfo;
|
|
|
|
typedef struct
|
|
{
|
|
char *str;
|
|
int len;
|
|
} string_t;
|
|
|
|
typedef struct
|
|
{
|
|
string_t *strings;
|
|
int count;
|
|
} string_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
int64_t id;
|
|
string_t name;
|
|
} id_name_pair_t;
|
|
|
|
typedef struct
|
|
{
|
|
string_t key;
|
|
string_t value;
|
|
} key_value_pair_t;
|
|
|
|
typedef struct
|
|
{
|
|
key_value_pair_t *kv_pairs;
|
|
int count;
|
|
} key_value_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
int32_t *elts;
|
|
int count;
|
|
} int32_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
int64_t *elts;
|
|
int count;
|
|
} int64_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
id_name_pair_t *elts;
|
|
int count;
|
|
} id_name_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
void *elts;
|
|
int count;
|
|
} void_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
pthread_mutex_t lock;
|
|
pthread_cond_t cond;
|
|
} pthread_lock_cond_pair_t;
|
|
|
|
typedef struct
|
|
{
|
|
int alloc;
|
|
int count;
|
|
struct iovec *iovs;
|
|
} iovec_array_t;
|
|
|
|
typedef struct
|
|
{
|
|
char buff[PATH_MAX];
|
|
string_t s;
|
|
} FilenameString;
|
|
|
|
typedef struct {
|
|
char *filename;
|
|
char *tmp_filename;
|
|
int fd;
|
|
} SafeWriteFileInfo;
|
|
|
|
typedef struct {
|
|
char filename[PATH_MAX];
|
|
int fd;
|
|
} FilenameFDPair;
|
|
|
|
typedef void (*FreeDataFunc)(void *ptr);
|
|
typedef int (*CompareFunc)(void *p1, void *p2);
|
|
typedef void* (*MallocFunc)(size_t size);
|
|
|
|
#define TO_UPPERCASE(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 32 : c)
|
|
|
|
#define MEM_ALIGN_FLOOR(x, align_size) ((x) & (~(align_size - 1)))
|
|
#define MEM_ALIGN_CEIL(x, align_size) \
|
|
(((x) + (align_size - 1)) & (~(align_size - 1)))
|
|
#define MEM_ALIGN(x) MEM_ALIGN_CEIL(x, 8)
|
|
|
|
#define FC_INIT_CHAIN(chain) (chain).head = (chain).tail = NULL
|
|
#define FC_IS_CHAIN_EMPTY(chain) ((chain).head == NULL)
|
|
|
|
#define FC_SET_CHAIN_TAIL_NEXT(chain, type, ptr) \
|
|
((type *)(chain).tail)->next = ptr
|
|
|
|
#ifdef WIN32
|
|
#define strcasecmp _stricmp
|
|
#endif
|
|
|
|
#ifndef likely
|
|
|
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
|
#define likely(cond) __builtin_expect ((cond), 1)
|
|
#define unlikely(cond) __builtin_expect ((cond), 0)
|
|
#else
|
|
#define likely(cond) (cond)
|
|
#define unlikely(cond) (cond)
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
#define __gcc_attribute__ __attribute__
|
|
#else
|
|
#define __gcc_attribute__(x)
|
|
#endif
|
|
|
|
#define FC_IS_CHINESE_UTF8_CHAR(p, end) \
|
|
((p + 2 < end) && \
|
|
((((unsigned char)*p) & 0xF0) == 0xE0) && \
|
|
((((unsigned char)*(p + 1)) & 0xC0) == 0x80) && \
|
|
((((unsigned char)*(p + 2)) & 0xC0) == 0x80))
|
|
|
|
//for printf format %.*s
|
|
#define FC_PRINTF_STAR_STRING_PARAMS(s) (s).len, (s).str
|
|
|
|
#define FC_SET_IOVEC(iovec, buff, len) \
|
|
do { \
|
|
(iovec).iov_base = buff; \
|
|
(iovec).iov_len = len; \
|
|
} while (0)
|
|
|
|
#define FC_SET_STRING(dest, src) \
|
|
do { \
|
|
(dest).str = src; \
|
|
(dest).len = strlen(src); \
|
|
} while (0)
|
|
|
|
#define FC_SET_STRING_EX(dest, s, l) \
|
|
do { \
|
|
(dest).str = s; \
|
|
(dest).len = l; \
|
|
} while (0)
|
|
|
|
#define FC_SET_STRING_NULL(dest) \
|
|
do { \
|
|
(dest).str = NULL; \
|
|
(dest).len = 0; \
|
|
} while (0)
|
|
|
|
#define FC_IS_NULL_STRING(s) ((s)->str == NULL)
|
|
#define FC_IS_EMPTY_STRING(s) ((s)->len == 0)
|
|
|
|
#define FC_INIT_FILENAME_STRING(filename) \
|
|
FC_SET_STRING_EX((filename).s, (filename).buff, 0)
|
|
|
|
#define FC_FILENAME_STRING_OBJ(filename) ((filename).s)
|
|
#define FC_FILENAME_STRING_PTR(filename) ((filename).buff)
|
|
#define FC_FILENAME_BUFFER_SIZE(filename) sizeof((filename).buff)
|
|
|
|
#define fc_compare_string(s1, s2) fc_string_compare(s1, s2)
|
|
|
|
static inline int fc_string_compare(const string_t *s1, const string_t *s2)
|
|
{
|
|
int result;
|
|
if (s1->len == s2->len) {
|
|
return memcmp(s1->str, s2->str, s1->len);
|
|
} else if (s1->len < s2->len) {
|
|
result = memcmp(s1->str, s2->str, s1->len);
|
|
return result == 0 ? -1 : result;
|
|
} else {
|
|
result = memcmp(s1->str, s2->str, s2->len);
|
|
return result == 0 ? 1 : result;
|
|
}
|
|
}
|
|
|
|
static inline bool fc_string_equal(const string_t *s1, const string_t *s2)
|
|
{
|
|
return (s1->len == s2->len) && (memcmp(s1->str, s2->str, s1->len) == 0);
|
|
}
|
|
|
|
static inline bool fc_string_equal2(const string_t *s1,
|
|
const char *str2, const int len2)
|
|
{
|
|
return (s1->len == len2) && (memcmp(s1->str, str2, s1->len) == 0);
|
|
}
|
|
|
|
#define fc_string_equals(s1, s2) fc_string_equal(s1, s2)
|
|
#define fc_string_equals2(s1, str2, len2) fc_string_equal2(s1, str2, len2)
|
|
|
|
|
|
#define fc_case_compare_string(s1, s2) fc_string_case_compare(s1, s2)
|
|
|
|
static inline int fc_string_case_compare(const string_t *s1, const string_t *s2)
|
|
{
|
|
int result;
|
|
if (s1->len == s2->len) {
|
|
return strncasecmp(s1->str, s2->str, s1->len);
|
|
} else if (s1->len < s2->len) {
|
|
result = strncasecmp(s1->str, s2->str, s1->len);
|
|
return result == 0 ? -1 : result;
|
|
} else {
|
|
result = strncasecmp(s1->str, s2->str, s2->len);
|
|
return result == 0 ? 1 : result;
|
|
}
|
|
}
|
|
|
|
static inline bool fc_string_case_equal(const string_t *s1, const string_t *s2)
|
|
{
|
|
return (s1->len == s2->len) && (strncasecmp(s1->str, s2->str, s1->len) == 0);
|
|
}
|
|
|
|
static inline bool fc_string_case_equal2(const string_t *s1,
|
|
const char *str2, const int len2)
|
|
{
|
|
return (s1->len == len2) && (strncasecmp(s1->str, str2, s1->len) == 0);
|
|
}
|
|
|
|
#define fc_string_case_equals(s1, s2) fc_string_case_equal(s1, s2)
|
|
#define fc_string_case_equals2(s1, str2, len2) \
|
|
fc_string_case_equal2(s1, str2, len2)
|
|
|
|
|
|
static inline int fc_compare_int64(const int64_t n1, const int64_t n2)
|
|
{
|
|
int64_t sub;
|
|
sub = n1 - n2;
|
|
if (sub < 0) {
|
|
return -1;
|
|
} else if (sub > 0) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#ifdef OS_LINUX
|
|
#define fc_fallocate(fd, size) fallocate(fd, 0, 0, size)
|
|
#else
|
|
#define fc_fallocate(fd, size) ftruncate(fd, size)
|
|
#define posix_fadvise(fd, offset, len, advice) 0
|
|
|
|
#ifndef POSIX_FADV_NORMAL
|
|
#define POSIX_FADV_NORMAL 0 /* No further special treatment. */
|
|
#define POSIX_FADV_RANDOM 1 /* Expect random page references. */
|
|
#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
|
#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
|
|
#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
|
|
#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
|
|
#endif
|
|
|
|
#ifdef OS_FREEBSD
|
|
//#define fdatasync(fd) syscall(SYS_fdatasync, fd)
|
|
#define fdatasync(fd) fsync(fd)
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|