Compare commits

...

10 Commits

Author SHA1 Message Date
Hongcai Deng d6dca2cad1
Merge a16fde8070 into f6f664b33d 2026-08-10 13:24:42 +05:30
YuQing f6f664b33d call getFileContentEx with offset constant 2026-07-22 15:34:16 +08:00
YuQing 7b06207f6f doc/ini_file_reader-Chinese.md beautify 2026-07-15 11:55:03 +08:00
YuQing d21a95b02e upgrade version to 1.0.87 2026-07-14 08:30:01 +08:00
YuQing a755beb263 README.md small changes 2026-07-11 09:21:27 +08:00
YuQing 369fe740d3 README.md: beautify layout 2026-07-10 20:45:30 +08:00
YuQing 176cf19576 rename README to README.md 2026-07-10 20:39:34 +08:00
YuQing 598ae419e7 README add doc links 2026-07-10 20:34:54 +08:00
YuQing 4f87de79ec ini_file_readers can refer env variable as %{env::XXX} 2026-07-10 19:45:08 +08:00
Hongcai Deng a16fde8070 fix: compile error when build .so using .a
```
src/libfastcommon.a(hash.o): relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
```

env: Ubuntu 14.04, gcc 4.8
2017-01-29 14:20:18 +08:00
12 changed files with 84 additions and 52 deletions

View File

@ -1,4 +1,7 @@
Version 1.87 2026-07-10
* ini_file_readers can refer env variable such as %{env::FASTDFS_IPADDR}
Version 1.86 2026-06-26 Version 1.86 2026-06-26
* add function fc_parse_version * add function fc_parse_version
* change return type of format_ip_address and format_ip_port * change return type of format_ip_address and format_ip_port

View File

@ -1,11 +1,3 @@
Copyright (C) 2010 Happy Fish / YuQing
libfastcommon may be copied only under the terms of the Less GNU General
Public License(LGPL).
Please visit the libfastcommon Home Page for more detail.
English language: https://github.com/happyfish100/libfastcommon
Chinese language: http://www.fastken.com/
c common functions library extracted from my open source projects FastDFS and c common functions library extracted from my open source projects FastDFS and
FastDHT. this library is very simple and stable. FastDHT. this library is very simple and stable.
@ -14,20 +6,29 @@ some functions are wrappered into php extension, such as fastcommon_gethostaddrs
fastcommon_id_generator_xxx, fastcommon_get_ifconfigs, fastcommon_get_sysinfo etc. fastcommon_id_generator_xxx, fastcommon_get_ifconfigs, fastcommon_get_sysinfo etc.
C function including: C function including:
logger: [logger.h] asynchronously sync to disk for high performance, thread safe, logger: [logger.h] asynchronously sync to disk for high performance, thread safe,
log rotate, auto delete old log files, compress log file etc. log rotate, auto delete old log files, compress log file etc.
ini file reader: [ini_file_reader.h] support sections marked by [SectionName] ini file reader: [ini_file_reader.h] support sections marked by [SectionName],
support a config item ocurs multiple times for multiple values, such as: support a config item ocurs multiple times for multiple values, such as:
```
tracker_server = ip1 tracker_server = ip1
tracker_server = ip2 tracker_server = ip2
```
```
#include directive to include other ini file #include directive to include other ini file
#@function directive for annotation #@function directive for annotation
#@set directive to set variables for condition of #@if directive #@set directive to set variables for condition of #@if directive
support control statements for special purpose as: support control statements for special purpose as:
#@if, #@else, #@endif, #@for, #@endfor #@if, #@else, #@endif, #@for, #@endfor
```
id generator: [id_generator.h] generate unique 64 bits integer ID for multi processes for more detail, please see [ini file reader guide](doc/ini_file_reader-Chinese.md)
id generator: [id_generator.h] generate unique 64 bits integer ID for multi processes.
for more detail, please see [id generator description](doc/id_generator-Chinese.md)
string operation: [shared_func.h] uppercase, lowercase, trim etc. string operation: [shared_func.h] uppercase, lowercase, trim etc.
@ -72,5 +73,5 @@ C function including:
char convert: [char_converter.h] and [char_convert_loader.h] for fast char convert char convert: [char_converter.h] and [char_convert_loader.h] for fast char convert
detail info please see the c header files. more detail info please see the c header files.

