📄 z_func.c
字号:
/******************** 分离路径中的文件名称 ********************/char *z_fnonly(char *path){ static char *p = NULL; p = strrchr(path, '/'); if( p ) p++; else p = path; return(p);}/************** 分解路径和名称 **************/int z_sep_path(char *file, char *path, char *name){ int n; char *str = NULL; str = strrchr(file, '/'); if( str ) { strcpy(name, str + 1); n = strlen(file) - strlen(name) - 1; strncpy(path, file, n); path[n+1] = 0; } else { strcpy(name, file); path[0] = 0; } return(0);}/************************************ 函数描述:通过系统 ps 命令获取进程号 约束 :进程名称长度上限100字节 ************************************/pid_t z_get_pid(char *proc){ FILE *pp; pid_t pid, me; char cmd[128], buf[128], comm[128]; memset(cmd, 0, sizeof(cmd)); sprintf(cmd, "ps -eo comm,pid|grep ^%.100s", proc); if( (pp = popen(cmd, "r")) != NULL ) { me = getpid(); while( ! feof(pp) ) { pid = 0; memset(buf, 0, sizeof(buf)); memset(comm, 0, sizeof(comm)); if( fgets(buf, 128, pp) == NULL ) break; sscanf(buf, "%100s%d", comm, &pid); if( (strcmp(comm, proc) == 0) && (pid != me) ) { pclose(pp); return(pid); } } pclose(pp); } return(-1);}/********************************** 函数描述:通过文件锁实现同步 返回值 :-1 文件打开失败 -2 文件已被其它进程锁定 >0 锁定成功,文件描述符 **********************************/int z_psw_lock(char *file, pid_t *pid){ int fd = 0; pid_t pidw; umask(000); fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if( fd < 0 ) return(-1); if( lockf(fd, F_TLOCK, 0) < 0 ) { if( pid ) read(fd, pid, sizeof(pid_t)); close(fd); return(-2); } /* 清空文件数据 */ ftruncate(fd, 0); /* 记录进程ID */ pidw = getpid(); write(fd, &pidw, sizeof(pid_t)); /* 刷新 */ fsync(fd); return(fd);}/********************************* 函数描述:停止文件中记录的进程 返回值 : 0 成功 -1 读取进程号失败 -2 文件记录的进程号为0 -3 进程已终止 *********************************/int z_pid_stop(char *file){ pid_t pid = 0; if( z_psw_lock(file, &pid) == -2 ) { if( pid ) { kill(pid, SIGTERM); truncate(file, 0); return(0); } else return(-2); } return(-3);}/************ 构造常驻进程 ************/int z_daemon(void){ pid_t childpid = 0; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; sigaction(SIGQUIT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); if( getppid() == 1 ) return(0); childpid = fork(); if( childpid < 0 ) exit(0); else if( childpid > 0 ) exit(0);/* the first child process */ if( setpgrp() == (-1) ) exit(0); childpid = fork(); if( childpid < 0 ) exit(0); else if( childpid > 0 ) exit(0);/* the second child process */ return(0);}/************ 内存数据显示 ************/int z_memshow(char *buf, int len){ int i, g, k; char *pa, *ph, dt[20]; memset(dt, 0, sizeof(dt)); z_get_dt(dt, 19, "l", 0); printf("系统时间: %s\n", dt); printf("报文长度: %d\n", len); printf("====================================报文开始====================================\n"); printf("位 置 -0--1--2--3--4--5--6--7--8--9--a--b--c--d--e--f -----ASCII 值-----\n"); ph = buf; pa = buf; for( i = 0; len > 0; i++, len -= 16 ) { printf("M(%6.6d) =< ", i * 16); g = len > 16 ? 16 : len; for(k = 0; k < g; k++) printf("%02x ", *ph++); for(k = g; k < 16; k++) printf(" "); printf("> "); for(k = 0; k < g; k++, pa++) printf("%c", isprint(*pa) ? *pa : '.'); printf("\n"); } printf("====================================报文结束====================================\n"); return(0);}/********************************** 转换,每个字节用两位16进制数值表示 **********************************/int z_s2hex(unsigned char *t, unsigned char *s, int l){ int i; unsigned char c; for( i = 0; i < l; i++ ) { c = (s[i] >> 4) & 0x0F; t[2*i] = (c <= 0x9 && c >= 0x0) ? c + 0x30 : c + 0x37; c = s[i] & 0x0F; t[2*i + 1] = (c <= 0x9 && c >= 0x0) ? c + 0x30 : c + 0x37; } t[2*i] = 0; return(0);}/********************************* 转换,两位16进制数值用1个字节表示 *********************************/int z_2hexs(unsigned char *t, unsigned char *s){ unsigned char c; while( *s && *(s + 1) ) { if( *s >= 0x41 && *s <= 0x46 ) c = *s - 0x37; else if( *s >= 0x61 && *s <= 0x66 ) c = *s - 0x57; else if( *s >= 0x30 && *s <= 0x39 ) c = *s - 0x30; else return(-1); *t = (c << 4) & 0xF0; if( *(s + 1) >= 0x41 && *(s + 1) <= 0x46 ) c = *(s + 1) - 0x37; else if( *(s + 1) >= 0x61 && *(s + 1) <= 0x66 ) c = *(s + 1) - 0x57; else if( *(s + 1) >= 0x30 && *(s + 1) <= 0x39 ) c = *(s + 1) - 0x30; else return(-1); *t |= (c & 0x0F); s += 2; t ++; } *t = 0; return(0);}/****************************************** 函数描述:UCS2编码,拆分字符串,不截断汉字 入口参数:char *s 待拆分字符串 int *l2 当前分组的实际字节数 int unit 分组最大长度,偶数 ******************************************/int z_split_ucs2(char *s, int *l2, int unit){ int l; l = (*l2) = 0; if( unit % 2 ) unit--; while( *s ) { if( l == unit ) break; if( isascii(*s) ) l += 2; else l += 1; s ++; (*l2) ++; } return(*l2);}/******** 示例代码 ********//* p = msg; while( *p ) { z_split_ucs2(p, &i, 140); strncpy(t, p, i); p += i; }*//****************** 确保串尾汉字的完整 ******************/int z_chi_nohalf(char *s, int l){ int i = 0; while( *s && (l-- > 0) ) if( ! isascii( *(s++) ) ) i++; if( i % 2 ) *(s - 1) = 0; *s = 0; return(0);}/************ 打开日志文件 ************/int z_logopen(char *file){ if( file == NULL || *file == 0 ) return(-1); if( LOG.fp == NULL && (LOG.fp = fopen(file, "a") ) == NULL) { printf("错误:打开日志文件 '%s' 失败.\n", file); return (-1); } return(0);}/************ 关闭日志文件 ************/int z_logclose(void){ if( LOG.fp ) { fclose(LOG.fp); LOG.fp = NULL; } return(0);}/**************** 设定日志文件大小 ****************/unsigned int z_logsetsz(unsigned int size){ unsigned int i; i = LOG.msize; LOG.msize = size; return(i);}/********************** 记录日志信息,参数可变 **********************/int z_logv(char *file, char *fmt, ...){ int b = 0; va_list ap; struct stat st; char tmval[16], logbak[260]; if( file == NULL || *file == 0 ) return(-1); if( strlen(file) >= sizeof(LOG.path) ) return(-1); if( strcmp(LOG.path, file) ) { /* 日志文件更换 */ z_logclose(); memset(LOG.path, 0, sizeof(LOG.path)); strcpy(LOG.path, file); b |= 0x1; } /* 查看日志文件大小 */ memset(&st, 0, sizeof(st)); if( stat(LOG.path, &st) < 0 ) { /* 假定文件不存在 */ z_logclose(); b |= 0x2; } else if( LOG.msize && st.st_size > LOG.msize ) { z_logclose(); b |= 0x4; sprintf(logbak, "%s.bak", LOG.path); if( rename(LOG.path, logbak) < 0 ) return(-2); } /* 打开日志文件 */ if( z_logopen(LOG.path) < 0 ) return(-3); z_get_dt(tmval, 19, "l", 0); tmval[19] = 0; fprintf(LOG.fp, "[%s]: [", tmval + 5); va_start(ap, fmt); vfprintf(LOG.fp, fmt, ap); va_end(ap); fprintf(LOG.fp, "]\n"); fflush(LOG.fp); return(b);}/**************************** 函数说明:验证ip地址的合法性 返回值 :4 合法 <>4 非法 ****************************/int z_valid_ip(char *ip){ int n, num, b, z; char s[8]; if( ip == NULL || *ip == 0 ) return(0); num = 0; do { memset(s, 0, sizeof(s)); b = z_get_fieldv(&ip, s, &n, 3, "."); if( s[0] == 0 ) break; if( ! z_adigit(s) ) break; z = atoi(s); if( z < 0 || z > 255 ) break; num ++; } while( b ); return(num);}/************************************** 函数功能:检测字符串是否匹配指定的模式 入口参数:char *n 待匹配字符串 char *f 模式 模式说明: '*' -- 匹配零或多个字符 '?' -- 匹配一个字符 '%' -- 匹配一个字母 '#' -- 匹配一个数字 返回值 :1 匹配 0 不匹配 **************************************/int z_smatch(char *n, char *f){ int xf = 0; /*星号标志*/ for( ; *f; f++ ) { switch( *f ) { case '*': xf = 1; break; case '?': if( *n == 0 ) return(0); n++; break; case '%': if( xf == 1 ) { while ( *n ) { /* 前移字符串指针 */ if( isalpha( *n ) ) break; n++; } if( *n == 0 ) return(0); } else if( ! isalpha( *n ) ) return(0); n++; break; case '#': if( xf == 1 ) { while ( *n ) { if( isdigit( *n ) ) break; n++; } if( *n == 0 ) return(0); } else if( ! isdigit( *n ) ) return(0); n++; break; default: if( xf == 1 ) { while ( *n ) { if( *n == *f ) break; n++; } if( *n == 0 ) return(0); } else if( *n != *f ) return(0); n++; break; } } if( xf == 0 && *n ) /*模式不包含'*',且多余表达式*/ return(0); return(1);}/******** 网络检测 ********//* ping -c 10 -l 9 %s*//************** 再连接共享内存 **************//*int z_reconn_shm(){ int b = 0; ** 连接 ** if( 内存指针 == NULL ) { printf("连接 ...\n"); if( 连接() < 0 ) { printf("没有启动\n"); return(-1); } } ** 查看内存状态 ** if( 内存状态失效 ) { b = 1; printf("内存已失效, 重新连接 ...\n"); 断连(); ** 重新连接 ** if( 连接() < 0 ) { printf("已终止\n"); return(-2); } } return(b);}*//******************************** 在连续内存区域中顺序循环两次查找 ********************************//*int z_twi_reskey(char *port){ static int i = 0; KEY = -1; for( ; i < N; i++ ) if( FOUND ) { KEY; i++; break; } if( KEY < 0 ) for( i = 0; i < N; i++ ) if( FOUND ) { KEY; i++; break; } return(KEY);}*//************************************ 启动单个进程;可使用文件锁锁定临界区 ************************************//*int z_start_single(char *name){ no = -1; for( i = 0; i < N; i++ ) { if( 空闲 ) { no = i; break; } if( 名称匹配 ) { if( 停止 || 启动失败 ) { no = i; ** 定位原空间 ** break; } printf("\n错误:%s 已启动\n\n", name); return(0); } else { if( 可重用 ) { if( no < 0 ) no = i; continue; } } } 状态=启动中;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -