I use execv
to run lshw
command to get the CPU, disk, and memory in C code. But I would like to search another solution to get these information from /proc
or any other existed data. Have any suggestion? Here is my code:
char *params[9] = {"/usr/bin/lshw", "-short", "-c", "disk",
"-c", "memory", "-c", "processor", 0}; //cmd params filled
execv(params[0], params);
Linux command: $ sudo lshw -short -c disk -c processor -c memory
$ sudo lshw -short -c disk -c processor -c memory
H/W path Device Class Description
======================================================
/0/0 memory 64KiB BIOS
/0/22 memory 16GiB System Memory
/0/22/0 memory DIMM Synchronous [empty]
/0/22/1 memory DIMM Synchronous [empty]
/0/22/2 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/22/3 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/2a memory 256KiB L1 cache
/0/2b memory 1MiB L2 cache
/0/2c memory 6MiB L3 cache
/0/2d processor Intel(R) Xeon(R) CPU D-1521 @ 2.40GHz
/0/1/0.0.0 /dev/sda disk 16GB SATADOM-SH 3IE3
/0/2/0.0.0 /dev/sdb disk 120GB Patriot Blaze
I have two questions:
- Where to find a guide to parse the files in
/proc
to get these hardware information? - Do I need to trace the source code of
lshw
to find what doeslshw
do?
Edit:
Chapter 7 of Advanced Linux Programming is a guide to parse the /proc
filesystem.
The best way to get hardware information is using sysconf() and sysctl*() functions (Mac OS X, freebsd, openbsd), and sysconf() and sysinfo() on Linux.
Parsing /proc/* is slower and more involved than calling sysinfo( ) or sysconf( )
Below is a small example giving you some information about processor and memory on Mac OS X:
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
char *p = NULL;
size_t len;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("hw.model", p, &len, NULL, 0);
printf("%s\n", p);
/* CTL_MACHDEP variables are architecture dependent so doesn't work
for every one */
sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("machdep.cpu.brand_string", p, &len, NULL, 0);
printf("%s\n", p);
int64_t mem;
len = sizeof(mem);
sysctlbyname("hw.memsize", &mem, &len, NULL, 0);
printf("System Memory : %lld\n", mem);
return (0);
}
You have to read man 3 sysctl, or on Linux man 2 sysconf and man 2 sysinfo.
An interesting link : http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system#Other
You can calculate the CPU load and usage retrieving some sysctl variables, and doing the math by yourself (you can find the formulas to do it on google).
But where to find the physical DIMM information as the report from $ sudo lshw -short -c memory ?
You can execute your command inside your C program to save it as a string like :
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
char *strjoin(char *s1, char *s2, int n)
{
int i = strlen(s2);
int j = 0;
if ((s2 = realloc(s2, (i + n + 1))) == NULL)
perror(0);
while (j < n && s1[j])
{
s2[i] = s1[j];
i++;
j++;
}
s2[i] = 0;
return (s2);
}
int main()
{
pid_t father;
char buf[500] = {0};
char *str;
char *argv[5] = {"/usr/bin/lshw", "-short", "-c", "memory"};
int fd[2];
int ret;
if (pipe(fd) == -1)
{
perror(NULL);
return -1;
}
father = fork();
if (father == 0)
{
close(fd[1]);
while ((ret = read(fd[0], buf, 500)))
{
str = strjoin(buf, str, ret);
}
close(fd[0]);
}
else
{
close(fd[0]);
execv(argv[0], argv);
close(fd[1]);
wait(0);
}
wait(0);
printf("%s", str);
return 0;
}
(I don't check all the function's return in this code, not to have a too long one, but you should do it in your program).
Here is an example of parsing the file /proc/meminfo to save in a double array 2 strings I want, and then printing them out :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *f;
char *line = NULL;
ssize_t read;
size_t len = 0;
char **info;
int i = 0;
info = malloc(3 * sizeof(char*));
f = fopen("/proc/meminfo", "r");
while ((read = getline(&line, &len, f)) != -1)
{
if (strstr(line, "MemTotal") != NULL)
info[i] = strdup(line);
else if (strstr(line, "MemFree") != NULL)
info[i] = strdup(line);
i++;
}
info[i] = 0;
fclose(f);
i = 0;
while (info[i])
{
printf("%s", info[i]);
free (info[i]);
i++;
}
free (info);
return 0;
}
If you want to save more strings, malloc more space in the double array info, and add them with else if inside the read loop. You can do that with any files from /proc/ to get the information you need.
By reading the source code of lshw
, I found that lshw
read raw data from /sys/class/dmi/
. Because lshw
is written in CPP that I am not familiar with, there is a question Where does dmidecode get the SMBIOS table? mentioned that dmidecode.c
read raw data from /sys/class/dmi
that's same as lshw
does.
Here are the definitions in dmidecode.c
#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
I extract code from dmidecode.c
to get the CPU and memory information, and use lsscsi
to get disk information.
Thanks for your help.
1: To get the CPU load use this command :
top -bn1 | grep load
this will give you output like :
top - 12:26:20 up 35 min, 2 users, load average: 0.02, 0.01, 0.00
now parse the load average from above string. 2: To get memory info use this command :
free -m
This will give you:
total used free shared buffers cached
Mem: 15926 308 15617 6 15 122
-/+ buffers/cache: 171 15755
Swap: 0 0 0
To get the disk info , use this :
df -H /home/test
This will give you :
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 102G 5.4G 91G 6% /
Now from above result parse the content what you want.
来源:https://stackoverflow.com/questions/44382885/get-hardware-information-from-proc-filesytem-in-linux