View File

@ -10,38 +10,42 @@ libfastcommon是在github开源的⼀个C函数库。它提供了ini⽂件解析
## ini_file_reader的主要特点 ## ini_file_reader的主要特点
### 1、⽀持section ### 1、⽀持section
例如:
``` ```
例如: [workers] [workers]
threads = 4
# 其他配置项
``` ```
### 2、⼀个配置项可以出现多次 ### 2、⼀个配置项可以出现多次
```
通过iniGetValues或者iniGetValuesEx获取。例如 通过iniGetValues或者iniGetValuesEx获取。例如
tracker_server = ip1 ```
tracker_server = ip2 tracker_server = 172.16.168.10
tracker_server = 172.16.168.11
``` ```
### 3、 #include指令包含其他配置⽂件 ### 3、 #include指令包含其他配置⽂件
可以包含本地配置⽂件也可以包含URL目前仅⽀持HTTP。例如
``` ```
可以包含本地⽂件也可以包含URL目前仅⽀持HTTP。例如
#include http.conf #include http.conf
``` ```
### 4、 #@function指令⽀持标注 ### 4、 #@function指令⽀持标注
配置项的取值为扩展(外部)动态库的返回值。
⽀持三个内置标注:
``` ```
配置项的取值为扩展(外部)动态库的返回值
V1.39⽀持三个内置标注:
I. LOCAL_IP_GET [inner | private | outer | public] 获取本机IP地址 I. LOCAL_IP_GET [inner | private | outer | public] 获取本机IP地址
inner或private表示获取内网IPouter或public表示获取外网IP inner或private表示获取内网IPouter或public表示获取外网IP
[index]表示获取指定序号的本机IP0表示获取第一个IP-1表示获取最后一个IP [index]表示获取指定序号的本机IP0表示获取第一个IP-1表示获取最后一个IP
例如:[0]、inner[-1], outer[1]等等 例如:[0]、inner[-1], outer[1]等等
II. SHELL_EXEC 获取命令⾏输出执行的command为配置项 II. SHELL_EXEC 获取命令⾏输出执行的command为配置项
III. REPLACE_VARS 替换配置项中%{VARIABLE}格式的变量,变量由#@set指令设置 III. REPLACE_VARS 替换配置项中%{VARIABLE}格式的变量,普通变量由#@set指令设置。
可以引用环境变量,格式为 %{env::VARIABLE},例如 %{env::FASTDFS_IPADDR}
``` ```
```
配置⽰例: 配置⽰例:
```
#@function SHELL_EXEC #@function SHELL_EXEC
host = hostname host = hostname
@ -57,12 +61,14 @@ libfastcommon是在github开源的⼀个C函数库。它提供了ini⽂件解析
### 5、 #@add_annotation 扩展#@function标签 ### 5、 #@add_annotation 扩展#@function标签
```
格式: 格式:
```
#@add_annotation <function> <动态库文件名> [参数1, 参数2, ...] #@add_annotation <function> <动态库文件名> [参数1, 参数2, ...]
```
参数个数0到3个。 参数个数0到3个。
使用libshmcache扩展标签CONFIG_GET示例 使用libshmcache扩展标签CONFIG_GET示例
```
#@add_annotation CONFIG_GET /usr/lib/libshmcache.so /etc/libshmcache.conf #@add_annotation CONFIG_GET /usr/lib/libshmcache.so /etc/libshmcache.conf
#@function CONFIG_GET #@function CONFIG_GET

View File

