1

I am trying to create a program monitor system parameter like: CPU usage percent, Ram usage percent and send a warning log when the percent is over 80%. My solution when reading CPU percent is using mpstat or cat the /proc/stat like this:

unsigned int get_system_value(char *command)
{
    FILE *fp;
    char value_string[1024];
    fflush(fp);
    fp = popen(command, "r"); /* The issue is here  */
    if (fp == NULL) {
        printf("Failed to check command system \n" );
        return -1;
    }

    while (fgets(value_string, sizeof(value_string), fp) != NULL);
    unsigned int value = atoi(value_string);
    return value;
    pclose(fp);
}

void *get_sys_stat(void* arg)
{
    float cpu_percent = 0;
    int cpu_high_flag = 0;
    int cpu_too_high_flag = 0;

    while(1) {
//      cpu_percent = get_system_value("mpstat | awk '$12 ~ /[0-9.]+/ { print 100 - $12"" }'"); // using mpstat
        cpu_percent = get_system_value("grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'"); // using cat /proc/stat
        if (cpu_percent > 80) {
            trap_cpu_high(ar_general_config[0].general_id); // send warning log
        }
    }
}

And the issue is when i run program after a few minutes i will can not open the file, the pointer fp is NULL. I guest that Linux prevent a program open a file too many times or maybe can not run a bash command too many times. Can you help me explain why ? and a solution for this case.

oguz ismail
  • 1
  • 16
  • 47
  • 69
Thanh Nguyen
  • 45
  • 1
  • 7
  • Why are you using `popen` to call a command to read the file? Just open the file directly and read that. – Cheatah Oct 16 '21 at 06:06
  • Because i need the return value from the shell command. I refer from this post: https://stackoverflow.com/questions/3736210/how-to-execute-a-shell-script-from-c-in-linux – Thanh Nguyen Oct 16 '21 at 06:12
  • I am saying you don't need a command. – Cheatah Oct 16 '21 at 06:32
  • Actually it not only read parameter in file, it needs some command when i need to get percent of ram, CPU temperature too, so i use the `popen()` – Thanh Nguyen Oct 16 '21 at 10:14
  • C is a programming language that you can use to read files and perform calculations. If you are going to rely heavily other commands, you might as well write a bash script. – Cheatah Oct 16 '21 at 11:33

1 Answers1

2
    return value;
    pclose(fp);

and so pclose(fp) is never called. Thus you leak resources (FILE stream, file descriptor, child process, etc) on every call, and eventually you run out so popen fails.

If you pclose properly there is no limit on how many times you can call popen.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Thanks for helpful answer i have fixed it. I am using this program to monitor my computer and it will run 24/24 for long time. Is there any potential issue if i get RAM, CPU percent by command like this ? I see there are some library in C support getting system parameter like `sys/sysinfo.h`, but i am not sure which way is more stable for 24/24 running computer. – Thanh Nguyen Oct 16 '21 at 10:19
  • @ThanhNguyen: I don't know what you mean by "more stable", and I'm not really in a position to analyze your code for all possible bugs. If this code works, it will keep working indefinitely. Presumably though you want a `sleep()` somewhere in your loop, or else your CPU usage will be 100% because of this program alone. – Nate Eldredge Oct 16 '21 at 15:31
  • @ThanhNguyen: Note that calling `grep` and `awk` every time is certainly less efficient than getting the values by reading and parsing `/proc/stat` directly in your C program (e.g. with `fscanf`), so that wastes some CPU time as well. Whether that's significant, and whether that efficiency is worth the time of writing more code, is something only you can decide. – Nate Eldredge Oct 16 '21 at 15:32