The HyperNews Linux KHG Discussion Pages

## try this code

  Forum: Filesystems
  Re: Documentation on /proc/pid#/ dirs?
  Date: Sun, 21 Jun 1998 16:58:18 GMT
  From: <marty@twsu.campus.mci.net>

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    #include <ctype.h>
    #include <pwd.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <time.h>
extern int errno; typedef signed char bool_t;
    #if !defined ( FALSE )
    #define FALSE 0
    #endif
    #if !defined ( TRUE )
    #define TRUE 1
    #endif
    #define GU_LINE_BUFFER_LEN 1024
    #define GU_FILE_NAME_LEN   81
    #define START_TIME_STR_LEN     16
    #define DIFF_TIME_STR_LEN      12
    #define RUN_TIME_STR_LEN       12
#define GU_DEBUG
    #if defined GU_DEBUG
    #define GU_ASSERT(A) \
         if (A) { \
         } else { \
             GU_logAssertion( __FILE__, __LINE__ ); \
         }
    #else
    #define GU_ASSERT(A)
    #endif
static FILE *SpfLog = (FILE *) NULL; static char *SszLog = "message.log";
    typedef struct UserStatTag {
        int pid;
        char szName[GU_FILE_NAME_LEN];
        char state;
        int ppid;
        int pgrp;
        int sid;
        int terminal;
        int pgid;
        unsigned long flags;
        unsigned long min_flt;
        unsigned long cmin_flt;
        unsigned long maj_flt;
        unsigned long cmaj_flt;
        long utime;
        long stime;
        long cutime;
        long cstime;
        long counter;
        long priority;
        unsigned long timeout;
        unsigned long it_real_value;
        long start_time;
        unsigned size;
        unsigned rss;
        unsigned rlim;
        unsigned long start_code;
        unsigned long end_code;
        unsigned long start_stack;
        unsigned long st_ptr;
        unsigned long ip_ptr;
        unsigned long signal;
        unsigned long blocked;
        unsigned long sv_ignored;
        unsigned long sv_handle;
        unsigned long addr_kernel;
    } UserStatStruct;
    void
    GU_exit(int nLevel)
    {
      exit(nLevel);
    }
    static void
    openLogFile(void)
    {
      SpfLog = fopen(SszLog, "w");
      if (!SpfLog) {
        fprintf(stderr, "%s(%d): Could not open %s for message logging!\n",
                __FILE__, __LINE__, SszLog);
        GU_exit(-1);
      }
      setvbuf(SpfLog, NULL, 0, _IONBF);
    }
    static void
    closeLogFile(void)
    {
      fclose(SpfLog);
      SpfLog = (FILE *) NULL;
    }
    int
    GU_logError(FILE * pf, char *szFmt,...)
    {
      va_list vargPtr;
      va_start(vargPtr, szFmt);
      if (!SpfLog) {
        openLogFile();
      }
      if (pf) {
        vfprintf(pf, szFmt, vargPtr);
      }
      vfprintf(SpfLog, szFmt, vargPtr);
      va_end(vargPtr);
return (0); }
    void
    GU_logAssertion(char *szFile, int nLine)
    {
      fprintf(stderr, "%s(%d): Assertion failed!\n", szFile, nLine);
      exit(-99);
    }
