[ale] Accessing /proc from C

Benjamin Dixon beatle at arches.uga.edu
Sat Dec 28 23:37:11 EST 2002



This is nice. I looked around, and seeing how the proc system is accessed,
as you indicate, its only really useful if you feel like messing with
ASCII. I was just looking for data from the arp cache and ended up just
doing some socket manipulation and ioctl to get the info I needed.
Probably more portable anyway.

Thanks,

Ben

On 28 Dec 2002, cfowler wrote:

> 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
> 

Today's Random Quote--------------------------------------

 43rd Law of Computing: Anything that can go wr .signature:
Segmentation violation -- Core dumped

-----------------------------------------------------------

_______________________________________________
Ale mailing list
Ale at ale.org
http://www.ale.org/mailman/listinfo/ale






More information about the Ale mailing list