Compare commits
9 Commits
b5a724dcd3
...
085dd32b28
| Author | SHA1 | Date |
|---|---|---|
|
|
085dd32b28 | |
|
|
79cd21f667 | |
|
|
1edcae9cf4 | |
|
|
724b008b0e | |
|
|
0ebccb5bf0 | |
|
|
cf40f8e42e | |
|
|
e5fa72b971 | |
|
|
701acb9810 | |
|
|
a16fde8070 |
8
HISTORY
8
HISTORY
|
|
@ -1,6 +1,12 @@
|
|||
|
||||
Version 1.85 2026-06-08
|
||||
Version 1.86 2026-06-26
|
||||
* add function fc_parse_version
|
||||
* change return type of format_ip_address and format_ip_port
|
||||
|
||||
Version 1.85 2026-06-23
|
||||
* add functions fc_safe_srand and fc_safe_rand for more security under Linux
|
||||
* add function seconds_to_human_str
|
||||
* add function fc_version by new files fc_version.h and fc_version.c
|
||||
|
||||
Version 1.84 2026-01-16
|
||||
* fast_task_queue.h: add function free_queue_task_arg_offset
|
||||
|
|
|
|||
2
INSTALL
2
INSTALL
|
|
@ -21,5 +21,5 @@ Debian, Ubuntu etc.:
|
|||
# the command lines as:
|
||||
|
||||
git clone https://github.com/happyfish100/libfastcommon.git
|
||||
cd libfastcommon; git checkout V1.0.84
|
||||
cd libfastcommon; git checkout V1.0.85
|
||||
./make.sh clean && ./make.sh && sudo ./make.sh install
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
%define CommitVersion %(echo $COMMIT_VERSION)
|
||||
|
||||
Name: libfastcommon
|
||||
Version: 1.0.84
|
||||
Version: 1.0.85
|
||||
Release: 1%{?dist}
|
||||
Summary: c common functions library extracted from my open source projects FastDFS
|
||||
License: LGPL
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include "common_define.h"
|
||||
#include "fc_version.h"
|
||||
#include "local_ip_func.h"
|
||||
#include "logger.h"
|
||||
#include "hash.h"
|
||||
|
|
@ -33,10 +33,6 @@
|
|||
#include "system_info.h"
|
||||
#include "fastcommon.h"
|
||||
|
||||
#define MAJOR_VERSION 1
|
||||
#define MINOR_VERSION 0
|
||||
#define PATCH_VERSION 8
|
||||
|
||||
#define IDG_FLAGS_EXTRA_DATA_BY_MOD 1
|
||||
|
||||
#define PHP_IDG_RESOURCE_NAME "fastcommon_idg"
|
||||
|
|
@ -311,13 +307,13 @@ PHP_RSHUTDOWN_FUNCTION(fastcommon)
|
|||
|
||||
PHP_MINFO_FUNCTION(fastcommon)
|
||||
{
|
||||
char mc_info[64];
|
||||
sprintf(mc_info, "fastcommon v%d.%02d support",
|
||||
MAJOR_VERSION, MINOR_VERSION);
|
||||
char mc_info[64];
|
||||
sprintf(mc_info, "fastcommon v%d.%d.%d supported",
|
||||
FC_MAJOR_VERSION, FC_MINOR_VERSION, FC_PATCH_VERSION);
|
||||
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, mc_info, "enabled");
|
||||
php_info_print_table_end();
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, mc_info, "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -326,13 +322,14 @@ return client library version
|
|||
*/
|
||||
ZEND_FUNCTION(fastcommon_version)
|
||||
{
|
||||
char szVersion[16];
|
||||
int len;
|
||||
Version version;
|
||||
char szVersion[16];
|
||||
int len;
|
||||
|
||||
len = sprintf(szVersion, "%d.%d.%d",
|
||||
MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
|
||||
|
||||
ZEND_RETURN_STRINGL(szVersion, len, 1);
|
||||
fc_version(&version);
|
||||
len = sprintf(szVersion, "%d.%d.%d", version.major,
|
||||
version.minor, version.patch);
|
||||
ZEND_RETURN_STRINGL(szVersion, len, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \
|
|||
multi_socket_client.lo skiplist_set.lo uniq_skiplist.lo \
|
||||
json_parser.lo buffered_file_writer.lo server_id_func.lo \
|
||||
fc_queue.lo sorted_queue.lo fc_memory.lo shared_buffer.lo \
|
||||
thread_pool.lo array_allocator.lo sorted_array.lo spinlock.lo
|
||||
thread_pool.lo array_allocator.lo sorted_array.lo spinlock.lo \
|
||||
fc_version.lo
|
||||
|
||||
FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
||||
logger.o sockopt.o base64.o sched_thread.o \
|
||||
|
|
@ -31,7 +32,8 @@ FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
|||
multi_socket_client.o skiplist_set.o uniq_skiplist.o \
|
||||
json_parser.o buffered_file_writer.o server_id_func.o \
|
||||
fc_queue.o sorted_queue.o fc_memory.o shared_buffer.o \
|
||||
thread_pool.o array_allocator.o sorted_array.o spinlock.o
|
||||
thread_pool.o array_allocator.o sorted_array.o spinlock.o \
|
||||
fc_version.o
|
||||
|
||||
HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
||||
shared_func.h pthread_func.h ini_file_reader.h _os_define.h \
|
||||
|
|
@ -47,7 +49,7 @@ HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
|||
fc_list.h locked_list.h json_parser.h buffered_file_writer.h \
|
||||
server_id_func.h fc_queue.h sorted_queue.h fc_memory.h \
|
||||
shared_buffer.h thread_pool.h fc_atomic.h array_allocator.h \
|
||||
sorted_array.h spinlock.h
|
||||
sorted_array.h spinlock.h fc_version.h
|
||||
|
||||
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)
|
||||
|
||||
|
|
@ -66,7 +68,7 @@ libfastcommon.a: $(FAST_STATIC_OBJS)
|
|||
.c:
|
||||
$(COMPILE) -o $@ $< $(FAST_STATIC_OBJS) $(LIB_PATH) $(INC_PATH)
|
||||
.c.o:
|
||||
$(COMPILE) -c -o $@ $< $(INC_PATH)
|
||||
$(COMPILE) -c -fPIC -o $@ $< $(INC_PATH)
|
||||
.c.lo:
|
||||
$(COMPILE) -c -fPIC -o $@ $< $(INC_PATH)
|
||||
install:
|
||||
|
|
|
|||
|
|
@ -372,6 +372,16 @@ typedef void* (*MallocFunc)(size_t size);
|
|||
#define FC_SET_CHAIN_TAIL_NEXT(chain, type, ptr) \
|
||||
((type *)(chain).tail)->next = ptr
|
||||
|
||||
#define FC_VERSION_TO_INT(major, minor, patch) \
|
||||
(major * 1000 * 1000 + minor * 1000 + patch)
|
||||
|
||||
#define FC_VERSION_TO_INT1(version) \
|
||||
FC_VERSION_TO_INT((version).major, \
|
||||
(version).minor, (version).patch)
|
||||
|
||||
#define FC_COMPARE_INT_VERSIONS_TO_OPERATOR_STR(v1, v2) \
|
||||
(v1 < v2 ? "<" : (v1 == v2 ? "==" : ">"))
|
||||
|
||||
#ifdef WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2026 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/>.
|
||||
*/
|
||||
|
||||
#include "fc_version.h"
|
||||
|
||||
int fc_version(Version *version)
|
||||
{
|
||||
version->major = FC_MAJOR_VERSION;
|
||||
version->minor = FC_MINOR_VERSION;
|
||||
version->patch = FC_PATCH_VERSION;
|
||||
return FC_VERSION_TO_INT1(*version);
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2026 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/>.
|
||||
*/
|
||||
|
||||
//fc_version.h
|
||||
|
||||
#ifndef _FC_VERSION_H
|
||||
#define _FC_VERSION_H
|
||||
|
||||
#include "common_define.h"
|
||||
|
||||
#define FC_MAJOR_VERSION 1
|
||||
#define FC_MINOR_VERSION 0
|
||||
#define FC_PATCH_VERSION 85
|
||||
|
||||
#define FC_VERSION_INT FC_VERSION_TO_INT(FC_MAJOR_VERSION, \
|
||||
FC_MINOR_VERSION, FC_PATCH_VERSION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int fc_version(Version *version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -140,26 +140,27 @@ static int fast_multi_sock_client_do_send(FastMultiSockClient *client,
|
|||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
break;
|
||||
} else if (errno == EINTR) { //should retry
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logDebug("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, ignore interupt signal", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
entry->conn->port);
|
||||
formatted_ip, entry->conn->port);
|
||||
continue;
|
||||
} else {
|
||||
result = errno != 0 ? errno : ECONNRESET;
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"send to server %s:%u fail, "
|
||||
"errno: %d, error info: %s", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
entry->conn->port, result, strerror(result));
|
||||
formatted_ip, entry->conn->port,
|
||||
result, strerror(result));
|
||||
|
||||
break;
|
||||
}
|
||||
} else if (bytes == 0) {
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"send to server %s:%u, sock: %d fail, "
|
||||
"connection disconnected", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
"connection disconnected", __LINE__, formatted_ip,
|
||||
entry->conn->port, entry->conn->sock);
|
||||
|
||||
result = ECONNRESET;
|
||||
|
|
@ -203,10 +204,10 @@ static int fast_multi_sock_client_send_data(FastMultiSockClient *client,
|
|||
if (client->entries[i].conn->sock < 0) {
|
||||
client->entries[i].error_no = ENOTCONN;
|
||||
client->entries[i].done = true;
|
||||
format_ip_address(client->entries[i].conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"NOT connected to %s:%u", __LINE__,
|
||||
format_ip_address(client->entries[i].conn->ip_addr,
|
||||
formatted_ip), client->entries[i].conn->port);
|
||||
formatted_ip, client->entries[i].conn->port);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -256,26 +257,27 @@ static int fast_multi_sock_client_do_recv(FastMultiSockClient *client,
|
|||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
break;
|
||||
} else if (errno == EINTR) { //should retry
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logDebug("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, ignore interupt signal", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
entry->conn->port);
|
||||
formatted_ip, entry->conn->port);
|
||||
continue;
|
||||
} else {
|
||||
result = errno != 0 ? errno : ECONNRESET;
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, recv failed, "
|
||||
"errno: %d, error info: %s", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
entry->conn->port, result, strerror(result));
|
||||
formatted_ip, entry->conn->port,
|
||||
result, strerror(result));
|
||||
|
||||
break;
|
||||
}
|
||||
} else if (bytes == 0) {
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, sock: %d, recv failed, "
|
||||
"connection disconnected", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
"connection disconnected", __LINE__, formatted_ip,
|
||||
entry->conn->port, entry->conn->sock);
|
||||
|
||||
result = ECONNRESET;
|
||||
|
|
@ -290,10 +292,10 @@ static int fast_multi_sock_client_do_recv(FastMultiSockClient *client,
|
|||
entry->recv_stage = fms_stage_recv_body;
|
||||
body_length = client->get_body_length_func(&entry->recv_buffer);
|
||||
if (body_length < 0) {
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, body_length: %d < 0", __LINE__,
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip),
|
||||
entry->conn->port, body_length);
|
||||
formatted_ip, entry->conn->port, body_length);
|
||||
result = EPIPE;
|
||||
break;
|
||||
} else if (body_length == 0) {
|
||||
|
|
@ -374,10 +376,10 @@ static int fast_multi_sock_client_deal_io(FastMultiSockClient *client)
|
|||
&client->ioevent, index);
|
||||
|
||||
if (event & IOEVENT_ERROR) {
|
||||
format_ip_address(entry->conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"server: %s:%u, recv error event: %d, connection "
|
||||
"reset", __LINE__, format_ip_address(entry->conn->
|
||||
ip_addr, formatted_ip), entry->conn->port, event);
|
||||
"server: %s:%u, recv error event: %d, connection reset",
|
||||
__LINE__, formatted_ip, entry->conn->port, event);
|
||||
|
||||
fast_multi_sock_client_finish(client, entry, ECONNRESET);
|
||||
continue;
|
||||
|
|
@ -404,10 +406,10 @@ static int fast_multi_sock_client_deal_io(FastMultiSockClient *client)
|
|||
if (!client->entries[i].done) {
|
||||
fast_multi_sock_client_finish(client,
|
||||
client->entries + i, ETIMEDOUT);
|
||||
format_ip_address(client->entries[i].conn->ip_addr, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"recv from %s:%u timedout", __LINE__,
|
||||
format_ip_address(client->entries[i].conn->ip_addr,
|
||||
formatted_ip), client->entries[i].conn->port);
|
||||
formatted_ip, client->entries[i].conn->port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,11 +259,11 @@ static int fc_server_check_ip_port(FCServerConfig *ctx,
|
|||
id1 = current->server->id;
|
||||
id2 = previous->server->id;
|
||||
}
|
||||
format_ip_address(previous->ip_addr.str, formatted_ip);
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: %s, duplicate ip:port %s:%u, "
|
||||
"the server ids: %d, %d", __LINE__,
|
||||
config_filename, format_ip_address(previous->ip_addr.str,
|
||||
formatted_ip), previous->port, id1, id2);
|
||||
"the server ids: %d, %d", __LINE__, config_filename,
|
||||
formatted_ip, previous->port, id1, id2);
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
|
|
@ -714,14 +714,14 @@ static int check_addresses_duplicate(FCServerConfig *ctx,
|
|||
ppend = group_addr->address_array.addrs + group_addr->address_array.count;
|
||||
for (ppaddr=group_addr->address_array.addrs+1; ppaddr<ppend; ppaddr++) {
|
||||
if (fc_server_cmp_address_ptr(ppaddr, pprevious) == 0) {
|
||||
format_ip_address((*ppaddr)->conn.ip_addr, formatted_ip),
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, group: %.*s, "
|
||||
"duplicate ip and port: %s:%u", __LINE__,
|
||||
config_filename, section_name,
|
||||
group_addr->server_group->group_name.len,
|
||||
group_addr->server_group->group_name.str,
|
||||
format_ip_address((*ppaddr)->conn.ip_addr, formatted_ip),
|
||||
(*ppaddr)->conn.port);
|
||||
formatted_ip, (*ppaddr)->conn.port);
|
||||
return EEXIST;
|
||||
}
|
||||
pprevious = ppaddr;
|
||||
|
|
@ -967,12 +967,12 @@ static int fc_server_set_host(FCServerConfig *ctx, FCServerInfo *server,
|
|||
}
|
||||
|
||||
if (!ctx->share_between_groups && (count > 1 && addr->conn.port > 0)) {
|
||||
format_ip_address(addr->conn.ip_addr, formatted_ip),
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, "
|
||||
"host %s:%u belongs to %d groups",
|
||||
__LINE__, config_filename, section_name,
|
||||
format_ip_address(addr->conn.ip_addr, formatted_ip),
|
||||
addr->conn.port, count);
|
||||
formatted_ip, addr->conn.port, count);
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
|
|
@ -1544,9 +1544,10 @@ static void fc_group_servers_to_string(FCServerConfig *ctx,
|
|||
gaddr->server_group->group_name.str,
|
||||
SERVER_ITEM_HOST_AFFIX_STR);
|
||||
}
|
||||
|
||||
format_ip_address((*addr)->conn.ip_addr, formatted_ip),
|
||||
fast_buffer_append(buffer, " = %s:%u\n",
|
||||
format_ip_address((*addr)->conn.ip_addr, formatted_ip),
|
||||
(*addr)->conn.port);
|
||||
formatted_ip, (*addr)->conn.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1655,9 +1656,9 @@ static void fc_server_log_group_servers(FCGroupAddresses *gaddr)
|
|||
|
||||
end = gaddr->address_array.addrs + gaddr->address_array.count;
|
||||
for (addr=gaddr->address_array.addrs; addr<end; addr++) {
|
||||
format_ip_address((*addr)->conn.ip_addr, formatted_ip),
|
||||
logInfo(" %d. %s:%u", (int)(addr - gaddr->address_array.addrs + 1),
|
||||
format_ip_address((*addr)->conn.ip_addr, formatted_ip),
|
||||
(*addr)->conn.port);
|
||||
formatted_ip, (*addr)->conn.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3353,6 +3353,117 @@ const char *bytes_to_human_str(const int64_t bytes, char *buff)
|
|||
return buff;
|
||||
}
|
||||
|
||||
static int format_number_with_unit(const int n, const char *unit_str,
|
||||
const int unit_len, char *buff, const bool add_leading_space)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (n <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = buff;
|
||||
if (add_leading_space)
|
||||
{
|
||||
*p++ = ' ';
|
||||
}
|
||||
if (n == 1)
|
||||
{
|
||||
*p++ = '1';
|
||||
*p++ = ' ';
|
||||
memcpy(p, unit_str, unit_len);
|
||||
p += unit_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += fc_itoa(n, p);
|
||||
*p++ = ' ';
|
||||
memcpy(p, unit_str, unit_len);
|
||||
p += unit_len;
|
||||
*p++ = 's';
|
||||
}
|
||||
|
||||
return p - buff;
|
||||
}
|
||||
|
||||
static inline int format_number_unit_first(const int n, const char *unit_str,
|
||||
const int unit_len, char *buff)
|
||||
{
|
||||
const bool add_leading_space = false;
|
||||
return format_number_with_unit(n, unit_str,
|
||||
unit_len, buff, add_leading_space);
|
||||
}
|
||||
|
||||
static inline int format_number_unit_next(const int n, const char *unit_str,
|
||||
const int unit_len, char *buff)
|
||||
{
|
||||
const bool add_leading_space = true;
|
||||
return format_number_with_unit(n, unit_str,
|
||||
unit_len, buff, add_leading_space);
|
||||
}
|
||||
|
||||
|
||||
const char *seconds_to_human_str(const int64_t seconds, char *buff)
|
||||
{
|
||||
int64_t remains;
|
||||
int day;
|
||||
int hour;
|
||||
int minute;
|
||||
int second;
|
||||
char *p;
|
||||
|
||||
if (seconds > 0)
|
||||
{
|
||||
remains = seconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
remains = 0;
|
||||
}
|
||||
|
||||
day = remains / (24 * 3600);
|
||||
remains %= (24 * 3600);
|
||||
hour = remains / 3600;
|
||||
remains %= 3600;
|
||||
minute = remains / 60;
|
||||
second = remains % 60;
|
||||
|
||||
p = buff;
|
||||
if (day > 0)
|
||||
{
|
||||
p += format_number_unit_first(day, "day", 3, p);
|
||||
p += format_number_unit_next(hour, "hour", 4, p);
|
||||
p += format_number_unit_next(minute, "minute", 6, p);
|
||||
p += format_number_unit_next(second, "second", 6, p);
|
||||
}
|
||||
else if (hour > 0)
|
||||
{
|
||||
p += format_number_unit_first(hour, "hour", 4, p);
|
||||
p += format_number_unit_next(minute, "minute", 6, p);
|
||||
p += format_number_unit_next(second, "second", 6, p);
|
||||
}
|
||||
else if (minute > 0)
|
||||
{
|
||||
p += format_number_unit_first(minute, "minute", 6, p);
|
||||
p += format_number_unit_next(second, "second", 6, p);
|
||||
}
|
||||
else if (second > 0)
|
||||
{
|
||||
p += format_number_unit_first(second, "second", 6, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '0';
|
||||
*p++ = ' ';
|
||||
memcpy(p, "second", 6);
|
||||
p += 6;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return buff;
|
||||
}
|
||||
|
||||
bool starts_with(const char *str, const char *needle)
|
||||
{
|
||||
int str_len;
|
||||
|
|
@ -4580,3 +4691,27 @@ int fc_safe_rand()
|
|||
return (n & RAND_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
int fc_parse_version(const char *src, Version *version)
|
||||
{
|
||||
const char *p;
|
||||
int numbers[2];
|
||||
int i;
|
||||
|
||||
numbers[0] = numbers[1] = 0;
|
||||
p = src;
|
||||
for (i=0; i<2; i++) {
|
||||
p = strchr(p, '.');
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
numbers[i] = strtol(p, NULL, 10);
|
||||
}
|
||||
|
||||
version->major = strtol(src, NULL, 10);
|
||||
version->minor = numbers[0];
|
||||
version->patch = numbers[1];
|
||||
return FC_VERSION_TO_INT1(*version);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1210,6 +1210,8 @@ static inline const char *double_to_comma_str(const double d,
|
|||
|
||||
const char *bytes_to_human_str(const int64_t bytes, char *buff);
|
||||
|
||||
const char *seconds_to_human_str(const int64_t seconds, char *buff);
|
||||
|
||||
/** if the string starts with the needle string
|
||||
* parameters:
|
||||
* str: the string to detect
|
||||
|
|
@ -1875,6 +1877,8 @@ int fc_safe_rand();
|
|||
#define fc_safe_rand() rand()
|
||||
#endif
|
||||
|
||||
int fc_parse_version(const char *src, Version *version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -706,11 +706,11 @@ static inline bool is_ipv6_addr(const char *ip)
|
|||
return (*ip == ':' || strchr(ip, ':') != NULL); //ipv6
|
||||
}
|
||||
|
||||
static inline const char *format_ip_address(const char *ip, char *buff)
|
||||
static inline int format_ip_address(const char *ip, char *buff)
|
||||
{
|
||||
int ip_len;
|
||||
if (is_ipv6_addr(ip))
|
||||
{
|
||||
int ip_len;
|
||||
char *p;
|
||||
|
||||
ip_len = strlen(ip);
|
||||
|
|
@ -720,17 +720,17 @@ static inline const char *format_ip_address(const char *ip, char *buff)
|
|||
p += ip_len;
|
||||
*p++ = ']';
|
||||
*p = '\0';
|
||||
return p - buff;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buff, ip);
|
||||
ip_len = strlen(ip);
|
||||
memcpy(buff, ip, ip_len + 1);
|
||||
return ip_len;
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
static inline const char *format_ip_port(const char *ip,
|
||||
const int port, char *buff)
|
||||
static inline int format_ip_port(const char *ip, const int port, char *buff)
|
||||
{
|
||||
int ip_len;
|
||||
bool is_ipv6;
|
||||
|
|
@ -753,7 +753,7 @@ static inline const char *format_ip_port(const char *ip,
|
|||
p += fc_itoa(port, p);
|
||||
*p = '\0';
|
||||
|
||||
return buff;
|
||||
return p - buff;
|
||||
}
|
||||
|
||||
void tcp_set_try_again_when_interrupt(const bool value);
|
||||
|
|
|
|||
|
|
@ -960,33 +960,16 @@ int get_sysinfo(struct fast_sysinfo *info)
|
|||
int get_kernel_version(Version *version)
|
||||
{
|
||||
struct utsname name;
|
||||
char *p;
|
||||
int numbers[2];
|
||||
int i;
|
||||
|
||||
if (uname(&name) < 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"call uname fail, errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"call uname fail, errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : EFAULT;
|
||||
}
|
||||
|
||||
numbers[0] = numbers[1] = 0;
|
||||
p = name.release;
|
||||
for (i=0; i<2; i++) {
|
||||
p = strchr(p, '.');
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
numbers[i] = strtol(p, NULL, 10);
|
||||
}
|
||||
|
||||
version->major = strtol(name.release, NULL, 10);
|
||||
version->minor = numbers[0];
|
||||
version->patch = numbers[1];
|
||||
fc_parse_version(name.release, version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue