Thread: Unix/Linux Processes

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

    Angry Unix/Linux Processes

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

    Code:
      
    #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);
    
    }
    PuterPaul.co.uk - Portfolio site

  2. #2
    The Artful Lurker Deckard's Avatar
    Join Date
    Jan 2002
    Posts
    633

    Re: Unix/Linux Processes

    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 procedure
    In 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.
    Jason Deckard

  3. #3
    Registered User alex's Avatar
    Join Date
    Sep 2001
    Posts
    132
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 34
    Last Post: 05-27-2009, 12:26 PM
  2. Processes not dying
    By Elkvis in forum Linux Programming
    Replies: 12
    Last Post: 04-23-2008, 08:59 AM
  3. binary tree of processes
    By gregulator in forum C Programming
    Replies: 1
    Last Post: 02-28-2005, 12:59 AM
  4. Unix processes
    By J-Dogg in forum Linux Programming
    Replies: 1
    Last Post: 03-24-2003, 05:42 PM
  5. Unix/Linux Processes
    By pdstatha in forum C Programming
    Replies: 3
    Last Post: 03-27-2002, 07:08 AM