/*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. Based
upon the return value, the program will print the
details of the process that was matched (a match
being a 1). These details are obtained by opening
a file stream to the processes stat file, and then
scanning through the details using the fscanf function.
This program is in essence a mimmick of the ps command.
Fortunately there are only a few things to iron out now
here goes.
1. When the processes and their details get printed out
they are not in order. I can''t say i really understand
why this doesn''t happen as this line in main should
perform this task
count = scandir(path,&direntp,NULL,alphasort);
2. The tty that the process uses seems to report back
incorecctly, infact the only one it seems to recognise
is pts/0 it never once mentions ttyx (where x is a number),
Also some of the time it comes back as null, where as if
I use the ps command normally those that are null in my version
have value in the proper version. Here are the lines associated
with tty.
t_name = ttyname(tty);
if(t_name == NULL)
t_name = "?";
3. Getting the run time of the process is not always succesful,
for example it sometimes gives the correct output such as
00:00:05 (Hours,Minutes,Seconds). But some of the time it prints
garble instead eg.
h-@h-@
This seems to suggest to me that the variable time hasn''t been assigned
any value and is just printing non-sense, where as it can be clearly
seen that this is not the case.
time = getTime(stime);
4. I suppose while i''m asking stuff I might aswell ask for ideas on implementing
"ps -A" which basically prints all the current processes, not those just
belonging to the user. Would this involve use of the getuid method??
*/
#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>
#define SIZE 256
/*prototypes*/
int matchDetails(char* filename,char* path);
void printDetails(char* filename,char* path);
char* getTime(int clockticks);
char *get_regerror(int errcode,regex_t *compiled);
int main(void){
int result,count,index; /*Set Conditions*/
char path[] = "/proc"; /*Path to the proc directory*/
struct dirent **direntp; /*Directory entry pointer*/
struct stat sbuf; /*Holds information about files*/
if (stat(path,&sbuf) != -1){
if(S_ISDIR(sbuf.st_mode)){
count = scandir(path,&direntp,NULL,alphasort);
if(count){
char temp[FILENAME_MAX];
printf("PID TTY TIME CMD\n");
for(index=0; indexd_name,temp);
if(result > 0) /*If directory name was matched*/
printDetails(direntp[index]->d_name,temp);
free(direntp[index]);
}
}else{
fprintf(stderr,"Can''t open %s\n",path);
exit(EXIT_FAILURE);
}
}else
return;
}else{
fprintf(stderr,"Can''t stat %s\n",path);
return;
}
return EXIT_SUCCESS;
}
/*Used to find process directories*/
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 | REG_NOSUB)) != 0){
result = get_regerror(regstat,&re);
fprintf(stderr,"%s\n",result);
return(0);
}
if((status = regexec(&re,filename,(size_t) 0,NULL,0)) != 0)
return(0);
regfree(&re);
}else
return(0);
}else{
fprintf(stderr,"Can''t stat %s\n",filename);
return(0);
}
return(1);
}
/*Print the process information*/
void printDetails(char* filename,char* path){
FILE *f_name;
int pid,tty,stime;
char pname[FILENAME_MAX];
char* t_name;
char* time;
/*Format the path*/
strcat(path,"/");
strcat(path,"stat");
if((f_name = fopen(path,"r")) != NULL){
fscanf(f_name,"%d %s %*c %*d %*d %*d %d %*d
%*u %*u %*u %*u %*u %*d %d",&pid,&pname,&tty,&stime);
t_name = ttyname(tty);
time = getTime(stime);
if(t_name == NULL)
t_name = "?";
printf("%-9d%-12s%-6s %s\n",pid,t_name,time,pname);
fclose(f_name);
}else
fprintf(stderr,"Can''t open %s\n",path);
}
/*Format jiffies into hours,minutes,seconds*/
char* getTime(int clockticks){
float jiffies,result;
int min,hr,seconds;
char* time = (char*)malloc(SIZE);
jiffies = 0.01f;
result = jiffies * clockticks;
seconds = result;
min = seconds/60;
hr = min/60;
seconds %= 60; /*MOD it into 0-59*/
min %= 60; /*MOD it into 0-59*/
if(hr < 10 && min < 10 && seconds < 10)
sprintf(time,"0%d:0%d:0%d",hr,min,seconds);
else if(hr < 10 && min < 10)
sprintf(time,"0%d:0%d:%d",hr,min,seconds);
else if(hr < 10 && seconds < 10)
sprintf(time,"0%d:%d:0%d",hr,min,seconds);
else if(min < 10 && seconds < 10)
sprintf(time,"%d:0%d:0%d",hr,min,seconds);
else if(hr < 10)
sprintf(time,"0%d:%d:%d",hr,min,seconds);
else if(min < 10)
sprintf(time,"%d:0%d:%d",hr,min,seconds);
else if(seconds < 10)
sprintf(time,"%d:%d:0%d",hr,min,seconds);
else
sprintf(time,"%d:%d:%d",hr,min,seconds);
free(time);
return time;
}
/*Used to store regex errors*/
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;
}
Some loose ends
Please read the following long commented piece of code.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement