Skip to content
Advertisement

Reading Long Values From Sysfs Path With Escape Characters

I am using C file IO to read value from a sysfs interface in linux. Path and sample value of the register is as follows:

cat /sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj
56039694184

Code: Added after intel-rapl to take into account unknown escape sequence

#define FILE_SIZE 512

static FILE *fp;
char filename[FILE_SIZE];

char TEMP[FILE_SIZE];
int FILE, READ;
long int POWER;

FILE = open("/sys/class/powercap/intel-rapl/intel-rapl\:0/energy_uj", O_RDONLY);
READ = read(FILE, TEMP, sizeof(TEMP));
POWER= strtod(TEMP,NULL);
close(FILE);

sprintf(filename,"test.csv");
fp  = fopen(filename,"a+");
fprintf(fp,"n");
fprintf(fp, "%ld", POWER);

The code compiles without any error, but in the output file I am getting value as 0. Is this due to how I am taking into account the escape sequence?

Thanks.

Advertisement

Answer

Since the sysfs files, while ‘files’ in one sense, may also be nodes, etc.. and not traditional text files, it is often best to let the shell interact with the sysfs files and simply read the needed values from a pipe following a call to popen using the shell command, e.g.

#include <stdio.h>

int main (void) {

    long unsigned energy_uj = 0;
    FILE *proc = popen (
        "cat /sys/class/powercap/intel-rapl/intel-rapl\:0/energy_uj", "r");

    if (!proc) {  /* validate pipe open for reading */
        fprintf (stderr, "error: process open failed.n");
        return 1;
    }

    if (fscanf (proc, "%lu", &energy_uj) == 1)  /* read/validate value */
        printf ("energy_uj: %lun", energy_uj);

    pclose (proc);

    return 0;
}

Example Use/Output

$ ./bin/sysfs_energy_uj
energy_uj: 29378726782

That’s not to say you cannot read from the sysfs files directly, but if you have any problems, then reading from a pipe is fine. For the energy_uj value, it can be read directly without issue:

#include <stdio.h>

int main (void) {

    long unsigned energy_uj = 0;
    FILE *fp = fopen (
        "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj", "r");

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed.n");
        return 1;
    }

    if (fscanf (fp, "%lu", &energy_uj) == 1)  /* read/validate value */
        printf ("energy_uj: %lun", energy_uj);

    fclose (fp);

    return 0;
}

Example Use/Output

$ ./bin/sysfs_energy_uj_file
energy_uj: 33636394660
Advertisement