@ -3,7 +3,7 @@
%define CommitVersion %(echo $COMMIT_VERSION) %define CommitVersion %(echo $COMMIT_VERSION)
Name: libfastcommon Name: libfastcommon
Version: 1.0.86 Version: 1.0.87
Release: 1%{?dist} Release: 1%{?dist}
Summary: c common functions library extracted from my open source projects FastDFS Summary: c common functions library extracted from my open source projects FastDFS
License: LGPL License: LGPL

View File

@ -68,7 +68,7 @@ libfastcommon.a: $(FAST_STATIC_OBJS)
.c: .c:
$(COMPILE) -o $@ $< $(FAST_STATIC_OBJS) $(LIB_PATH) $(INC_PATH) $(COMPILE) -o $@ $< $(FAST_STATIC_OBJS) $(LIB_PATH) $(INC_PATH)
.c.o: .c.o:
$(COMPILE) -c -o $@ $< $(INC_PATH) $(COMPILE) -c -fPIC -o $@ $< $(INC_PATH)
.c.lo: .c.lo:
$(COMPILE) -c -fPIC -o $@ $< $(INC_PATH) $(COMPILE) -c -fPIC -o $@ $< $(INC_PATH)
install: install:

View File

@ -180,6 +180,7 @@ int fast_buffer_append_binary(FastBuffer *buffer,
int fast_buffer_append_file(FastBuffer *buffer, const char *filename) int fast_buffer_append_file(FastBuffer *buffer, const char *filename)
{ {
const int64_t offset = 0;
struct stat st; struct stat st;
int result; int result;
int64_t file_size; int64_t file_size;
@ -213,7 +214,7 @@ int fast_buffer_append_file(FastBuffer *buffer, const char *filename)
} }
if ((result=getFileContentEx(filename, buffer->data + buffer->length, if ((result=getFileContentEx(filename, buffer->data + buffer->length,
0, &file_size)) != 0) offset, &file_size)) != 0)
{ {
return result; return result;
} }

View File

@ -22,7 +22,7 @@
#define FC_MAJOR_VERSION 1 #define FC_MAJOR_VERSION 1
#define FC_MINOR_VERSION 0 #define FC_MINOR_VERSION 0
#define FC_PATCH_VERSION 86 #define FC_PATCH_VERSION 87
#define FC_VERSION_INT FC_VERSION_TO_INT(FC_MAJOR_VERSION, \ #define FC_VERSION_INT FC_VERSION_TO_INT(FC_MAJOR_VERSION, \
FC_MINOR_VERSION, FC_PATCH_VERSION) FC_MINOR_VERSION, FC_PATCH_VERSION)

View File

