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;
|
||
}
|
||
} |