Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any Idea Why My C Code Can't Read from /proc?

Tags:

c

linux

unix

I have been able to write a program that can read any text files... except the ones found in /proc. Any file that I try to read from /proc shows up empty.

But whenever I type

cat /proc/cpuinfo

on terminal, I am presented with my CPU info.

I can also see the file when I open it with a text editor, such as gedit or leafpad.

So it seems that /proc files are indeed text files, but my C program is having a hard time reading them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char* readFileString( char* loc ) {
        char *fileDat;
        FILE * pFile;
        long lsize;

        pFile = fopen( loc, "r" );

        // Grab the file size.
        fseek(pFile, 0L, SEEK_END);
        lsize = ftell( pFile );
        fseek(pFile, 0L, SEEK_SET);

        fileDat = calloc( lsize + 1, sizeof(char) );

        fread( fileDat, 1, lsize, pFile );

        return fileDat;
}

int main( void ) {
        char *cpuInfo;

        cpuInfo = readFileString( "/proc/cpuinfo" );

        printf( "%s\n", cpuInfo );

        return 0;
}

Any idea why?

like image 548
Sal Rahman Avatar asked Jan 24 '12 18:01

Sal Rahman


3 Answers

The files from /proc have a size of 0 byte because they are generated on the fly by the kernel.

See here for more information on proc filesystem:

http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/proc.html

like image 187
ouah Avatar answered Oct 20 '22 02:10

ouah


Most /proc/ textual files are intended to be read sequentially by a classical loop like

FILE *f = fopen("/proc/cpuinfo", "r");
size_t sz = 0;
char * lin = 0;
do {
   ssize_t lsz = getline (&lin, &sz, f);
   if (lsz<0) break;
   handle_line_of_size (lin, lsz);
} while (!feof (f));
fclose (f);

seeking don't work on them. A bit like for pipes.

like image 21
Basile Starynkevitch Avatar answered Oct 20 '22 00:10

Basile Starynkevitch


If you want to know the size of a file, stat(2) is the way to go. But for what you're doing, either allocate a very large buffer (RAM is cheap and this is a one-shot program) you fread() into after you fopen() it, or learn about realloc(3) and use that in your file-reading loop. As ouah said, the files in /proc are special.

For general-purpose use, and especially for strings, calloc() is a waste of cpu cycles, as setting the 0th char of the returned allocation area to '\0' is sufficient to make it an empty string, regardless of the data following that first byte.

like image 41
Andrew Beals Avatar answered Oct 20 '22 01:10

Andrew Beals