Thread: Some loose ends

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    87

    Some loose ends

    Please read the following long commented piece of code.

    Code:
    /*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; index<count; ++index){
               strcpy(temp,path);
               result = matchDetails(direntp[index]->d_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;
    }
    PuterPaul.co.uk - Portfolio site

  2. #2
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669

    Thumbs up

    The first error is in your library definiton. Library "dirent.h" does not exist, but the library "direct.h" does exist.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    Thats not an error, dirent.h does exist but only in unix/linux
    PuterPaul.co.uk - Portfolio site

  4. #4
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669

    Wink

    Ups, sorry about that .
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    *bump* Comeon you linux gurus
    PuterPaul.co.uk - Portfolio site

  6. #6
    Registered User
    Join Date
    Feb 2002
    Posts
    31

    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);
    in function getTime().

    could it be that you free time before you return it?
    Last edited by CtrlAltKick; 03-31-2002 at 02:10 PM.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    Nah i tried commenting that out, still get the same problem.

    EDIT: Hmm could have sworn I tried that, obviously not, neway that seemed to work, oh well 1 down 3 to go
    Last edited by pdstatha; 03-31-2002 at 02:14 PM.
    PuterPaul.co.uk - Portfolio site

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    I know why it isn't sorting now, it's cos it sorts alpabetically not numerically. I've looked up the man pages for the qsort, which is defined as the following.

    Code:
    void qsort(void *base, size_t nmemb, size_t size,
                 int (*compar)(const void *, const void *));
    I can't really make much sense of this, how would I implement this function for my purposes??
    PuterPaul.co.uk - Portfolio site

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to cap the gluCylinder() ends
    By ting in forum Game Programming
    Replies: 1
    Last Post: 06-02-2008, 05:03 PM
  2. instance of a class disappearing after function ends
    By combatdave in forum C++ Programming
    Replies: 14
    Last Post: 10-20-2006, 08:59 AM
  3. Socket abruptly closes after function ends
    By Sfpiano in forum Networking/Device Communication
    Replies: 1
    Last Post: 08-08-2005, 04:49 PM
  4. Laptop Lid Loose (Toshiba Tecra)
    By moonwalker in forum Tech Board
    Replies: 0
    Last Post: 07-14-2003, 09:11 PM
  5. Why do i loose my first character?
    By ss3x in forum C++ Programming
    Replies: 4
    Last Post: 04-10-2002, 03:04 PM