Annotation of coherent/b/bin/ps/ps.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <string.h>
        !             3: #include <sys/coherent.h>
        !             4: #include <sys/coh_ps.h>
        !             5: #include <fcntl.h>
        !             6: #include <sys/types.h>
        !             7: #include <sys/stat.h>
        !             8: #include <dirent.h>
        !             9: #include <pwd.h>
        !            10: #include "ps.h"
        !            11: 
        !            12: #define        PROC_NUM        64      /* Number of processes */
        !            13: #define CON_SIZE       8       /* max # of bytes in contrl terminal filed */
        !            14: 
        !            15: extern char    *malloc();
        !            16: void           vGetData();     /* Read the data about all processes */
        !            17: void           vCvtArgs();     /* Process command line */
        !            18: void           vPrintPs();     /* Print data */
        !            19: void           vPrintHeader(); /* Print ps header */
        !            20: void           vPrintLine();   /* Print ps data */
        !            21: dev_t          dvtGetTerminal();/* Get ps controlling terminal */
        !            22: int            iState();       /* Is the process asleep, running, or zombie? */
        !            23: void           ReadDevDir();    /* Read device directory */
        !            24: unsigned       uOkToPrint();   /* Is the process one we want to display? */
        !            25: 
        !            26: stMonitor      *pMonData = NULL;       /* Pointer to an array of data for ps */
        !            27: int            iRet;                   /* Number of bytes read */
        !            28: dev_t          dvtPs;                  /* ps device */
        !            29: 
        !            30: #define                MAXPROCESSES    40              /* # max number of precesses */
        !            31: 
        !            32: unsigned       auProcessP[MAXPROCESSES];       /* List of process to print */
        !            33: int            iNumProcessP = 0;               /* Number of process to print */
        !            34: 
        !            35: static stDevices       *pstDevFirst= NULL;     /* List of character devices. */
        !            36: 
        !            37: /* Flags for input command options */
        !            38: int    iaFlag,         /* Display information from all terminals */
        !            39:        idFlag,         /* Status of loadable drivers */
        !            40:        ifFlag,         /* Blank fields have '-' */
        !            41:        igFlag,         /* Print group leader if l given */
        !            42:        ilFlag,         /* Long format */
        !            43:        imFlag,         /* Scheduling fields */
        !            44:        inFlag,         /* Suppress header line */
        !            45:        ipFlag,         /* Print only specified processes */
        !            46:        irFlag,         /* Print real size of processes */
        !            47:        itFlag,         /* Print elapsed CPU time */
        !            48:        iwFlag,         /* Wide format (print 132 columns) */
        !            49:        ixFlag;         /* Display processes without controlling terminals */
        !            50: 
        !            51: /*
        !            52:  * Print out process status.
        !            53:  */
        !            54: main(argc, argv)
        !            55: int    argc;
        !            56: char   *argv[];
        !            57: {
        !            58:        /*
        !            59:         * To preserve compatibility with older versions of COHERENT ps
        !            60:         * we will fake minus here. Be aware that it adds '-' not only to
        !            61:         * the command line options but to their arguments as well ;-(
        !            62:         * See 'p' case.
        !            63:         */
        !            64:        fakeMinus(argc, argv);
        !            65:        /*
        !            66:         * Digest the command line.
        !            67:         *
        !            68:         * This routine will not return if there are errors in
        !            69:         * the command line.
        !            70:         */
        !            71:        vCvtArgs(argc, argv);
        !            72: 
        !            73:        /* This function will not return if error occurs */
        !            74:        vGetData();
        !            75: 
        !            76:        /* Get dev_t value for device from which ps was fired */
        !            77:        dvtPs = dvtGetTerminal();
        !            78: 
        !            79:        /* We have our data and all flags are set. So, we can print it */
        !            80:        vPrintPs();
        !            81: }
        !            82: 
        !            83: /*
        !            84:  * Fetch all data for ps from the kernel.
        !            85:  */
        !            86: void   vGetData()
        !            87: {
        !            88:        int     fd;     /* File descriptor to /dev/ps*/
        !            89:        int     iCnt;   /* number of attempt to read */
        !            90: 
        !            91:        /* Open process device */
        !            92:        if ((fd = open("/dev/ps", O_RDONLY)) < 0) {
        !            93:                fflush(stdout);
        !            94:                perror("ps: cannot open /dev/ps");
        !            95:                exit(1);
        !            96:        }
        !            97: 
        !            98:        /* This is our main engine. At this point we do not know the
        !            99:         * total number of processes. So, we start from our gess PROC_NUM.
        !           100:         * If we get close enough, do realloc and try again.
        !           101:         */
        !           102:        for (iCnt = 0, iRet = 0; iCnt - iRet <= sizeof(stMonitor); ) {
        !           103:                iCnt += sizeof(stMonitor) * PROC_NUM;
        !           104:                if (pMonData != NULL)
        !           105:                        free(pMonData);
        !           106:                if ((pMonData = (stMonitor *) malloc(iCnt)) == NULL) {
        !           107:                        fflush(stdout);
        !           108:                        perror("ps");
        !           109:                        exit(1);
        !           110:                }
        !           111:                if ((iRet = read(fd, (char *) pMonData, iCnt)) < 0) {
        !           112:                        fflush(stdout);
        !           113:                        perror("ps");
        !           114:                        exit(1);
        !           115:                }
        !           116:        }
        !           117: 
        !           118:        close(fd);
        !           119:        fflush(stdout);
        !           120: 
        !           121: } /* main() */
        !           122: 
        !           123: /*
        !           124:  * Digest the command line.
        !           125:  */
        !           126: void
        !           127: vCvtArgs(argc, argv)
        !           128: int argc;
        !           129: char *argv[];
        !           130: {
        !           131:        char            *opstring = "ac:defgk:lmnp:rtwx";
        !           132:        extern char     *optarg;
        !           133:        int             c;
        !           134:        char            *token;
        !           135: 
        !           136:        while ((c = getopt(argc, argv, opstring)) != EOF)
        !           137:                switch (c) {
        !           138:                case 'a':
        !           139:                case 'e':
        !           140:                        iaFlag = 1;
        !           141:                        break;
        !           142:                case 'c':       /* We will just ignore it */
        !           143:                        break;
        !           144:                case 'd':
        !           145:                        idFlag = 1;
        !           146:                        break;
        !           147:                case 'f':
        !           148:                        ifFlag = 1;
        !           149:                        break;
        !           150:                case 'g':
        !           151:                        igFlag = 1;
        !           152:                        break;
        !           153:                case 'k':       /* We will just ignore it */
        !           154:                        break;
        !           155:                case 'l':
        !           156:                        ilFlag = 1;
        !           157:                        break;
        !           158:                case 'm':
        !           159:                        imFlag = 1;
        !           160:                        break;
        !           161:                case 'n':
        !           162:                        inFlag = 1;
        !           163:                        break;
        !           164:                case 'p':
        !           165:                        ipFlag = iaFlag = 1;
        !           166: 
        !           167:                        /* Take out the '-' that fakeMinus puts in */
        !           168:                        while (*optarg == '-')
        !           169:                                optarg++;
        !           170: 
        !           171:                        token = strtok(optarg, ",");
        !           172:                        while((token != NULL) && (iNumProcessP < MAXPROCESSES)) 
        !           173:                        {
        !           174:                                auProcessP[iNumProcessP++] = atoi(token);
        !           175:                                token = strtok(NULL, ",");
        !           176:                        }
        !           177:                        if (iNumProcessP == 0)
        !           178:                                ipFlag = 0;
        !           179:                        break;
        !           180:                case 'r':
        !           181:                        irFlag = 1;
        !           182:                        break;
        !           183:                case 't':
        !           184:                        itFlag = 1;
        !           185:                        break;
        !           186:                case 'w':
        !           187:                        iwFlag = 1;
        !           188:                        break;
        !           189:                case 'x':
        !           190:                        ixFlag = 1;
        !           191:                        break;
        !           192:                default:
        !           193:                        usage(c);
        !           194:        }
        !           195:        if (ilFlag && igFlag)
        !           196:                igFlag = 1;
        !           197:        else
        !           198:                igFlag = 0;     
        !           199: } /* cvt_args() */
        !           200: 
        !           201: void vPrintPs()
        !           202: {
        !           203:        register stMonitor      *pMonTmp;
        !           204: 
        !           205:        /* Read device directory only once */
        !           206:        ReadDevDir();   /* We may not return from ReadDevDir */
        !           207: 
        !           208:        /* Print the header line */
        !           209:        vPrintHeader();
        !           210: 
        !           211:        for (pMonTmp = pMonData + iRet / sizeof(stMonitor) - 1;
        !           212:                                        pMonTmp >= pMonData; pMonTmp--) {
        !           213:                if (uOkToPrint(pMonTmp->p_pid))
        !           214:                        vPrintLine(pMonTmp);
        !           215:        }
        !           216: }
        !           217: 
        !           218: void vPrintHeader()
        !           219: {
        !           220:        /* If header suppressed */
        !           221:        if (inFlag)
        !           222:                return;
        !           223:        /* Now we can print */
        !           224:        printf("%-8s%5s", "TTY", "PID");
        !           225:        if (igFlag)
        !           226:                printf(" %5s", "GROUP");
        !           227:        if (ilFlag)
        !           228:                printf(" %5s%9s%5s%5s%2s%9s",
        !           229:                        "PPID", "UID", "K", "F", "S", "EVENT");
        !           230: #if 0
        !           231:        if (imFlag)
        !           232:                printf(" %8s %8s %8s %8s", "CVAL", "SVAL", "IVAL", "RVAL");
        !           233: #endif
        !           234:        if (itFlag)
        !           235:                printf(" UTIME STIME");
        !           236:        puts("  COMMAND");
        !           237: }
        !           238: 
        !           239: /*
        !           240:  * Print next line.
        !           241:  */
        !           242: void vPrintLine(pMonLine)
        !           243: stMonitor      *pMonLine;
        !           244: {
        !           245:        char            *cpFindTerminal();
        !           246:        char            *cpTty;
        !           247: 
        !           248:        /* Check controling terminal */
        !           249:        if (major(pMonLine->p_ttdev) == 0) {
        !           250:                if (minor(pMonLine->p_ttdev) == 0)
        !           251:                        cpTty = "null";
        !           252:        } else {
        !           253:                if (major(pMonLine->p_ttdev) == 0x0FF) {
        !           254:                        if (minor(pMonLine->p_ttdev) == 255) {
        !           255:                                cpTty = "-------";
        !           256:                        }
        !           257:                } else {
        !           258:                        if ((cpTty=cpFindTerminal(pMonLine->p_ttdev)) == NULL)
        !           259:                                cpTty = "?";
        !           260:                }
        !           261:        }
        !           262: 
        !           263:        /* Do we have to skip this line? */
        !           264:        if (!iaFlag && (dvtPs != pMonLine->p_ttdev)) {
        !           265:                if (!ixFlag || strcmp("-------", cpTty))
        !           266:                        return;
        !           267:        } else
        !           268:                if (!ixFlag && !strcmp("-------", cpTty))
        !           269:                        return;
        !           270:        printf("%-8s%5u", cpTty, pMonLine->p_pid);
        !           271: 
        !           272:        if (igFlag)
        !           273:                printf(" %5d", pMonLine->p_rgid);
        !           274: 
        !           275:        if (ilFlag) {
        !           276:                int     c;
        !           277:                struct passwd   *pstPasswd;
        !           278: 
        !           279:                if ((pstPasswd = getpwuid(pMonLine->p_uid)) == NULL) {
        !           280:                        fflush(stdout);
        !           281:                        perror("\nps: cannot get user name");
        !           282:                        exit(1);
        !           283:                }
        !           284:                printf("%6d%9s", pMonLine->p_ppid, pstPasswd->pw_name);
        !           285:                if (irFlag)
        !           286:                        printf("%5d", pMonLine->rsize);
        !           287:                else
        !           288:                        printf("%5d", pMonLine->size);
        !           289:                printf("%5o", pMonLine->p_flags);
        !           290:                c = iState(pMonLine);
        !           291:                printf(" %c", c);
        !           292:                if (c == 'S') {
        !           293:                        if (pMonLine->u_sleep[0] != '\0')
        !           294:                                printf("%9s", pMonLine->u_sleep);
        !           295:                        else
        !           296:                                printf("%9x", pMonLine->p_event);
        !           297:                } else
        !           298:                        if (ifFlag)
        !           299:                                printf("        -");
        !           300:                        else
        !           301:                                printf("         ");
        !           302: 
        !           303:        }
        !           304: 
        !           305:        /* Scheduling fields */
        !           306: #if 0
        !           307:        if (imFlag) 
        !           308:                printf(" %8x %8x %8x %8x", pMonLine->p_cval,
        !           309:                                pMonLine->p_sval,
        !           310:                                pMonLine->p_ival,
        !           311:                                pMonLine->p_rval);
        !           312: #endif
        !           313:        if (itFlag) {
        !           314:                ptime(pMonLine->p_utime);
        !           315:                ptime(pMonLine->p_stime);
        !           316:        }
        !           317:                                
        !           318:        printf("  %.*s\n", U_COMM_LEN, pMonLine->u_comm);
        !           319: }
        !           320: 
        !           321: /*
        !           322:  * Given a time in HZ, print it out.
        !           323:  */
        !           324: ptime(l)
        !           325:        long l;
        !           326: {
        !           327:        register unsigned m;
        !           328: 
        !           329:        if ((l=(l+HZ/2)/HZ) == 0) {
        !           330:                if (ifFlag)
        !           331:                        printf("     -");
        !           332:                else
        !           333:                        printf("      ");
        !           334:                return;
        !           335:        }
        !           336:        if ((m=l/60) >= 100) {
        !           337:                printf("%6d", m);
        !           338:                return;
        !           339:        }
        !           340:        printf(" %2d:%02d", m, (unsigned)l%60);
        !           341: }
        !           342: 
        !           343: /*
        !           344:  * Find status of a proces. If sleep, reason why.
        !           345:  */
        !           346: int iState(pMon)
        !           347: stMonitor      *pMon;
        !           348: {
        !           349: 
        !           350:        if (ASLEEP(pMon)) {
        !           351:                if (pMon->rrun)
        !           352:                        return 'S';
        !           353:                if ((pMon->p_flags & PFSTOP) != 0)
        !           354:                        return 'T';
        !           355:                if (pMon->p_state == PSSLEEP)
        !           356:                        return 'W';
        !           357:                else
        !           358:                        return 'w';
        !           359:        }
        !           360:                
        !           361:        if (pMon->p_state == PSRUN)
        !           362:                return 'R';
        !           363:        if (pMon->p_state == PSDEAD)
        !           364:                return 'Z';
        !           365:        return '?';
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * Find a device. Return device name or NULL if device was not found.
        !           370:  */
        !           371: char *cpFindTerminal(dev)
        !           372: dev_t  dev;
        !           373: {
        !           374:        register stDevices      *pstDev;
        !           375: 
        !           376:        /* Find a proper device */
        !           377:        for (pstDev = pstDevFirst; pstDev != NULL; pstDev = pstDev->next) {
        !           378:                if (dev == pstDev->dev) {
        !           379:                        return pstDev->pDevName;
        !           380:                }
        !           381:        }
        !           382:        /* Device not found */
        !           383:        return NULL;
        !           384: }
        !           385: 
        !           386: /*
        !           387:  * Read device directory and store data in memory.
        !           388:  * This function will not return if it cannot open /dev or run
        !           389:  * out of memory.
        !           390:  */
        !           391: void ReadDevDir()
        !           392: {
        !           393:        register DIR            *pDir;
        !           394:        register stDevices      *pstDevNext;
        !           395:        static stDevices        *pstDevPrev;
        !           396:        register struct dirent  *pDrnt;
        !           397:        struct stat             stStat;
        !           398:        char                    pFileName[32];  /* File name buffer */
        !           399:        
        !           400:        if ((pDir = opendir( "/dev" )) == NULL) {
        !           401:                fflush(stdout);
        !           402:                perror("ps");
        !           403:                exit(1);
        !           404:        }
        !           405: 
        !           406:        while ( (pDrnt = readdir( pDir )) != NULL ) {
        !           407:                sprintf(pFileName, "/dev/%.*s", DIRSIZ, pDrnt->d_name);
        !           408:                /* We may skip silent the file that we cannot stat.
        !           409:                 */
        !           410:                if (stat(pFileName, &stStat) < 0)
        !           411:                        continue;
        !           412:                if ((stStat.st_mode & S_IFMT) != S_IFCHR)
        !           413:                        continue;
        !           414: 
        !           415:                if ((pstDevNext = malloc(sizeof(struct DEVICES))) == NULL) {
        !           416:                        fflush(stdout);
        !           417:                        perror("ps");
        !           418:                        exit(1);        
        !           419:                }
        !           420:                if (pstDevFirst == NULL)
        !           421:                        pstDevFirst = pstDevPrev = pstDevNext;
        !           422:                else
        !           423:                        pstDevPrev->next = pstDevNext;
        !           424:                        
        !           425:                pstDevNext->dev = stStat.st_rdev;
        !           426:                strncpy(pstDevNext->pDevName, pDrnt->d_name, DIRSIZ);
        !           427:                pstDevNext->next = NULL;
        !           428:                pstDevPrev = pstDevNext;
        !           429:         }
        !           430:        closedir(pDir);
        !           431: }
        !           432: 
        !           433: /*
        !           434:  * Get dev_t value for ps controlling terminal.
        !           435:  * Return 0 is a flag was set or controlling terminal was not found.
        !           436:  */
        !           437: dev_t dvtGetTerminal()
        !           438: {
        !           439:        register stMonitor      *pMonTmp;
        !           440:        register int            iPid;   /* Our process id */
        !           441: 
        !           442:        if (iaFlag)
        !           443:                return 0;
        !           444:        
        !           445:        iPid = getpid();
        !           446:        
        !           447:        /* Go through all data until ps id will be found */
        !           448:        for (pMonTmp = pMonData + iRet / sizeof(stMonitor) - 1;
        !           449:                                        pMonTmp >= pMonData; pMonTmp--)
        !           450:                if (pMonTmp->p_pid == iPid)
        !           451:                        return pMonTmp->p_ttdev;
        !           452: 
        !           453:        return 0;
        !           454: }
        !           455: 
        !           456: /* 
        !           457:  * Return 1 if ipFlag is not set or ipFlag is set and process is specified, 
        !           458:  * 0 otherwise.
        !           459:  */
        !           460: unsigned uOkToPrint(pnum)
        !           461: unsigned pnum;
        !           462: {
        !           463:        int     i;
        !           464: 
        !           465:        if (!ipFlag)
        !           466:                return 1;
        !           467:        
        !           468:        for (i = 0; i < iNumProcessP; i++)
        !           469:                if (auProcessP[i] == pnum)
        !           470:                        return 1;
        !           471:        return 0;
        !           472: }
        !           473: 
        !           474: usage()
        !           475: {
        !           476:        printf("usage: ps [-][aefglmnrtwx][p#[,#]...]\n");
        !           477:        exit(1);
        !           478: }
        !           479: 
        !           480: fakeMinus(argc, argv)
        !           481: int argc;
        !           482: char * argv[];
        !           483: {
        !           484:        int argn;
        !           485:        char * malloc();
        !           486: 
        !           487:        for (argn = 1; argn < argc; argn++) {
        !           488:                if (argv[argn][0] && argv[argn][0] != '-') {
        !           489:                        char * temp = malloc(strlen(argv[argn])+2);
        !           490:                        temp[0] = '-';
        !           491:                        strcpy(temp+1, argv[argn]);
        !           492:                        argv[argn] = temp;
        !           493:                }
        !           494:        }
        !           495: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.