223 lines
6.9 KiB
C
223 lines
6.9 KiB
C
|
/*****************************************************************************
|
|||
|
* @copyright 1997-2050, . POWER SUPPLY CO., LTD.
|
|||
|
* @file kit_core.c
|
|||
|
* @brief xx功能
|
|||
|
* @author Gary
|
|||
|
* @date 2024-09-21
|
|||
|
* @remark
|
|||
|
*****************************************************************************/
|
|||
|
|
|||
|
#include <errno.h>
|
|||
|
#include "kit_core.h"
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
* @brief 通过管道执行shell命令 (使用 system)
|
|||
|
* @param[in] cmd:shell命令
|
|||
|
* @param[in] buffer:读取执行结果
|
|||
|
* @param[in] buffer_size:读取执行结果长度
|
|||
|
* @return 1-执行错误 0-执行成功
|
|||
|
*****************************************************************************/
|
|||
|
int kit_popen_exec(const char *cmd, char* buffer, size_t buffer_size)
|
|||
|
{
|
|||
|
#if IF_RUNIN_VM == RUNIN_VM // 虚拟机环境,返回默认值
|
|||
|
return 0;
|
|||
|
#endif
|
|||
|
FILE *fp = popen(cmd, "r");
|
|||
|
if (fp == NULL)
|
|||
|
{
|
|||
|
KITLOG(LOG_KIT_EN, ERROR_EN, "popen failed");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
// 读取执行结果
|
|||
|
size_t bytes_read = fread(buffer, 1, buffer_size - 1, fp); // 最多只读取buffer_size比特数据
|
|||
|
if (ferror(fp))
|
|||
|
{
|
|||
|
KITLOG(LOG_KIT_EN, ERROR_EN, "文件读取失败: %s\n", strerror(errno));
|
|||
|
pclose(fp);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
buffer[bytes_read] = '\0'; // 字符串要以NULL结束
|
|||
|
|
|||
|
int status = pclose(fp);
|
|||
|
if (status == -1)
|
|||
|
{
|
|||
|
KITLOG(LOG_KIT_EN, ERROR_EN, "pclose failed");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
|
|||
|
{
|
|||
|
KITLOG(LOG_KIT_EN, ERROR_EN, "CMD命令 '%s' 执行失败,失败的编号: %d\n", cmd, WEXITSTATUS(status));
|
|||
|
return 1;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
* @brief 获取网络连接状态
|
|||
|
* @param[in] cmd:shell命令
|
|||
|
* @return 1-网络不可连接 0-网络连接成功
|
|||
|
*****************************************************************************/
|
|||
|
int kit_get_net_status(void)
|
|||
|
{
|
|||
|
FILE *fp = popen("ping -c 1 -W 1 www.baidu.com > /dev/null 2>&1", "r");
|
|||
|
|
|||
|
if (fp == NULL)
|
|||
|
{
|
|||
|
perror("popen failed");
|
|||
|
return 1; // 如果popen失败,认为网络不可用
|
|||
|
}
|
|||
|
|
|||
|
// 等待命令执行完毕,获取返回状态
|
|||
|
int status = pclose(fp);
|
|||
|
|
|||
|
// WEXITSTATUS获取子进程返回的状态码,ping成功返回0
|
|||
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
|||
|
{
|
|||
|
return 0; // 网络可用
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return 1; // 网络不可用
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
* @brief 获取EMS的SN号
|
|||
|
* @param[in] serial:返回SN号
|
|||
|
* @return 1-执行错误 0-执行成功
|
|||
|
*****************************************************************************/
|
|||
|
int kit_get_ems_sn(char serial[128])
|
|||
|
{
|
|||
|
char buffer[3000]; // 接收执行返回值
|
|||
|
char buffer_copy[3000]; // 用于 strtok 的副本
|
|||
|
char *line = NULL;
|
|||
|
char *serialStart = NULL;
|
|||
|
|
|||
|
// 使用 kit_popen_exec 执行"cat /proc/cpuinfo"
|
|||
|
if (kit_popen_exec("cat /proc/cpuinfo", buffer, sizeof(buffer)) != 0)
|
|||
|
{
|
|||
|
KITLOG(LOG_DRIVER_EN, ERROR_EN, "cat /proc/cpuinfo 命令执行失败\n");
|
|||
|
return 1; // 返回错误
|
|||
|
}
|
|||
|
|
|||
|
strcpy(buffer_copy, buffer); // 复制 buffer 到 buffer_copy
|
|||
|
// 使用 strtok 按行分割 buffer_copy
|
|||
|
line = strtok(buffer_copy, "\n");
|
|||
|
while (line != NULL)
|
|||
|
{
|
|||
|
// 查找 "Serial" 字符串
|
|||
|
if ((serialStart = strstr(line, "Serial")) != NULL)
|
|||
|
{
|
|||
|
// 提取序列号
|
|||
|
serialStart += strlen("Serial\t\t: "); // 跳过 "Serial : "
|
|||
|
char *endOfSerial = strchr(serialStart, '\n'); // 查找换行符
|
|||
|
if (endOfSerial != NULL)
|
|||
|
{
|
|||
|
*endOfSerial = '\0'; // 将换行符替换为字符串终止符
|
|||
|
}
|
|||
|
strncpy(serial, serialStart, 127); // 复制序列号到 serial,限制长度防止溢出
|
|||
|
serial[127] = '\0'; // 添加字符串终止符
|
|||
|
return 0; // 返回成功
|
|||
|
}
|
|||
|
line = strtok(NULL, "\n");
|
|||
|
}
|
|||
|
|
|||
|
KITLOG(LOG_DRIVER_EN, ERROR_EN, "未找到序列号\n");
|
|||
|
return 1; // 返回错误
|
|||
|
}
|
|||
|
|
|||
|
// 获取系统 CPU 时间
|
|||
|
void getSysCpuTime(cpu_time_t *time)
|
|||
|
{
|
|||
|
FILE *file = fopen("/proc/stat", "r");
|
|||
|
if (file == NULL)
|
|||
|
{
|
|||
|
perror("Error opening /proc/stat");
|
|||
|
exit(EXIT_FAILURE);
|
|||
|
}
|
|||
|
fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu %lu",
|
|||
|
&time->user, &time->nice, &time->system, &time->idle,
|
|||
|
&time->iowait, &time->irq, &time->softirq, &time->steal);
|
|||
|
fclose(file);
|
|||
|
}
|
|||
|
|
|||
|
// 获取指定进程的 CPU 时间
|
|||
|
void getProCpuTime(cpu_time_t *time, pid_t pid)
|
|||
|
{
|
|||
|
char filename[32];
|
|||
|
sprintf(filename, "/proc/%d/stat", pid);
|
|||
|
FILE *file = fopen(filename, "r");
|
|||
|
if (file == NULL)
|
|||
|
{
|
|||
|
perror("Error opening process stat file");
|
|||
|
exit(EXIT_FAILURE);
|
|||
|
}
|
|||
|
uint64_t utime, stime;
|
|||
|
fscanf(file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &utime, &stime);
|
|||
|
time->user = utime;
|
|||
|
time->system = stime;
|
|||
|
fclose(file);
|
|||
|
}
|
|||
|
|
|||
|
// 获取内存信息的函数
|
|||
|
void getMemInfo(memory_info_t *info)
|
|||
|
{
|
|||
|
FILE *file = fopen("/proc/meminfo", "r"); // 打开 /proc/meminfo 文件
|
|||
|
if (file == NULL)
|
|||
|
{
|
|||
|
perror("Error opening /proc/meminfo"); // 如果打开失败,打印错误信息并退出
|
|||
|
return;
|
|||
|
}
|
|||
|
// 从文件中读取内存信息,包括总内存、空闲内存、可用内存、缓冲区内存和缓存内存
|
|||
|
fscanf(file, "MemTotal: %lu kB\nMemFree: %lu kB\nMemAvailable: %lu kB\nBuffers: %lu kB\nCached: %lu kB",
|
|||
|
&info->total, &info->free, &info->available, &info->buffers, &info->cached);
|
|||
|
fclose(file); // 关闭文件
|
|||
|
}
|
|||
|
|
|||
|
// 函数用于提取指定关键字后的整数值
|
|||
|
int extractValue(const char *line, const char *keyword)
|
|||
|
{
|
|||
|
char *pos = strstr(line, keyword);
|
|||
|
if (pos == NULL)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
pos += strlen(keyword);
|
|||
|
int value;
|
|||
|
sscanf(pos, "%d", &value);
|
|||
|
return value;
|
|||
|
}
|
|||
|
|
|||
|
// 计算当前进程内存占用
|
|||
|
double calculateProcMemUsage(memory_info_t info, pid_t pid)
|
|||
|
{
|
|||
|
char filename[32];
|
|||
|
sprintf(filename, "/proc/%d/status", pid);
|
|||
|
FILE *file = fopen(filename, "r");
|
|||
|
if (file == NULL)
|
|||
|
{
|
|||
|
// perror("Error opening process status file");
|
|||
|
return 0.0;
|
|||
|
}
|
|||
|
char line[256];
|
|||
|
int rss = -1;
|
|||
|
while (fgets(line, sizeof(line), file))
|
|||
|
{
|
|||
|
if (rss == -1 && strstr(line, "VmRSS") != NULL)
|
|||
|
{
|
|||
|
rss = extractValue(line, "VmRSS:");
|
|||
|
}
|
|||
|
}
|
|||
|
fclose(file);
|
|||
|
if (rss != -1)
|
|||
|
{
|
|||
|
// printf("Current process resident memory size: %d kB\n", rss);
|
|||
|
return (double)rss / info.total * 100.0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// printf("Failed to get process memory usage.\n");
|
|||
|
return 0.0;
|
|||
|
}
|
|||
|
}
|