[ale] Accessing /proc from C
cfowler
cfowler at outpostsentinel.com
Sat Dec 28 23:10:49 EST 2002
Here is where a discussion may get started. Some people like binary
some like ASCII. I prefer Binary data whenever possible because it
allows for fewer cycles to go to parsing. However it is not as portable
as ASCII. So in /proc all that data is ASCII. You must parse them out
like you would any file but the code is not that much of a killer. Use
buffered i/o fgets() and friends to read the data in. Then use a
sscanf() function to parse the data into char arrays (strings). You can
eaisly display the data in that file.
I *heavily* modified the Comtrol Rocket Port driver for Linux. It now
includes instant reporting in /proc/rocketport/ of that status of each
port. I have a program that needs to retrieve DCD state. Now I can
eaisly get DCD stat by using an ioctl() on a open file but this would
assert DTR and RTS on that port. This is not the behavior that I
wanted. So I needed a interface (/proc is a good one) that would allow
me to get data about each individual port without open()ing that port.
So that is why I had to do some modifications. But, below is some code
that eaisly parses the status of the port from this:
[cfowler at badass]# pwd
/proc/rocketport
[cfowler at badass]# cat 1
Port: 1
OUT: 0 IN: 7698
AOUT: 0 AIN: 1089
Refcount: 1
LastCharIn: 40839886
DTR: 1
DCD: 1
CTS: 0
RTS: 1
DSR: 0
DCDChanges: 3
[cfowler at badass]#
/*
* get_dcd_state() - Return a pointer to a (static) string containing
the
* status of the DCD pin of the specified port
(0-based)
*
* Essentially a stripped down version of
* snmp-agent/outpostUtils.c:getTermios()
*/
static char *
get_dcd_state(int port)
{
char pName[64] ;
FILE *fp ;
char *status = "unknown" ;
snprintf(pName, sizeof(pName), "/proc/rocketport/%d", port) ;
/*
* Read the /proc entry, looking for a line that says:
* "DCD: x", where x = 0 or 1. Failsafe to "unknown"
* if we can't find anything useful or even open the
* file.
*/
if ((fp = fopen(pName, "r")) != NULL) {
char buf[100] ;
int i ;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (sscanf(buf, "DCD: %d\n", &i) == 1) {
if (i == 0) {
status = "false" ;
} else if (i == 1) {
status = "true" ;
}
break ;
}
}
fclose(fp) ;
}
return(status) ;
}
So see, it really is not that hard to parse the data from that file.
You'll need to do this for all files in proc.
Here is code that parses the data from /proc/<pid>/status
static void parseproc(char *S, proc_t *P)
{
char *tmp;
memset(P->cmd, 0, sizeof(P->cmd));
P->pid = P->mem = P->data = 0;
sscanf(S, "Name:\t%15c", P->cmd);
tmp = strchr(P->cmd, '\n');
if (tmp)
*tmp= '\0';
tmp = strstr(S, "State:");
if(tmp)
sscanf(tmp, "State:\t%c\n", &P->state);
tmp = strstr(S,"Pid:");
if (tmp)
sscanf(tmp, "Pid:\t%d\n", &P->pid);
tmp = strstr(S,"PPid:");
if (tmp)
sscanf(tmp, "PPid:\t%d\n", &P->ppid);
tmp = strstr(S, "VmRSS:");
if (tmp)
sscanf(tmp, "VmRSS:\t%d\n", &P->mem);
tmp = strstr(S, "VmData:");
if(tmp)
sscanf(tmp, "VmData:\r%d\n", &P->data);
tmp = strstr(S, "Uid:");
if(tmp)
sscanf(tmp, "Uid:\r%d\n", &P->ruid);
}
On Sat, 2002-12-28 at 21:09, Benjamin Dixon wrote:
>
> Does anyone know if its possible to access information stored in the /proc
> filesystem from C without resorting to reading the file and parsing the
> strings? Any references or links? I've found plenty of stuff on how to
> write modules that use /proc but nothing on how to interact with it other
> than from the command line.
>
> Ben
>
>
> _______________________________________________
> Ale mailing list
> Ale at ale.org
> http://www.ale.org/mailman/listinfo/ale
_______________________________________________
Ale mailing list
Ale at ale.org
http://www.ale.org/mailman/listinfo/ale
More information about the Ale
mailing list