配置文件键值对读写API函数实现
来源:互联网 发布:淘宝美工一组图多少钱 编辑:程序博客网 时间:2024/05/22 14:27
项目中开发了一种读写配置文件键值的函数(name = value格式),非常实用,特将源码记录如下:
调用接口函数为:
int setcfgx(const char *filpath, const char *nam, char *val) 写入
int getcfgx(const char *filpath, const char *nam, char *val) 读取
Conftool.h文件源码:
/*** Copyright (c) 2012 OCS, Inc.**** Project: GPON-ONT-V2.0** File: conf_toolkit.h** Author: ychxie/xuzhe** Date: 02/08/2012**** Purpose:** provide funcitions for reading and writing configuration files*/#ifndef _CONF_TOOLKIT_H#define _CONF_TOOLKIT_H#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* Macro constant definitions. */#define SVC_PRINTF_BUF_LEN 4096#define SVC_PRINTF_BUF_MARGIN_LEN 32#define BOOL eOsBool/* Type definitions. */typedef enum{ eSVC_LL_MIN, eSVC_LL_MINOR = eSVC_LL_MIN, eSVC_LL_MAJOR, eSVC_LL_CRITICAL, eSVC_LL_NO_LOG, eSVC_LL_MAX, OG_ENUM_MAX} eSvcLogLevel;typedef enum{ FALSE, TRUE} eOsBool;/* Include files. *//* Macro constant definitions. */#define MAX_LINES 4096#define LINE_LEN 128#define NAME_LEN 128/* Type definitions. */typedef enum{ eOP_ERR_SUCCESS = 0, eOP_ERR_ERROR = 1 }eOpCfgError;/* External function declarations. *//* Macro API definitions. *//* Global variable declarations. *//**************************************************************************** Function Name: setcfgx** Purpose:** set single key and value pairs into conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int setcfgx(const char *filpath, const char *nam, char *val);/**************************************************************************** Function Name: getcfgx** Purpose:** get single key from conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int getcfgx(const char *filpath, const char *nam, char *val);/**************************************************************************** Function Name: item_write** Purpose:** set single key and value pairs into conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int item_write(const char *path, const char *key, const char *value);/**************************************************************************** Function Name: item_read** Purpose:** get single key from conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int item_read(const char *path, const char *key, char *value);/**************************************************************************** Function Name: batch_start** Purpose:** Identification of batch operation start.** Parameters:** None** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int batch_start(void);/**************************************************************************** Function Name: batch_stop** Purpose:** Identification of batch operation stop.** Parameters:** None** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int batch_stop(void);#ifdef __cplusplus} /* extern "C" */#endif /* __cplusplus */#endif
Conftool.c文件源码:
/*** Copyright (c) 2012 OCS, Inc.**** Project: GPON-ONT-V2.0** File: conf_toolkig.c** Author: ychxie/xuzhe** Date: 02/08/2012**** Purpose:** implement of conf_toolkit.h.*//* Include files. */#include <stdio.h>#include <sys/time.h>#include <sys/timeb.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <pthread.h>#include <string.h>#include <semaphore.h>#include <errno.h>#include <stdarg.h>#include <ctype.h>#include <libgen.h>#include "conftool.h"#include "debug_log.h"/* Macro constant definitions. */#define S_ISSYMLNK(m) (((m) & S_IFMT) == S_IFLNK) /**analyze if a file is a symbol link*/#define OPEN_FLAG O_CREAT#define OPEN_MODE 00644#define INIT_V 1#define MAX_READ_WRITE_TIMES 3#define ERR_CACHE_MAX (2 * 1024 + 4) // 2k for Error Buffer.#define LINE_CACHE_MAX (5 * 1024 + 4) // 5k for A Line.#define FILE_PATH_MAX (1 * 1024 + 4) // 1k for File/Dir path./* Type definitions. */struct one_line { char *line; char *extern_line; char line_cache[LINE_LEN]; int line_size;};struct file_content { struct one_line lines[MAX_LINES]; int line_cnt;};typedef enum{ eOP_TYPE_GET = 0, eOP_TYPE_SET, eOP_TYPE_BATCH_OP}eOpType;/* Local function declarations. */static void op_log_head(eOpType op_type, const char* filename, const char *name);static void op_log_tail(eOpType op_type, const char* filename, const char *name, const char *val, int op_ret);static void rleadingblank(char *string);static void rrearblank(char *string);static void riprt(char *str);static int readfromfile(char *filename, struct file_content *file);static int writetofile(char *filename, char *strtxt, int strsize);static int setlinecontent(struct file_content *file, int index, char *fmt, const char *name, const char *val);static void initstaticvar(void);static void seterrstr(const char *formatP, ...);/* Macro API definitions. *//* Global variable definitions. */static struct file_content batch_op_file;//symbol of batching operation//if symbol is true,then setcfgx operations not to read file again after first reading the file to RAM ,and not write file//until executint the batch_stop(),then to set already_read false ,and begin to write filestatic BOOL batch_flag = FALSE;//indicate the file has been read into RAM, in batch_read stitution not need to read again//in single_read and call DLL stitution,must set this parameter to false before function return in setcfgx(),otherwise not to read the file in readfromfile() static BOOL already_read = FALSE;static BOOL modify_flag = FALSE;static char batch_tmp_file_name[LINE_LEN] = {0};static char batch_real_file_path[LINE_LEN] = {0};static char error_str[ERR_CACHE_MAX] = {0};static sem_t *sem = NULL;static pthread_mutex_t *ptool_lock = NULL;extern int errno;//the methods below not to release// int item_write(const char *path, const char *key, const char *value);// int item_read(const char *path, const char *key, char *value);int batch_start(void);int batch_stop(void);/**************************************************************************** Function Name: setcfgx** Purpose:** set single key and value pairs into conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int setcfgx(const char *filpath, const char *nam, char *val){ struct file_content tempfile; struct file_content *file = NULL; char tmpline[LINE_CACHE_MAX] = {0}; char tmpname[NAME_LEN] = {0}; char realname[NAME_LEN] = {0}; char *saveptr = NULL, *pname = NULL; int i = 0, ret = 0, file_size = 0, exist = 0, firstchar = 1; char dir_name[FILE_PATH_MAX] = {0}; char file_name[FILE_PATH_MAX] = {0}; char tmp_file_name[FILE_PATH_MAX] = {0}; char real_file_path[FILE_PATH_MAX] = {0}; char *ptoken = NULL; char *file_buffer = NULL; //parameter value in conf has been modified BOOL bModified = FALSE; //DEBUG_LOG("****bModified parameter original value is false\n"); if (NULL == ptool_lock) { ptool_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); if (NULL == ptool_lock) { DEBUG_LOG("malloc pthread_mutex_t failed.\n"); return eOP_ERR_ERROR; } if(pthread_mutex_init(ptool_lock, NULL) != 0) { DEBUG_LOG("Init Mutex agent_conf_lock failed.\n"); free(ptool_lock); ptool_lock = NULL; return eOP_ERR_ERROR; } } pthread_mutex_lock(ptool_lock); op_log_head(eOP_TYPE_SET, filpath, nam); if ((NULL == filpath) || (NULL == nam) || (NULL == val)) { seterrstr("Invalid pointer."); op_log_tail(eOP_TYPE_SET, filpath, nam, val, eOP_ERR_ERROR); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } // file pointer points to static variable if batch flag is true if (batch_flag) { file = &batch_op_file; modify_flag = TRUE; } else { file = &tempfile; memset(file, 0, sizeof(struct file_content)); } strcpy(real_file_path, filpath); ret = readfromfile(real_file_path, file); if (eOP_ERR_SUCCESS != ret) { /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, ret); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } strcpy(dir_name, real_file_path); strcpy(file_name, real_file_path); sprintf(tmp_file_name , "%s/.tmp_%s", dirname(dir_name), basename(file_name)); //DEBUG_LOG("\n****file line count = %d\n",file->line_cnt); for (i = 0; i < file->line_cnt; i++) { //DEBUG_LOG("****enter for cycle\n"); memset(tmpline, 0, sizeof(tmpline)); strcpy(tmpline, file->lines[i].line); if (tmpline[0] == '#')continue; rleadingblank(tmpline); rrearblank(tmpline); if ((saveptr = tmpline) && ((pname = strsep(&saveptr, "=")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); memset(realname, 0, sizeof(realname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); strcat(realname, " "); } strcat(tmpname, pname); strcat(realname, pname); pname = strsep(&saveptr, "="); } //op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_ERROR); rleadingblank(tmpname); rrearblank(tmpname); //compare set value to the original value if (!strcmp(tmpname, nam)) { //DEBUG_LOG("**** parameter names are the same!!\n"); //DEBUG_LOG("****original:tmpname = %s,destination:nam = %s,are the same\n",tmpname,nam); //DEBUG_LOG("****source value = %s,destination:value = %s \n", pname, val); exist = 1;//not new item if(strcmp(pname, val))//value want to be changed { //DEBUG_LOG("**** parameter values are different,bModified is TRUE!!\n"); bModified = TRUE; setlinecontent(file, i, "%s=%s", realname, val); } break; } } else if ((saveptr = tmpline) && ((pname = strsep(&saveptr, "\t")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); memset(realname, 0, sizeof(realname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); strcat(realname, "\t"); } strcat(tmpname, pname); strcat(realname, pname); pname = strsep(&saveptr, "\t"); } rleadingblank(tmpname); rrearblank(tmpname); //compare set value to the original value if (!strcmp(tmpname, nam)) { //DEBUG_LOG("**** parameter names are the same!!\n"); //DEBUG_LOG("****original:tmpname = %s,destination:nam = %s,are the same\n",tmpname,nam); //DEBUG_LOG("****source value = %s,destination:value = %s \n", pname, val); exist = 1;//not new item if(strcmp(pname, val))//value want to be changed { //DEBUG_LOG("**** parameter values are different,bModified is TRUE!!\n"); bModified = TRUE; setlinecontent(file, i, "%s\t%s", realname, val); } break; } } else if ((saveptr = tmpline) && ((pname = strsep(&saveptr, " ")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); memset(realname, 0, sizeof(realname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); strcat(realname, " "); } strcat(tmpname, pname); strcat(realname, pname); pname = strsep(&saveptr, " "); } rleadingblank(tmpname); rrearblank(tmpname); //compare set value to the original value if (!strcmp(tmpname, nam)) { //DEBUG_LOG("**** parameter names are the same!!\n"); //DEBUG_LOG("****original:tmpname = %s,destination:nam = %s,are the same\n",tmpname,nam); //DEBUG_LOG("****source value = %s,destination:value = %s \n", pname, val); exist = 1;//not new item if(strcmp(pname, val))//value want to be changed { //DEBUG_LOG("**** parameter values are different,bModified is TRUE!!\n"); bModified = TRUE; setlinecontent(file, i, "%s %s", realname, val); } break; } } } //DEBUG_LOG("****exist= %d!!\n",exist); // the name is a new item for the cfg file while exist is 0 if (0 == exist) { //DEBUG_LOG("****need increase new line!!\n"); if (MAX_LINES > file->line_cnt) { //DEBUG_LOG("****not exceed the most line number!!\n"); setlinecontent(file, i, "%s=%s", nam, val); file->line_cnt++; //file need to be writed bModified = TRUE; } else { if (!batch_flag) { // clean for (i = 0; i < file->line_cnt; i++) { if (NULL != file->lines[i].extern_line) { free(file->lines[i].extern_line); file->lines[i].extern_line = NULL; file->lines[i].line = NULL; } } /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ } // return error seterrstr("exceed 4096 lines."); op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_ERROR); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } } if (batch_flag) { // do not write file here in batch mode op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_SUCCESS); pthread_mutex_unlock(ptool_lock); strcpy(batch_real_file_path, real_file_path); strcpy(batch_tmp_file_name, tmp_file_name); return eOP_ERR_SUCCESS; } //if parameter value has not been changed in file ,then do not write to file if (!bModified) { //DEBUG_LOG("bModified is false\n"); // clean for (i = 0; i < file->line_cnt; i++) { if (NULL != file->lines[i].extern_line) { free(file->lines[i].extern_line); file->lines[i].extern_line = NULL; file->lines[i].line = NULL; } } // already_read should be cleared after write to file in single mode already_read = FALSE; op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_SUCCESS); //DEBUG_LOG("notice:in %s,the parameter %s value still is %s, not changed,no rewrite file!!! \n",real_file_path,nam,val); pthread_mutex_unlock(ptool_lock); //DEBUG_LOG("\n\n"); return eOP_ERR_SUCCESS; } //DEBUG_LOG("bModified is true\n"); // perpare file_size = 0; for (i = 0; i < file->line_cnt; i++) { file_size += (strlen(file->lines[i].line)+1); } file_buffer = (char*)malloc(file_size+1); if (NULL == file_buffer) { // clean for (i = 0; i < file->line_cnt; i++) { if (NULL != file->lines[i].extern_line) { free(file->lines[i].extern_line); file->lines[i].extern_line = NULL; file->lines[i].line = NULL; } } /* // return error if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ seterrstr("write malloc error."); op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_ERROR); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } memset(file_buffer, 0, file_size+1); ptoken = file_buffer; for (i = 0; i < file->line_cnt; i++) { memcpy(ptoken, file->lines[i].line, strlen(file->lines[i].line)); ptoken += strlen(file->lines[i].line); *(ptoken) = '\n'; if (NULL != file->lines[i].extern_line) { free(file->lines[i].extern_line); file->lines[i].extern_line = NULL; file->lines[i].line = NULL; } ptoken++; } ret = writetofile(tmp_file_name, file_buffer, file_size); if (eOP_ERR_SUCCESS != ret) { free(file_buffer); file_buffer = NULL; /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, ret); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } free(file_buffer); file_buffer = NULL; rename(tmp_file_name, real_file_path); // already_read should be cleared after write to file in single mode already_read = FALSE; /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ op_log_tail(eOP_TYPE_SET, real_file_path, nam, val, eOP_ERR_SUCCESS); pthread_mutex_unlock(ptool_lock); //DEBUG_LOG("\n\n"); return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: getcfgx** Purpose:** get single key from conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int getcfgx(const char *filpath, const char *nam, char *val){ struct file_content tempfile; struct file_content *file = NULL; char tmpline[LINE_CACHE_MAX] = {0}; char tmpname[NAME_LEN] = {0}; char dir_name[FILE_PATH_MAX] = {0}; char file_name[FILE_PATH_MAX] = {0}; char tmp_file_name[FILE_PATH_MAX] = {0}; char real_file_path[FILE_PATH_MAX] = {0}; char *saveptr = NULL, *pname = NULL; int i = 0, ret = 0, firstchar = 1;; if (NULL == ptool_lock) { ptool_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); if (NULL == ptool_lock) { DEBUG_LOG("malloc pthread_mutex_t failed.\n"); return eOP_ERR_ERROR; } if(pthread_mutex_init(ptool_lock, NULL) != 0) { DEBUG_LOG("Init Mutex agent_conf_lock failed.\n"); free(ptool_lock); ptool_lock = NULL; return eOP_ERR_ERROR; } } pthread_mutex_lock(ptool_lock); op_log_head(eOP_TYPE_GET, filpath, nam); if ((NULL == filpath) || (NULL == nam) || (NULL == val)) { seterrstr("Invalid pointer.\n"); op_log_tail(eOP_TYPE_GET, filpath, nam, val, eOP_ERR_ERROR); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } // clean cache *val = 0; // file pointer points to static variable if batch flag is true if (batch_flag) { file = &batch_op_file; } else { file = &tempfile; memset(file, 0, sizeof(struct file_content)); } strcpy(real_file_path, filpath); ret = readfromfile(real_file_path, file); if (eOP_ERR_SUCCESS != ret) { /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ op_log_tail(eOP_TYPE_GET, real_file_path, nam, val, ret); pthread_mutex_unlock(ptool_lock); return eOP_ERR_ERROR; } strcpy(dir_name, real_file_path); strcpy(file_name, real_file_path); sprintf(tmp_file_name , "%s/.tmp_%s", dirname(dir_name), basename(file_name)); /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ for (i = 0; i < file->line_cnt; i++) { memset(tmpline, 0, sizeof(tmpline)); strcpy(tmpline, file->lines[i].line); if (tmpline[0] == '#')continue; rleadingblank(tmpline); rrearblank(tmpline); if ((saveptr = tmpline) && ((pname = strsep(&saveptr, "=")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); } strcat(tmpname, pname); pname = strsep(&saveptr, "="); } rleadingblank(tmpname); rrearblank(tmpname); if (!strcmp(tmpname, nam)) { strcpy(val, pname); riprt(val); rleadingblank(val); rrearblank(val); break; } } else if ((saveptr = tmpline) && ((pname = strsep(&saveptr, "\t")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); } strcat(tmpname, pname); pname = strsep(&saveptr, "\t"); } rleadingblank(tmpname); rrearblank(tmpname); if (!strcmp(tmpname, nam)) { strcpy(val, pname); riprt(val); rleadingblank(val); rrearblank(val); break; } } else if ((saveptr = tmpline) && ((pname = strsep(&saveptr, " ")) != NULL) && (NULL != saveptr)) { memset(tmpname, 0, sizeof(tmpname)); firstchar = 1; while((NULL != pname) && (NULL != saveptr)) { if (firstchar) { firstchar = 0; } else { strcat(tmpname, " "); } strcat(tmpname, pname); pname = strsep(&saveptr, " "); } rleadingblank(tmpname); rrearblank(tmpname); if (!strcmp(tmpname, nam)) { strcpy(val, pname); riprt(val); rleadingblank(val); rrearblank(val); break; } } } if (!batch_flag) { // already_read should be cleared after write to file in single mode already_read = FALSE; // clean for (i = 0; i < file->line_cnt; i++) { if (NULL != file->lines[i].extern_line) { free(file->lines[i].extern_line); file->lines[i].extern_line = NULL; file->lines[i].line = NULL; } } } else { strcpy(batch_real_file_path, real_file_path); strcpy(batch_tmp_file_name, tmp_file_name); } op_log_tail(eOP_TYPE_GET, real_file_path, nam, val, eOP_ERR_SUCCESS); pthread_mutex_unlock(ptool_lock); return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: item_write** Purpose:** set single key and value pairs into conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/// int item_write(const char *path, const char *key, const char *value)// { // return setcfgx(path, key, value);// }/**************************************************************************** Function Name: riprt** Purpose:** get single key from conf.** Parameters:** filpath - full path of configuration file** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/// int item_read(const char *path, const char *key, char *value)// { // return getcfgx(path, key, value);// }/**************************************************************************** Function Name: batch_start** Purpose:** Identification of batch operation start.** Parameters:** None** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int batch_start(void){ batch_flag = TRUE; memset(&batch_op_file, 0, sizeof(batch_op_file)); return 0;}/**************************************************************************** Function Name: batch_stop** Purpose:** Identification of batch operation stop.** Parameters:** None** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/int batch_stop(void){ int i = 0, ret = 0, file_size = 0; char *ptoken = NULL; char *file_buffer = NULL; struct file_content *file = &batch_op_file; if (modify_flag) { // perpare file_size = 0; for (i = 0; i < file->line_cnt; i++) { file_size += (strlen(file->lines[i].line)+1); } file_buffer = (char*)malloc(file_size+1); if (NULL == file_buffer) { //op_log(eOP_TYPE_BATCH_OP, -1, real_file_path, nam, val); seterrstr("write malloc error.\n"); /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ // clear initstaticvar(); return eOP_ERR_ERROR; } memset(file_buffer, 0, file_size+1); ptoken = file_buffer; for (i = 0; i < file->line_cnt; i++) { memcpy(ptoken, file->lines[i].line, strlen(file->lines[i].line)); ptoken += strlen(file->lines[i].line); *(ptoken) = '\n'; ptoken++; } if (eOP_ERR_SUCCESS != writetofile(batch_tmp_file_name, file_buffer, file_size)) { free(file_buffer); file_buffer = NULL; //op_log(eOP_TYPE_BATCH_OP, -1, real_file_path, nam, val); /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ // clear initstaticvar(); return eOP_ERR_ERROR; } free(file_buffer); file_buffer = NULL; rename(batch_tmp_file_name, batch_real_file_path); //op_log(eOP_TYPE_BATCH_OP, 0, real_file_path, nam, val); } /* if (NULL != sem) { sem_post(sem); sem_close(sem); sem = NULL; } */ // clear initstaticvar(); return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: op_log_head** Purpose:** log operations .** Parameters:** op_ret - result of operation (0 = success: oter = failed)** filename - name of the file to be operated** nam - key** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/void op_log_head(eOpType op_type, const char* filename, const char *name){ struct timeval tv; struct tm *pm = NULL; char szopname[NAME_LEN] = {0}; char szdest[FILE_PATH_MAX] = {0}; int ret = 0; // initialize cache memset(szopname, 0, NAME_LEN); memset(szdest, 0, FILE_PATH_MAX); // decide op name switch(op_type) { case eOP_TYPE_GET: if (batch_flag) { sprintf(szopname, "BATCH GET"); } else { sprintf(szopname, "GET"); } break; case eOP_TYPE_SET: if (batch_flag) { sprintf(szopname, "BATCH SET"); } else { sprintf(szopname, "SET"); } break; case eOP_TYPE_BATCH_OP: sprintf(szopname, "BATCH OPTION"); break; default: break; } ret = readlink("/proc/self/exe", szdest, FILE_PATH_MAX); ret = gettimeofday(&tv, NULL); if (0 == ret) { pm = localtime((time_t *)&tv.tv_sec);#if 0 DEBUG_LOG("[%04d-%02d-%02d %02d:%02d:%02d:%03d] [%s] [%s] [%s] [%s = ", pm->tm_year + 1900, pm->tm_mon + 1, pm->tm_mday, pm->tm_hour, pm->tm_min, pm->tm_sec, tv.tv_usec/1000, szdest, filename, szopname, name );#endif }}/**************************************************************************** Function Name: op_log_tail** Purpose:** log operations .** Parameters:** op_ret - result of operation (0 = success: oter = failed)** filename - name of the file to be operated** nam - key** val - value** Return:** 0 - success** other - failure (refer to eOpCfgError for details)** Notes:** None.**************************************************************************/void op_log_tail(eOpType op_type, const char* filename, const char *name, const char *val, int op_ret){ if ((NULL == filename) || (NULL == name) || (NULL == val)) { DEBUG_LOG("\n<<Invalid pointer.>>\n"); return; } if (eOP_ERR_SUCCESS == op_ret) { //DEBUG_LOG("%s]: %s\n", val, "SUCCESS"); } else { DEBUG_LOG("%s]: %s\n Error : %s\n", val, "FAIL", error_str); }}/**************************************************************************** Function Name: rleadingblank** Purpose:** remove leading blank .** Parameters:** string - string to handle** Return:** void** Notes:** None.**************************************************************************/void rleadingblank(char *string){ char tmpstr[LINE_CACHE_MAX] = {0}; int npos = 0; if (NULL == string) { return; } if (0 == strlen(string)) { return; } strcpy(tmpstr, string); memset(string, 0, strlen(string)); while(isblank(tmpstr[npos])) { npos++; } strcpy(string, tmpstr+npos);}/**************************************************************************** Function Name: rrearblank** Purpose:** remove rear blank .** Parameters:** string - string to handle** Return:** void** Notes:** None.**************************************************************************/void rrearblank(char *string){ int len = 0; if (NULL == string) { return; } len = strlen(string); if (0 == len) { return; } while (isblank(string[len-1])) { string[len-1] = '\0'; len--; }}/**************************************************************************** Function Name: riprt** Purpose:** remove '\r' and '\n' .** Parameters:** string - string to handle** Return:** void** Notes:** None.**************************************************************************/void riprt(char *str){ int len = 0, i = 0; if (str == NULL) { return; } len = strlen(str); if (len == 0) { return; } for (i = 0; i < len; i++) { if (str[i] == '\r' || str[i] == '\n') { str[i] = '\0'; } }}/**************************************************************************** Function Name: readfromfile** Purpose:** read from file ,and translate symbo link to real path** Parameters:** filename - file path** file - point of file_content** Return:** int** Notes:** None.**************************************************************************/int readfromfile(char *filename, struct file_content *file){ int fd = 0; int ret = 0, file_size = 0, line_size = 0, newbuffer_size = 0; char *file_buffer = NULL; char *ptoken = NULL; char *saveptr = NULL; int i = 0, readtimes = 0; char szpath[FILE_PATH_MAX] = {0}; struct stat buf; if ((NULL == filename) || (NULL == file)) { seterrstr("Invalid pointer."); return eOP_ERR_ERROR; } ret = lstat(filename, &buf); if (0 != ret) { seterrstr("file error. lstat %s = %d, err = %s.", filename, ret, strerror(errno)); return eOP_ERR_ERROR; } if (S_ISSYMLNK(buf.st_mode)) { readlink(filename, szpath, FILE_PATH_MAX); memset(filename, 0, FILE_PATH_MAX); strcpy(filename, szpath); } if (already_read) { // return 0 if the file is read into memory in batch mode return eOP_ERR_SUCCESS; } /* //add lock sem = sem_open((char*)basename(filename), OPEN_FLAG, OPEN_MODE, INIT_V); if (NULL != sem) { sem_wait(sem); } else { seterrstr("open sem failed %s, err = %s.", filename, strerror(errno)); return eOP_ERR_ERROR; } */ ret = stat(filename, &buf); if (0 != ret) { seterrstr("file error. stat %s = %d, err = %s.", filename, ret, strerror(errno)); return eOP_ERR_ERROR; } file_size = buf.st_size; fd = open(filename, O_RDONLY|O_NONBLOCK); if (-1 == fd) { seterrstr("read open file %s failed, err = %s.", filename, strerror(errno)); return eOP_ERR_ERROR; } file_buffer = (char*)malloc(file_size+1); if (NULL == file_buffer) { seterrstr("read malloc error."); close(fd); return eOP_ERR_ERROR; } memset(file_buffer, 0, file_size+1); do { ret = read(fd, file_buffer, file_size); readtimes++; if (-1 == ret) { usleep(100); } }while((-1 == ret) && (readtimes < MAX_READ_WRITE_TIMES)); if (readtimes >= MAX_READ_WRITE_TIMES) { free(file_buffer); file_buffer = NULL; close(fd); seterrstr("try to read file %s exceed max times, err = %s.", filename, strerror(errno)); return eOP_ERR_ERROR; } close(fd); saveptr = file_buffer; ptoken = strsep( &saveptr, "\n"); while( (NULL != ptoken)) { /* While there are tokens in "string" */ if (NULL != saveptr) { line_size = saveptr-ptoken; } else { line_size = strlen(ptoken); } if (LINE_LEN <= line_size) { newbuffer_size = (sizeof(char))*line_size+1; file->lines[i].extern_line = (char*)malloc(newbuffer_size); if (NULL == file->lines[i].extern_line) { free(file_buffer); file_buffer = NULL; seterrstr("read malloc extern_line error, size = %d.", newbuffer_size); return eOP_ERR_ERROR; } memset(file->lines[i].extern_line, 0, newbuffer_size); memcpy(file->lines[i].extern_line, ptoken, line_size); file->lines[i].line = file->lines[i].extern_line; file->lines[i].line_size = newbuffer_size; } else { memcpy(file->lines[i].line_cache, ptoken, line_size); file->lines[i].line = file->lines[i].line_cache; file->lines[i].line_size = LINE_LEN; } riprt(file->lines[i].line); /* Get next token: */ if (NULL != saveptr) { ptoken = strsep(&saveptr, "\n"); } else { //solution: can't get the value when line ends without '/r' if (0 != strlen(file->lines[i].line)) { i++; } break; } i++; if (MAX_LINES <= i) { break; } } free(file_buffer); file_buffer = NULL; file->line_cnt = i; already_read = TRUE; return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: writetofile** Purpose:** write into file ** Parameters:** filename - file path** strtxt - buffer of text to write** strsize - buffer size** Return:** int** Notes:** None.**************************************************************************/int writetofile(char *filename, char *strtxt, int strsize){ int fd = 0, ret = 0, writetimes = 0; if ((NULL == filename) || (NULL == strtxt)) { seterrstr("Invalid pointer."); return eOP_ERR_ERROR; } fd = open(filename, O_WRONLY|O_CREAT|O_NONBLOCK, S_IRWXU|S_IRWXG|S_IRWXO); if (-1 == fd) { seterrstr("write open file %s failed, err = %s.", filename, strerror(errno)); return eOP_ERR_ERROR; } //add write lock do { ret = write(fd, strtxt, strsize); writetimes++; if (-1 == ret) { usleep(100); } }while((-1 == ret) && (writetimes < MAX_READ_WRITE_TIMES)); if (writetimes >= MAX_READ_WRITE_TIMES) { close(fd); seterrstr("try to write file %s exceed max times, err = %s.", filename, strerror(errno)); return eOP_ERR_ERROR; } //fsync(fd); close(fd); return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: setlinecontent** Purpose:** write into file ** Parameters:** filename - file path** strtxt - buffer of text to write** strsize - buffer size** Return:** int** Notes:** None.*************************************************************************/int setlinecontent(struct file_content *file, int index, char *fmt, const char *name, const char *val){ int line_size = 0; int new_buffersize = 0; char *buffer_exceed = NULL; if ((NULL == file) || (NULL == fmt) || (NULL == name) || (NULL == val)) { seterrstr("Invalid pointer."); return eOP_ERR_ERROR; } line_size = strlen(name)+strlen(val)+1; if (file->lines[index].line_size <= line_size) { new_buffersize = (sizeof(char))*line_size + 1; buffer_exceed = (char*)malloc(new_buffersize); if (NULL == buffer_exceed) { seterrstr("set line content error for invalid pointer."); return eOP_ERR_ERROR; } memset(buffer_exceed, 0, new_buffersize); sprintf(buffer_exceed, fmt, name, val); if (NULL != file->lines[index].extern_line) { free(file->lines[index].extern_line); file->lines[index].extern_line = NULL; file->lines[index].line = NULL; } file->lines[index].extern_line = buffer_exceed; file->lines[index].line = file->lines[index].extern_line; file->lines[index].line_size = new_buffersize; } else { memset(file->lines[index].line, 0, file->lines[index].line_size); sprintf(file->lines[index].line, fmt, name, val); } return eOP_ERR_SUCCESS;}/**************************************************************************** Function Name: initstaticvar** Purpose:** write into file ** Parameters:** None** Return:** void** Notes:** None.*************************************************************************/void initstaticvar(void){ int i = 0; // clean for (i = 0; i < batch_op_file.line_cnt; i++) { if (NULL != batch_op_file.lines[i].extern_line) { free(batch_op_file.lines[i].extern_line); batch_op_file.lines[i].extern_line = NULL; batch_op_file.lines[i].line = NULL; } } memset(&batch_op_file, 0, sizeof(batch_op_file)); memset(batch_real_file_path, 0, sizeof(batch_real_file_path)); memset(batch_tmp_file_name, 0, sizeof(batch_tmp_file_name)); batch_flag = FALSE; already_read = FALSE; modify_flag = FALSE;}/**************************************************************************** Function Name: seterrstr** Purpose:** set error string to static variable ** Parameters:** formatP - string of format** ... - variable stack** Return:** void** Notes:** None.*************************************************************************/void seterrstr(const char *formatP, ...){ memset(error_str, 0, sizeof(error_str)); va_list argList; va_start(argList, formatP); vsnprintf(error_str, sizeof(error_str), formatP, argList); va_end(argList);}
0 0
- 配置文件键值对读写API函数实现
- c++ 实现对配置文件的读写 根据windows API 函数简单改写
- c++ stl实现对配置文件的读写 根据windows API WritePrivateProfileString,GetPrivateProfileString简单改写
- Python--键值对配置文件处理
- javascript 实现键值对。
- C++实现键值对
- API 读写配置文件
- 调用API函数读写配置文件
- 纯API函数实现串口读写。
- 获得配置文件键值对application.properties
- JS实现键值对功能
- C函数读写配置文件
- C# API读写ini配置文件
- API来实现对INI文件的读写
- JAVA Excel API 实现对Excel表格的读写更新
- ini配置文件读写实现
- API函数读写文件
- 文件读写API函数
- mobiscroll.custom-2.17.0.min.js 破解版
- Application
- Your build settings specify a provisioning profile with the UUID “”, however, no such provisioning p
- JSP常用Form标签
- 短视频应用应该如何打造技术架构?
- 配置文件键值对读写API函数实现
- App Store审核指南:ResearchKit和Apple Pay有新规
- Linux入门(四)系统管理
- excel单元格内强制换行
- mysql运维2--基本操作
- linux编译
- UVA10305Ordering Tasks(拓补排序)
- ntpdate及ntpq命令使用方法
- mybatis学习笔记(8)-动态sql