Unix/Linux Processes [Archive] - C Board

PDA

View Full Version : Unix/Linux Processes


pdstatha
03-27-2002, 03:23 AM
//This program will scan through a directory
//if it finds subdirectories within it, it will
//check if the name of the directory is a digit
//if it is it will return 1, otherwise a 0. And
//then print the returned result.

//There is a method behind my madness although it might
//not be apparent. The reason i'm doing this is because
//i'm trying implement the "ps" unix/linux command. I have
//discovered that there is a process filesystem mounted to both
//of these platforms, under "/proc" each process has it's own
//subdirectory within this directory e.g "/proc/xxx" where xxx
//is the the process id. Within these directories are several files
//containting information about the process, one these files is
//called stat which is apparently what ps uses to get it's information.

//Whats confusing me at the moment is that my book tells me that there
//is a data structure called task_struct which represents a process, and
//is a also a doubly linked list "The structures themselves are allocated
//dynamically,when a new process is created,and kept on a doubly linked list.
//But to avoid overhead of frequently searching this list,the structures are
//also maintained as a hash list."

//My theory behind the following code is that if I can identify what directories
//within "/proc" represent a process then I can add a structure to the hash list.
//Is this a sound theory? Or have I got the wrong end of the stick completly. If
//so could someone please give a simple example of how I could implement such a procedure

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <regex.h>
#include <unistd.h>

//prototypes
int matchDetails(char* filename,char* path);
char *get_regerror(int errcode,regex_t *compiled);

int main(void){
int result,count,index;
char path[] = "/cygdrive/c/PROGRA~1/RATIONAL/RATION~1/NUTCROOT/usr/temp";
struct dirent **direntp;
struct stat sbuf;

if (stat(path,&sbuf) != -1){
if(S_ISDIR(sbuf.st_mode)){
count = scandir(path,&direntp,NULL,alphasort);
if(count){
char temp[FILENAME_MAX];
for(index=0; index<count; ++index){
strcpy(temp,path);
result = matchDetails(direntp[index]->d_name,temp);
printf("%d\n",result);
free(direntp[index]);
}
}else{
fprintf(stderr,"Can't open %s\n",path);
exit(EXIT_FAILURE);
}
}else{
fprintf(stderr,"Can't find process directories\n");
return;
}
}else{
fprintf(stderr,"Can't stat %s\n",path);
return;
}
return EXIT_SUCCESS;
}

int matchDetails(char* filename,char* path){
int status,regstat;
char *pattern = "[0-9]"; //Match digits only
char *result;
struct stat sbuf;

//Get the full pathname
strcat(path,"/");
strcat(path,filename);

//Stat the full path name
if(stat(path,&sbuf) != -1){
if(S_ISDIR(sbuf.st_mode)){ //If a directory
regex_t re;
if((regstat = regcomp(&re,pattern,REG_EXTENDED)) != 0){
result = get_regerror(regstat,&re);
fprintf(stderr,"%s\n",result);
return(0);
}
if((status = regexec(&re,filename,re.re_nsub,NULL,0)) != 0){
result = get_regerror(status,&re);
fprintf(stderr,"%s\n",result);
return(0);
}
regfree(&re);
}else{
fprintf(stderr,"Can't find process directories\n");
return;
}
}else{
fprintf(stderr,"Can't stat %s\n",filename);
return;
}
return(1);

}

char *get_regerror(int errcode,regex_t *compiled){
size_t length = regerror(errcode,compiled,NULL,0);
char *buffer = malloc(length);
(void) regerror(errcode,compiled,buffer,length);
return buffer;
}

*bump*

I managed to find some sample code on using procfs.h , it says that this should work for all *ix platforms. Unfortunately it doesn't.


#include <stdio.h>
#include <fcntl.h>
#include <sys/procfs.h>
#include <unistd.h>

int main(){

int ifd;
char sFilename[16];
struct prpsinfo tPrpsinfo; //ERROR: storage size of tPrpsinfo unknown

(void)ioctl(ifd,PIOCPSINFO,&tPrpsinfo); //ERROR: PIOCPSINFO unknown
(void)fprintf(stderr,"processname = %s\n",tPrpsinfo.pr_fname);
(void)sprintf(sFilename,"/proc/%d",getpid());
ifd = open(sFilename,O_RDONLY);
(void)fprintf(stderr,"file = %s, file descriptor = %d\n",
sFilename,ifd);
(void)close(ifd);

return(0);

}

Deckard
03-27-2002, 06:51 AM
Originally posted by pdstatha
//My theory behind the following code is that if I can identify what directories
//within "/proc" represent a process then I can add a structure to the hash list.
//Is this a sound theory? Or have I got the wrong end of the stick completly. If
//so could someone please give a simple example of how I could implement such a procedureIn Linux, each process has a subdirectory within /proc, named after the PID:
Example:
[ /home/jdeckard ]
jdeckard@sora> ps -fu jdeckard
UID PID PPID C STIME TTY TIME CMD
jdeckard 5069 5068 0 06:36 pts/0 00:00:00 -bash
jdeckard 5090 5069 9 06:40 pts/0 00:00:00 ps -fu jdeckard

[ /home/jdeckard ]
jdeckard@sora> cat /proc/5069/status
Name: bash
State: S (sleeping)
Pid: 5069
PPid: 5068
TracerPid: 0
Uid: 1007 1007 1007 1007
Gid: 100 100 100 100
FDSize: 256
Groups: 100
VmSize: 2004 kB
VmLck: 0 kB
VmRSS: 1208 kB
VmData: 164 kB
VmStk: 16 kB
VmExe: 476 kB
VmLib: 1268 kB
SigPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 8000000000384004
SigCgt: 000000004b813efb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
There are a number of other 'files' you can access in a process' directory that yield further information. Unfortunately, POSIX does not define how processes should be managed, and not all *nix operating systems will have a /proc directory (HP/UX 11.00, for example, does not have a /proc directory).

I hope that helps.

alex
03-27-2002, 12:56 PM
Hi!

You can probably take a peak at the original ps (GPL). It's available at http://sourceforge.net/projects/procps/. The source also includes a tiny version of the ps command.

The example code of sys/procfs.h doesn't work on linux. Anyhow, this headerfile is not related to the "/proc" directory. On a "real" Unix, the code works if the line "ifd = open(sFilename,O_RDONLY);" is put before the ioctl call.

alex