static int parseTimeLong ( char *timeStr, time_t timeVal, char *timeFormat ) { int returnCode = 0; /* Return code from strftime */ struct tm *tm = (struct tm *)NULL; /* Time struct, used as temp space */
        memset( timeStr, '\0', DIFF_TIME_STR_LEN );
        tm = localtime( &timeVal );
        returnCode = strftime( timeStr,
                               START_TIME_STR_LEN - 4,
                               timeFormat,
                               tm );
return( returnCode ); } static char * getRunTime ( time_t timeVal ) { static char timeStr[ RUN_TIME_STR_LEN ]; time_t seconds = (time_t)0; time_t minutes = (time_t)0; time_t hours = (time_t)0; time_t days = (time_t)0;
        memset( timeStr, '\0', RUN_TIME_STR_LEN );
        /* If to be reported as ... */
        if ( timeVal < (time_t)60 ) {
            sprintf( timeStr, "%ld s", timeVal );
        } else if ( timeVal < (time_t)3600 ) {
            minutes = timeVal / (time_t)60;
            seconds = timeVal % (time_t)60;
            sprintf( timeStr, "%ld:%ld m", minutes, seconds );
        } else if ( timeVal < (time_t)86400 ) {
            hours   = timeVal / (time_t)3600;
            minutes = ( timeVal % (time_t)3600 ) / (time_t)60;
            seconds = ( timeVal % (time_t)3600 ) % (time_t)60;
            sprintf( timeStr, "%ld:%ld h", hours, minutes );
        } else {
            days    = timeVal / (time_t)86400;
            hours   = ( timeVal % (time_t)86400 ) / (time_t)3600;
            sprintf( timeStr, "%ld:%ld d", days, hours );
        }
return( timeStr ); } /* **************** Start of stuff **************************** */ int main ( int argc, char *argv[] ) { FILE *pf = (FILE *)NULL;
    struct passwd *pwdUser = (struct passwd *)NULL;
    struct passwd *pwdCurr = (struct passwd *)NULL;
    char *pszProc = (char *)NULL;
    char *pszUser = (char *)NULL;
DIR *pDir = (DIR *)NULL; struct dirent *pEnt = (struct dirent *)NULL; char szFileName[GU_FILE_NAME_LEN]; int iRC = 0; uid_t uidUser; struct stat ss; UserStatStruct sus; time_t ttStart = 0; time_t ttCur = 0; time_t ttMidNight = 0; time_t ttElapsed = 0; time_t ttBoot = 0; char szLine[GU_LINE_BUFFER_LEN]; char szBuf[GU_LINE_BUFFER_LEN]; int iReadIn; char *psz = (char *)NULL; char szStartTime[ START_TIME_STR_LEN ]; char szRunTime[ DIFF_TIME_STR_LEN ];
    char *pszStartFormat = (char *)NULL;
    char *pszRunFormat = (char *)NULL;
char *pszCurrUser = (char *)NULL; int i; int j; int k; struct tm *ptm = (struct tm *)NULL; struct tm tm;
       ttCur = time( (time_t *)NULL );
       ptm = localtime( &ttCur );
       tm = *ptm;
       tm.tm_sec = 0;
       tm.tm_min = 0;
       tm.tm_hour = 0;
       ttMidNight = mktime( &tm );
       /* printf( "%ld %ld\n", ttCur, ttMidNight ); */
       if ( argc == 2 || argc == 3 ) {
               pszProc = argv[1];
           if ( argc == 3 ) {
               pszUser = argv[2];
               pwdUser = getpwnam( pszUser );
               if ( pwdUser ) {
                   GU_logError( NULL, "%s has uid %d\n",
                                pwdUser->pw_name, pwdUser->pw_uid );
                   uidUser = pwdUser->pw_uid;
               } else {
                   GU_logError( stderr, "%s has no account\n", pszUser );
                   GU_exit( -1 );
               }
           }
       } else {
           GU_logError( stderr, "%s <base name> [<user>]\n", argv[0] );
           GU_exit( -1 );
       }
       /*
        * Get the boot time!
        */
       sprintf( szFileName, "%s/stat", pszProc );
       pf = fopen( szFileName, "r" );
       if ( !pf ) {
           GU_logError( stderr, "%s(%d): Could not open %s for reading.\n",
                    __FILE__, __LINE__, szFileName );
           exit( -1 );
       }
       iReadIn = 0;
       while (fgets(szLine, GU_LINE_BUFFER_LEN, pf)) {
           if ( feof( pf ) ) {
               break;
           }
           strcpy( szBuf, szLine );
           iReadIn++;
           psz = strtok(szLine, " ");
           if ( !psz ) {
               continue;
           }
           if ( !strcmp( psz, "btime" ) ) {
               psz = strtok(NULL, "\n");
               if ( !psz ) {
                   continue;
               }
               ttBoot = atol( psz );
               break;
           }
       }
       GU_logError( NULL, "Current time is %ld\nBoot Time is %ld\n",
                    ttCur, ttBoot );
       fclose( pf );
       pf = (FILE *)NULL;
       pDir = opendir( pszProc );
       if ( !pDir ) {
           GU_logError( stderr, "%s does not exist!\n", pszProc );
           GU_exit( -1 );
       }
       GU_logError( stdout, "%8s %5s %5s %5s %s %3s %12s %12s %5s %s %s\n",
                    "User", "pid", "uid", "pgrp", "F", "pri", "start", "elapsed",
                    "ppid", "pwd", "command line" );
       while ( 1 ) {
           pEnt = readdir( pDir );
           if ( !pEnt ) {
               break;
           }
           if ( !isdigit( pEnt->d_name[0] ) ) {
               continue;
           }
           GU_logError( NULL, "%s current entry\n", pEnt->d_name );
           sprintf( szFileName, "%s/%s/stat", pszProc, pEnt->d_name );
           iRC = stat( szFileName, &ss );
           if ( iRC ) {
               GU_logError( stderr, "Could not access %s -- %s\n",
                            szFileName, strerror( errno ) );
               continue;
           }
           if ( pszUser && ss.st_uid != uidUser ) {
               continue;
           } else if ( pszUser ) {
               pszCurrUser = pszUser;
           } else {
               pwdCurr = getpwuid( ss.st_uid );
               if ( pwdCurr ) {
                    pszCurrUser = pwdCurr->pw_name;
               } else {
                   GU_logError( stderr, "%s has no account\n", pszUser );
                   continue;
               }
           }
           GU_logError( NULL, "UID = %d\n", ss.st_uid );
           pf = fopen( szFileName, "r" );
           if ( !pf ) {
               GU_logError( stderr, "PID has expired: %s\n", szFileName );
               continue;
           }
           fscanf( pf, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu"
                       "%ld %ld %ld %ld %ld %ld %lu %lu %ld %u %u %u"
                       "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
                   &sus.pid, sus.szName, &sus.state, &sus.ppid, &sus.pgrp,
                   &sus.sid, &sus.terminal, &sus.pgid, &sus.flags,
                   &sus.min_flt, &sus.cmin_flt, &sus.maj_flt, &sus.cmaj_flt,
                   &sus.utime, &sus.stime, &sus.cutime, &sus.cstime,
                   &sus.counter, &sus.priority, &sus.timeout,
                   &sus.it_real_value, &sus.start_time, &sus.size,
                   &sus.rss, &sus.rlim, &sus.start_code, &sus.end_code,
                   &sus.start_stack, &sus.st_ptr, &sus.ip_ptr, &sus.signal,
                   &sus.blocked, &sus.sv_ignored, &sus.sv_handle,
                   &sus.addr_kernel );
           GU_logError( NULL, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu"
                       "%ld %ld %ld %ld %ld %ld %lu %lu %ld %u %u %u"
                       "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
                   sus.pid, sus.szName, sus.state, sus.ppid, sus.pgrp,
                   sus.sid, sus.terminal, sus.pgid, sus.flags,
                   sus.min_flt, sus.cmin_flt, sus.maj_flt, sus.cmaj_flt,
                   sus.utime, sus.stime, sus.cutime, sus.cstime,
                   sus.counter, sus.priority, sus.timeout,
                   sus.it_real_value, sus.start_time, sus.size,
                   sus.rss, sus.rlim, sus.start_code, sus.end_code,
                   sus.start_stack, sus.st_ptr, sus.ip_ptr, sus.signal,
                   sus.blocked, sus.sv_ignored, sus.sv_handle,
                   sus.addr_kernel );
           fclose( pf );
           pf = (FILE *)NULL;
           ttStart = ttBoot + sus.start_time / 100;
           ttElapsed = ttCur - ttStart;
            if ( ttStart < ttMidNight ) {
                pszRunFormat = "%b %d";
                pszStartFormat = "%b %d";
            } else {
                if ( ttElapsed < ( 60 * 60 ) ) {
                    pszRunFormat = "%M:%S";
                    pszStartFormat = "%r";
                } else if ( ttElapsed < ( 24 * 60 * 60 ) ) {
                    pszRunFormat = "%H:%M:%S";
                    pszStartFormat = "%r";
                } else {
                    pszRunFormat = "%b %d";
                    pszStartFormat = "%b %d";
                }
            }
            /* Get the time the process was kicked off */
            parseTimeLong( szStartTime, ttStart, pszStartFormat );
            /* Get the time the proc ran */
    #if defined ( NOT_NOW )
            parseTimeLong( szRunTime, ttElapsed, pszRunFormat );
    #else
            strcpy( szRunTime, getRunTime( ttElapsed ) );
    #endif
    	/* username pid uid gid state nice start time elasped time parent pid
    	   fullpath command line args */
            GU_logError( stdout,
                         "%8s %5d %5d %5d %c %3d %12s %12s %5d",
                         pszCurrUser, sus.pid, uidUser,
                         sus.pgrp, sus.state, sus.priority, szStartTime, szRunTime,
                         sus.ppid );
           sprintf( szFileName, "%s/%s/environ", pszProc, pEnt->d_name );
           pf = fopen( szFileName, "r" );
           if ( !pf ) {
               GU_logError( stdout, "\n" );
               continue;
           }
           memset( szLine, '\0', GU_LINE_BUFFER_LEN );
           psz = fgets(szLine, GU_LINE_BUFFER_LEN, pf);
           if ( !psz ) {
               GU_logError( NULL,
                            "Could not get data from %s -- %d -- %d\n",
                            szFileName,
                            ferror( pf ), feof( pf ) );
           }
           for ( i = 0; i < GU_LINE_BUFFER_LEN; i = k ) {
               for ( k = i + 1; k < GU_LINE_BUFFER_LEN; k++ ) {
                   if ( szLine[k] == '=' ) {
                       szLine[k] = '\0';
                       j = k + 1;
                   } else if ( szLine[k] == '\0' ) {
                       k++;
                       break;
                   }
               }
               if ( !strcmp( &szLine[i], "PWD" ) ) {
                   GU_logError( stdout, " %s", &szLine[j] );
                   break;
               }
           }
           fclose( pf );
           pf = (FILE *)NULL;
           sprintf( szFileName, "%s/%s/cmdline", pszProc, pEnt->d_name );
           pf = fopen( szFileName, "r" );
           if ( !pf ) {
               GU_logError( stdout, "\n" );
               continue;
           }
           memset( szLine, '\0', GU_LINE_BUFFER_LEN );
           psz = fgets(szLine, GU_LINE_BUFFER_LEN, pf);
           if ( !psz ) {
               GU_logError( NULL,
                            "Could not get data from %s -- %d -- %d\n",
                            szFileName,
                            ferror( pf ), feof( pf ) );
           }
           for ( i = 0; i < GU_LINE_BUFFER_LEN; i++ ) {
               if ( szLine[i] == '\0' ) {
                   szLine[i] = ' ';
               }
           }
           for ( i--; i > 0; i-- ) {
               if ( szLine[i] != ' ' ) {
                   break;
               } else {
                   szLine[i] = '\0';
               }
           }
           GU_logError( stdout, " %s", szLine );
           fclose( pf );
           pf = (FILE *)NULL;
           GU_logError( stdout, "\n" );
       }
       closedir( pDir );
       closeLogFile();
       return ( 0 );
    }