Get hardware information from /proc filesytem in Linux

后端 未结 3 1580
既然无缘
既然无缘 2021-01-14 07:35

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 fr

3条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-14 08:24

    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 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    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 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    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 
    #include 
    #include 
    
    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.

提交回复
热议问题