@ -299,6 +299,11 @@ static char *doReplaceVars(IniContext *pContext, const char *param,
{ {
#define VARIABLE_TAG_MIN_LENGTH 4 //%{v} #define VARIABLE_TAG_MIN_LENGTH 4 //%{v}
#define ENV_VAR_NAME_STARTWITH_STR "env::"
#define ENV_VAR_NAME_STARTWITH_LEN (sizeof(ENV_VAR_NAME_STARTWITH_STR) - 1)
#define ENV_VARIABLE_MARK_STR "%{"ENV_VAR_NAME_STARTWITH_STR
SetDirectiveVars *set; SetDirectiveVars *set;
const char *p; const char *p;
const char *e; const char *e;
@ -319,12 +324,14 @@ static char *doReplaceVars(IniContext *pContext, const char *param,
set = iniGetVars(pContext); set = iniGetVars(pContext);
if (set == NULL || set->vars == NULL) { if (set == NULL || set->vars == NULL) {
if (strstr(param, ENV_VARIABLE_MARK_STR) == NULL) {
logWarning("file: "__FILE__", line: %d, " logWarning("file: "__FILE__", line: %d, "
"NO set directives before, set value to %s", "NO set directives before, set value to %s",
__LINE__, param); __LINE__, param);
fc_strlcpy(output, param, FAST_INI_ITEM_VALUE_SIZE); fc_strlcpy(output, param, FAST_INI_ITEM_VALUE_SIZE);
return output; return output;
} }
}
pEnd = param + strlen(param); pEnd = param + strlen(param);
pLoopEnd = pEnd - (VARIABLE_TAG_MIN_LENGTH - 1); pLoopEnd = pEnd - (VARIABLE_TAG_MIN_LENGTH - 1);
@ -354,25 +361,33 @@ static char *doReplaceVars(IniContext *pContext, const char *param,
*(name + name_len) = '\0'; *(name + name_len) = '\0';
fc_trim(name); fc_trim(name);
name_len = strlen(name); name_len = strlen(name);
if (name_len > 0) { if (name_len > ENV_VAR_NAME_STARTWITH_LEN &&
memcmp(name, ENV_VAR_NAME_STARTWITH_STR,
ENV_VAR_NAME_STARTWITH_LEN) == 0)
{
value = getenv(name + ENV_VAR_NAME_STARTWITH_LEN);
} else if (name_len > 0) {
if (set != NULL && set->vars != NULL) {
value = (char *)fc_hash_find(set->vars, name, name_len); value = (char *)fc_hash_find(set->vars, name, name_len);
} else { } else {
value = NULL; value = NULL;
} }
} else {
value = NULL;
}
if (value != NULL) { if (value != NULL) {
len = strlen(value); len = strlen(value);
} } else {
else {
logWarning("file: "__FILE__", line: %d, " logWarning("file: "__FILE__", line: %d, "
"name: %s NOT found, keep the origin", "variable \"%s\" NOT found, keep the origin",
__LINE__, name); __LINE__, name);
value = start - 2; value = start - 2;
len = p - value; len = p - value;
} }
pDest += iniCopyBuffer(pDest, FAST_INI_ITEM_VALUE_SIZE - pDest += iniCopyBuffer(pDest, FAST_INI_ITEM_VALUE_SIZE -
(pDest - output), value, len); (pDest - output), value, len);
} } else {
else {
if (pDest - output < FAST_INI_ITEM_VALUE_LEN) { if (pDest - output < FAST_INI_ITEM_VALUE_LEN) {
*pDest++ = *p++; *pDest++ = *p++;
} }

View File

@ -24,6 +24,7 @@
int get_pid_from_file(const char *pidFilename, pid_t *pid) int get_pid_from_file(const char *pidFilename, pid_t *pid)
{ {
const int64_t offset = 0;
char buff[32]; char buff[32];
int64_t file_size; int64_t file_size;
int result; int result;
@ -33,7 +34,7 @@ int get_pid_from_file(const char *pidFilename, pid_t *pid)
} }
file_size = sizeof(buff); file_size = sizeof(buff);
if ((result=getFileContentEx(pidFilename, buff, 0, &file_size)) != 0) { if ((result=getFileContentEx(pidFilename, buff, offset, &file_size)) != 0) {
return result; return result;
} }
@ -183,12 +184,13 @@ static const char *process_get_exename(const char* program)
static const char *get_exename_by_pid(const pid_t pid, char *buff, static const char *get_exename_by_pid(const pid_t pid, char *buff,
const int buff_size, int *result) const int buff_size, int *result)
{ {
const int64_t offset = 0;
char cmdfile[MAX_PATH_SIZE]; char cmdfile[MAX_PATH_SIZE];
int64_t cmdsz; int64_t cmdsz;
cmdsz = buff_size; cmdsz = buff_size;
sprintf(cmdfile, "/proc/%d/cmdline", pid); sprintf(cmdfile, "/proc/%d/cmdline", pid);
if ((*result=getFileContentEx(cmdfile, buff, 0, &cmdsz)) != 0) { if ((*result=getFileContentEx(cmdfile, buff, offset, &cmdsz)) != 0) {
fprintf(stderr, "read file %s fail, errno: %d, error info: %s\n", fprintf(stderr, "read file %s fail, errno: %d, error info: %s\n",
cmdfile, *result, strerror(*result)); cmdfile, *result, strerror(*result));
return NULL; return NULL;

View File

@ -4090,12 +4090,13 @@ int fc_check_rename_ex(const char *oldpath, const char *newpath,
int fc_get_first_line(const char *filename, char *buff, int fc_get_first_line(const char *filename, char *buff,
const int buff_size, string_t *line) const int buff_size, string_t *line)
{ {
const int64_t offset = 0;
int result; int result;
int64_t read_bytes; int64_t read_bytes;
char *line_end; char *line_end;
read_bytes = buff_size - 1; read_bytes = buff_size - 1;
if ((result=getFileContentEx(filename, buff, 0, &read_bytes)) != 0) { if ((result=getFileContentEx(filename, buff, offset, &read_bytes)) != 0) {
FC_SET_STRING_EMPTY(*line, buff); FC_SET_STRING_EMPTY(*line, buff);
return result; return result;
} }
@ -4121,6 +4122,7 @@ int fc_get_first_line(const char *filename, char *buff,
int fc_get_first_lines(const char *filename, char *buff, int fc_get_first_lines(const char *filename, char *buff,
const int buff_size, string_t *lines, int *count) const int buff_size, string_t *lines, int *count)
{ {
const int64_t offset = 0;
int result; int result;
int target_count; int target_count;
int64_t read_bytes; int64_t read_bytes;
@ -4134,7 +4136,7 @@ int fc_get_first_lines(const char *filename, char *buff,
} }
read_bytes = buff_size - 1; read_bytes = buff_size - 1;
if ((result=getFileContentEx(filename, buff, 0, &read_bytes)) != 0) { if ((result=getFileContentEx(filename, buff, offset, &read_bytes)) != 0) {
*count = 0; *count = 0;
FC_SET_STRING_EMPTY(*lines, buff); FC_SET_STRING_EMPTY(*lines, buff);
return result; return result;

View File

@ -878,7 +878,7 @@ int getFileContentEx1(int fd, const char *filename, char *buff,
* size: specify the size to fetch and return the fetched size * size: specify the size to fetch and return the fetched size
* return: error no , 0 success, != 0 fail * return: error no , 0 success, != 0 fail
*/ */
int getFileContentEx(const char *filename, char *buff, \ int getFileContentEx(const char *filename, char *buff,
int64_t offset, int64_t *size); int64_t offset, int64_t *size);
/** get file size /** get file size

View File

@ -118,12 +118,13 @@ int get_sys_cpu_count()
int get_boot_time(struct timeval *boot_time) int get_boot_time(struct timeval *boot_time)
{ {
#ifdef OS_LINUX #ifdef OS_LINUX
const int64_t offset = 0;
char buff[256]; char buff[256];
int64_t bytes; int64_t bytes;
struct sysinfo si; struct sysinfo si;
bytes = sizeof(buff); bytes = sizeof(buff);
if (getFileContentEx("/proc/uptime", buff, 0, &bytes) == 0) if (getFileContentEx("/proc/uptime", buff, offset, &bytes) == 0)
{ {
double uptime; double uptime;
double btime; double btime;
@ -621,6 +622,7 @@ static void parse_proc_stat(char *buff, const int len,
int get_processes(struct fast_process_info **processes, int *count) int get_processes(struct fast_process_info **processes, int *count)
{ {
const int64_t offset = 0;
const char *dirname = "/proc"; const char *dirname = "/proc";
char filename[128]; char filename[128];
char buff[4096]; char buff[4096];
@ -679,7 +681,7 @@ int get_processes(struct fast_process_info **processes, int *count)
sprintf(filename, "%s/%s/stat", dirname, ent->d_name); sprintf(filename, "%s/%s/stat", dirname, ent->d_name);
bytes = sizeof(buff); bytes = sizeof(buff);
if (getFileContentEx(filename, buff, 0, &bytes) != 0) if (getFileContentEx(filename, buff, offset, &bytes) != 0)
{ {
continue; continue;
} }