/* @(#)ps.c 1.6 */ /* * ps - process status * examine and print certain things about processes */ #include <stdio.h> #include <fcntl.h> #include "sys/types.h" #ifdef u3b #include "sys/page.h" #include "sys/istk.h" #include "sys/ssr.h" #include "sys/seg.h" #endif #include "a.out.h" #include "pwd.h" #include "sys/param.h" #ifdef u3b #include "sys/macro.h" #else #include "sys/sysmacros.h" #endif #include "sys/proc.h" #include "sys/tty.h" #include "sys/dir.h" #include "sys/signal.h" #include "sys/stat.h" #include "sys/user.h" #include "sys/var.h" #include "core.h" #define NTTYS 20 #define SIZ 30 #define TSIZE 100 #define ARGSIZ 30 #ifndef MAXLOGIN #define MAXLOGIN 8 #endif /* Structure for storing user info */ struct udata { unsigned short uid; /* numeric user id */ char name[MAXLOGIN]; /* character user id, may not be null terminated */ }; /* udata granularity for structure allocation */ #define UDQ 50 /* Pointer to user data */ struct udata *ud; int nud = 0; /* number of valid ud structures */ int maxud = 0; /* number of ud's allocated */ struct udata uid_tbl[SIZ]; /* table to store selected uid's */ int nut = 0; /* counter for uid_tbl */ struct nlist nl[] = { #ifdef u3b "proc", (long)0, (short)0, (unsigned short)0, (char)0, (char)0, "swaplow", (long)0, (short)0, (unsigned short)0, (char)0, (char)0, "v", (long)0, (short)0, (unsigned short)0, (char)0, (char)0, "_sbrpte", (long)0, (short)0, (unsigned short)0, (char)0, (char)0, 0, (long)0, (short)0, (unsigned short)0, (char)0, (char)0 #else { "_proc" }, { "_swplo" }, { "_v" }, { "_sbrpte" }, { 0 }, #endif }; #ifndef u3b union { struct proc mprc; struct xproc zprc; } prc; #define mproc prc.mprc #define zproc prc.zprc #else /* u3b */ struct proc prc; #define mproc prc #define zproc prc int procaddr; #endif /* u3b */ struct var v; #ifndef u3b int sbrpte; int upte[128]; int spte; #endif #if pdp11 || u3b struct user u; #endif #ifdef vax union { struct user yy; int xx[128] [USIZE]; } zz; #define u zz.yy int mf; #endif #ifdef u3b int file; #endif int retcode=1; int c; int lflg; int eflg; int uflg; int aflg; int dflg; int pflg; int fflg; int gflg; int nflg; int tflg; int sflg; int errflg; char *gettty(); char *ttyname(); int memfd; int swmem; int swap; daddr_t swplo; char argbuf[ARGSIZ]; char *parg; char *p1; char *coref; char *memf; char *system; long lseek(); static char stdbuf[BUFSIZ]; #define NDEV 512 int ndev; struct devl { char dname[DIRSIZ]; dev_t dev; } devl[NDEV]; char *tty[NTTYS]; /* for t option */ int ntty = 0; int pid[SIZ]; /* for p option */ int npid = 0; int grpid[SIZ]; /* for g option */ int ngrpid = 0; main(argc, argv) char **argv; { register char **ttyp = tty; char *name; char *p; int puid, ppid, ppgrp; int i, found; extern char *optarg; extern int optind; char *getstr; char *usage="ps [ -edalf ] [ -c corefile ] [ -s swapdev ] [ -n namelist ] [ -t tlist ]"; char *usage2=" [ -p plist ] [ -u ulist ] [ -g glist ]"; char *malloc(); unsigned size; getstr = "lfeadn:s:c:t:p:g:u:"; system = "/unix"; #ifdef vax coref = "/dev/kmem"; memf = "/dev/mem"; #else coref = "/dev/mem"; memf = coref; #endif setbuf(stdout, stdbuf); while ((c = getopt(argc,argv,getstr)) != EOF) switch(c) { case 'l': /* long listing */ lflg++; break; case 'f': /* full listing */ fflg++; break; case 'e': /* list for every process */ eflg++; tflg = uflg = pflg = gflg = 0; break; case 'a': /* same as e except no proc grp leaders */ aflg++; /* and no non-terminal processes */ break; case 'd': /* same as e except no proc grp leaders */ dflg++; break; case 'n': /* alternate namelist */ nflg++; system = optarg; break; case 'c': /* core file given */ coref = optarg; memf = coref; break; case 's': /* swap device given */ sflg++; if ((swap = open(optarg, 0)) < 0 ) { fprintf(stderr, "ps: cannot open %s\n",optarg); done(1); } break; case 't': /* terminals */ tflg++; p1 = optarg; do { parg = argbuf; if (ntty >= NTTYS) break; getarg(); if (strncmp(parg,"tty",3) == 0) parg += 3; size = strlen(parg); if ((p = malloc(++size)) == NULL) { fprintf(stderr,"ps: no memory\n"); done(1); } strcpy(p,parg); *ttyp++ = p; ntty++; } while (*p1); break; case 'p': /* proc ids */ pflg++; p1 = optarg; parg = argbuf; do { if (npid >= SIZ) break; getarg(); pid[npid++] = atoi(parg); } while (*p1); break; case 'g': /* proc group */ gflg++; p1 = optarg; parg = argbuf; do { if (ngrpid >= SIZ) break; getarg(); grpid[ngrpid++] = atoi(parg); } while (*p1); break; case 'u': /* user name or number */ uflg++; p1 = optarg; parg = argbuf; do { getarg(); if(nut < SIZ) strncpy(uid_tbl[nut++].name,parg,MAXLOGIN); } while (*p1); break; case '?': /* error */ errflg++; break; } if ( errflg || (optind < argc)) { fprintf(stderr,"usage: %s\n%s\n",usage,usage2); done(1); } if (tflg) *ttyp = 0; /* if specifying options not used, current terminal is default */ if ( !(aflg || eflg || dflg || uflg || tflg || pflg || gflg )) { name = ttyname(2); if (strncmp(name+5,"tty",3)==0) *ttyp++ = name+8; else *ttyp++ = name+5; *ttyp = 0; ntty++; tflg++; } if (eflg) tflg = uflg = pflg = gflg = aflg = dflg = 0; if (aflg || dflg) tflg = 0; /* get data from psfile */ if(!readata()) { getdev(); getpass(); getnl(); if(!nflg) wrdata(); }else { if(nflg) getnl(); } uconv(); if(nl[0].n_value==0||nl[1].n_value==0||nl[2].n_value==0) { fprintf(stderr, "ps: no namelist\n"); done(1); } #ifdef vax nl[0].n_value = ((int)nl[0].n_value & 0x3fffffff); nl[1].n_value = ((int)nl[1].n_value & 0x3fffffff); nl[2].n_value = ((int)nl[2].n_value & 0x3fffffff); nl[3].n_value = ((int)nl[3].n_value & 0x3fffffff); #endif if ((memfd = open(coref, 0)) < 0) { fprintf(stderr, "ps: no mem\n"); done(1); } if ((swmem = open(memf,0)) < 0) { fprintf(stderr, "ps: no mem\n"); done(1); } /* * Find base of swap */ l_lseek(memfd, (long)nl[1].n_value, 0); r_read(memfd, (char *)&swplo, sizeof(swplo)); /* * read to find proc table size */ l_lseek(memfd, (long)nl[2].n_value, 0); r_read(memfd, (char *)&v, sizeof(v)); #ifdef vax /* * read to find system page tables */ l_lseek(memfd, (long)nl[3].n_value, 0); r_read(memfd, (char *)&sbrpte, sizeof(sbrpte)); sbrpte &= 0x3fffffff; #endif /* * Locate proc table */ l_lseek(memfd, (long)nl[0].n_value, 0); /* this opens swap */ if ( !sflg ) { if ((swap = open("/dev/swap", 0)) < 0) { fprintf(stderr, "ps: cannot open /dev/swap\n"); done(1); } } if (fflg && lflg ) printf(" F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME COMD\n"); else if (fflg) printf(" UID PID PPID C STIME TTY TIME COMMAND\n"); else if (lflg) printf(" F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME COMD\n"); else printf(" PID TTY TIME COMMAND\n"); /* determine which processes to print info about */ for (i=0; i<v.v_proc; i++) { found = 0; r_read(memfd, (char *)&mproc, sizeof(mproc)); if (mproc.p_stat == 0) continue; puid = mproc.p_uid; ppid = mproc.p_pid; ppgrp = mproc.p_pgrp; if ((ppid == ppgrp) && (dflg || aflg)) continue; if (eflg || dflg) found++; else if (pflg && search(pid, npid, ppid)) found++; else if (uflg && ufind(puid)) found++; else if (gflg && search(grpid, ngrpid, ppgrp)) found++; if ( !found && !tflg && !aflg ) continue; #ifdef u3b procaddr = nl[0].n_value + (i * sizeof(mproc)) + (int)mproc.p_stbl - (int)&mproc; #endif if (prcom(puid,found)) { printf("\n"); retcode =0; } } done(retcode); } /* readata reads in the open devices (terminals) and stores */ /* info in the devl structure. */ static char psfile[] = "/etc/ps_data"; int readata() { struct stat sbuf1, sbuf2; int fd; if (stat(psfile, &sbuf1) < 0 || (stat("/dev", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime) || (stat("/unix", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime) || (stat("/etc/passwd", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime)) { return(0); } if(( fd = open(psfile, O_RDONLY)) < 0) return(0); /* read /dev data from psfile */ psread(fd, &ndev, sizeof(ndev)); psread(fd, devl, ndev * sizeof(*devl)); /* read /etc/passwd data from psfile */ psread(fd, &nud, sizeof(nud)); if((ud = (struct udata *)malloc(nud * sizeof(*ud))) == NULL) { fprintf(stderr, "ps: not enough memory\n"); exit(1); } psread(fd, ud, nud * sizeof(*ud)); /* read /unix data from psfile */ if(!nflg) psread(fd, nl, sizeof(nl)); close(fd); return(1); } getdev() { register FILE *df; struct direct dbuf; struct stat sbuf1; if ((df = fopen("/dev", "r")) == NULL) { fprintf(stderr, "ps: cannot open /dev\n"); done(1); } if (chdir("/dev") < 0) { fprintf(stderr, "ps: cannot change to /dev\n"); done(1); } ndev = 0; while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) { if(dbuf.d_ino == 0) continue; if(stat(dbuf.d_name, &sbuf1) < 0) continue; if ((sbuf1.st_mode&S_IFMT) != S_IFCHR) continue; strcpy(devl[ndev].dname, dbuf.d_name); devl[ndev].dev = sbuf1.st_rdev; ndev++; } fclose(df); } /* Get the passwd file data into the ud structure */ getpass() { struct passwd *pw, *getpwent(); char *malloc(), *realloc(); ud = NULL; nud = 0; maxud = 0; while((pw=getpwent()) != NULL) { while(nud >= maxud) { maxud += UDQ; ud = (struct udata *) ((ud == NULL) ? malloc(sizeof(struct udata) * maxud) : realloc(ud, sizeof(struct udata) * maxud)); if(ud == NULL) { fprintf(stderr,"ps: not enough memory for %d users\n", maxud); exit(1); } } /* copy fields from pw file structure to udata */ ud[nud].uid = pw->pw_uid; strncpy(ud[nud].name, pw->pw_name, MAXLOGIN); nud++; } endpwent(); } /* Get name list data into nl structure */ getnl() { nlist(system, nl); } wrdata() { int fd; umask(02); unlink(psfile); if((fd = open(psfile, O_WRONLY | O_CREAT | O_EXCL, 0664)) > -1) { /* write /dev data */ pswrite(fd, &ndev, sizeof(ndev)); pswrite(fd, devl, ndev * sizeof(*devl)); /* write /etc/passwd data */ pswrite(fd, &nud, sizeof(nud)); pswrite(fd, ud, nud * sizeof(*ud)); /* write /unix data */ pswrite(fd, nl, sizeof(nl)); close(fd); } } /* getarg finds next argument in list and copies arg into argbuf */ /* p1 first pts to arg passed back from getopt routine. p1 is then */ /* bumped to next character that is not a comma or blank - p1 null */ /* indicates end of list */ getarg() { char *parga; parga = argbuf; while(*p1 && *p1 != ',' && *p1 != ' ') *parga++ = *p1++; *parga = '\0'; while( *p1 && ( *p1 == ',' || *p1 == ' ') ) p1++; } /* gettty returns the user's tty number or ? if none */ char *gettty() { register i; register char *p; if (u.u_ttyp==0) return("?"); for (i=0; i<ndev; i++) { if (devl[i].dev == u.u_ttyd) { p = devl[i].dname; if (strncmp(p,"tty",3) == 0) p += 3; return(p); } } return("?"); } #ifdef pdp11 long round(a,b) long a, b; { long w = ((a+b-1)/b)*b; return(w); } typedef unsigned pos; struct map { long b1, e1; long f1; long b2, e2; long f2; }; struct map datmap; int file; #endif /* print info about the process */ prcom(puid,found) int puid,found; { #ifdef u3b char line[80]; int page; #endif register int *ip; register char *cp, *cp1; register char *tp; long addr; char *ctime(); time_t time(); time_t *clock, *tloc; time_t tim; char timbuf[26]; char *curtim = timbuf; char *sttim, *s1; long tm; #if pdp11 || vax int abuf[BSIZE*2/sizeof(int)]; int nbad, badflg; #endif #ifdef pdp11 long txtsiz, datsiz, stksiz; int septxt; int lw=(lflg?35:80); #endif int match, i; int nbytes; int uzero = 0; register char **ttyp, *str; #ifndef u3b int ww; int adrv0, cnt; int *ip1; #endif /* if process is zombie, call print routine and return */ if (mproc.p_stat==SZOMB) { if ( tflg && !found) return(0); else { przom(puid); return(1); } } /* Determine if process is in memory or swap space */ /* and read in user block */ #ifdef u3b if (mproc.p_flag & SLOAD) { addr = mproc.p_uptbl[0] & PT_ADDR; file = swmem; } else { addr = ( mproc.p_swaddr + swplo + (( mproc.p_size - USIZE ) * 4 )) <<9; file = swap; procaddr = mproc.p_swaddr;; } if (file >= 0) { lseek(file, addr, 0); if ((nbytes = read(file, &u, sizeof(u))) != sizeof(u)) if ((nbytes == 0) && sflg && (file == swap)) { uzero++; for ( i = 0, tp = (char *)&u; i < sizeof(u); i++) *tp++ = '\0'; } else return(0); } else { /* swap device open failed */ for ( i = 0, tp = (char *)&u; i < sizeof(u); i++) *tp++ = '\0'; for ( i = 0 , tp = "<NOSWAP>"; i < 8; i++) u.u_comm[i] = *tp++; uzero++; } #endif /* u3b */ #ifdef vax if ((mproc.p_flag& (SLOAD | SSPART)) == 0) { addr = (mproc.p_swaddr+swplo+mproc.p_swsize-USIZE)<<9; mf = swap; l_lseek(mf, addr, 0); if ((nbytes = read(mf, (char *)&u, sizeof(u))) != sizeof(u)) { if (( nbytes == 0) && sflg) { uzero++; for ( i = 0, tp = (char *) &u; i < sizeof(u); i++) *tp++ = '\0'; } else return(0); } } else { ww = (int)(mproc.p_spt + (mproc.p_nspt-1)*128); ww = sbrpte + ((ww&0x3fffffff)>>9)*4; l_lseek(swmem,(long)ww&0x3fffffff,0); r_read(swmem,&spte, 4); l_lseek(swmem,(spte<<9),0); r_read(swmem, upte, sizeof upte); for(c=0; c<USIZE; c++) { l_lseek(swmem, upte[128-USIZE+c]<<9, 0); if (read(swmem,(char *)(((int *)&u)+128*c),512) != 512) /* get u page */ return(0); if(sizeof(struct user) - (c + 1) * 512 <= 0) break; } } #endif #ifdef pdp11 if (mproc.p_flag&SLOAD) { addr = ctob((long)mproc.p_addr); file = swmem; } else { addr = (mproc.p_addr+swplo)<<9; file = swap; } l_lseek(file, addr, 0); if ((nbytes = read(file, (char *)&u, sizeof(u))) != sizeof(u)) if (( nbytes == 0) && sflg && (file == swap)) { uzero++; for ( i = 0, tp = (char *) &u; i < sizeof(u); i++) *tp++ = '\0'; } else return(0); #endif /* get current terminal - if none (?) and aflg is set */ /* then don't print info - if tflg is set, check if term */ /* is in list of desired terminals and print if so */ tp = gettty(); if ( aflg && (*tp == '?' )) return(0); if(tflg && !found) { /* the t option */ for (ttyp=tty, match=0; (str = *ttyp) !=0 && !match; ttyp++) if (strcmp(tp,str) == 0) match++; if(!match) return(0); } if (lflg) printf("%3o %c", mproc.p_flag&0377, "OSWRIZTXX"[mproc.p_stat]); /* F S */ if (fflg) { i = getunam(puid); if (i >= 0) printf("%7s", ud[i].name); else printf("%7u", puid); } else if (lflg) printf("%6u", puid); printf("%6u",mproc.p_pid); /* PID */ if (lflg || fflg) printf("%6u%3d", mproc.p_ppid, mproc.p_cpu&0377); /* PPID CPU */ if (lflg) { printf("%4d%3d",mproc.p_pri, mproc.p_nice); /* PRI NICE */ #if vax || u3b printf("%7x%4d", #ifdef vax mproc.p_addr, #else procaddr, #endif mproc.p_size); /* ADDR SZ */ if (mproc.p_wchan) printf("%9x",mproc.p_wchan); /* WCHAN */ else printf(" "); #endif #ifdef pdp11 printf("%8o%3d", mproc.p_addr, (mproc.p_size+7)>>3); if (mproc.p_wchan) printf("%9o", mproc.p_wchan); else printf(" "); #endif } if (uzero) /* u-block zeroed out so return */ return(1); if (fflg) { /* STIME*/ clock = &u.u_start; tim = time((time_t *) 0); tloc = &tim; s1 = ctime(tloc); strcpy(curtim,s1); sttim = ctime(clock); prtim(curtim, sttim); } printf(" %4.4s", tp); /* TTY */ tm = (u.u_utime + u.u_stime + HZ/2)/HZ; /* TIME */ printf(" %2ld:%.2ld", tm/60, tm%60); if (mproc.p_pid==0) { printf(" swapper"); return(1); } /* if fflg not set, print command from u_block */ if (!fflg) { /* CMD */ printf(" %.8s", u.u_comm); return(1); } /* set up address maps for user pcs */ #ifdef pdp11 txtsiz = ctob(u.u_tsize); datsiz = ctob(u.u_dsize); stksiz = ctob(u.u_ssize); septxt = u.u_sep; datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ)); datmap.e1=datmap.b1+datsiz; datmap.f1 = ctob(USIZE)+addr; datmap.b2 = stackbas(stksiz); datmap.e2 = stacktop(stksiz); datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr; /* determine if process is a shell or not */ /* if last word is null then shell */ addr += ctob(mproc.p_size) - sizeof(abuf); l_lseek(file, addr+sizeof(abuf)-sizeof(int), 0); if (read(file, (char *)abuf, sizeof(int)) != sizeof(int)) return(1); if (abuf[0]&0177400) { char b[82]; char *bp = b; char **ap = abuf[0]; char *cp; *bp++ = ' '; badflg = 0; while((cp=(char *)getword(ap++)) != -1 && cp && (bp < b+lw)){ nbad = 0; while((c = getbyte(cp++)) && (int)(cp) != 0177777 && (bp < b + lw)){ badflg++; if (c < ' ' || c > '~') { if (nbad++ > 3) break; continue; } *bp++ = c; } *bp++ = ' '; } *bp++ = '\0'; if ( badflg == 0 || nbad != 0 || *b == '\0' ) printf(" [ %.8s ]",u.u_comm); else printf("%.20s",b); return(1); } l_lseek(file, addr, 0); if (read(file, (char *)abuf, sizeof(abuf)) != sizeof(abuf)) return(1); #endif #ifdef vax if ((mproc.p_flag & SLOAD) == 0) { addr -= sizeof(abuf); l_lseek(mf, addr, 0); if (read(mf, (char *)abuf, sizeof(abuf)) != sizeof(abuf)) return(1); } else { l_lseek(swmem,ctob((upte[128-USIZE-2] & 0x1fffff)),0); if (read(swmem,(char *)abuf,512) != 512) return(1); l_lseek(swmem,ctob((upte[128-USIZE-1] & 0x1fffff)),0); if (read(swmem,(char *)&abuf[128],512) != 512) return(1); } #endif #ifndef u3b badflg = 0; for (ip = &abuf[BSIZE*2/sizeof(int)-sizeof(int)]; ip > abuf;) { if (*--ip == -1 || *ip == 0) { cp = (char *)(ip+1); if (*cp==0) cp++; nbad = 0; /* find argc */ cnt = 0; adrv0 = (int)(ip+1) - (int)(abuf) + (int)(USRSTACK - sizeof(abuf)); for (ip1 = ip; ip1 > abuf;) { if (*--ip1 == adrv0) { cnt = *(ip1 - 3); break; } } for (cp1 = cp; cp1 < (char *)&abuf[BSIZE*2/sizeof(int)]; cp1++) { badflg++; c = *cp1&0177; if (c==0) { if (--cnt <= 0) { *cp1++ = 0; break; } else { *cp1 = ' '; } } else if (c < ' ' || c > '~') { if (++nbad >= 3) { *cp1++ = ' '; break; } *cp1 = '?'; } } while (*--cp1==' ') *cp1 = 0; if ( cnt != 0 || badflg == 0 || nbad != 0 || *cp == '\0') printf(" [ %.8s ]",u.u_comm); else printf(lflg?" %.35s":" %.80s", cp); return(1); } } printf(" [ %.8s ]",u.u_comm); #endif #ifdef u3b if (file == swmem) { lseek(file, segptbl(prc.p_stbl[NSEGP-STACKSEG]), 0); read(file, &page, sizeof(page)); lseek(file, page & PT_ADDR, 0); } else if (file >= 0) lseek(file, addr - ptob(u.u_ssize), 0); read(file, &page, sizeof(page)); /* argc */ read(file, line, sizeof (line)); if (page == 0) { printf(" [ %.8s ]", u.u_comm); } else { for (i = 0; i < sizeof(line); i++) if (line[i] == 0) if (--page == 0) break; else if (line[i+1]) line[i] = ' '; else break; printf(lflg?" %.35s":" %.80s", line); } #endif return(1); } /* file handling and access routines */ #ifdef pdp11 getbyte(adr) pos adr; { return((int)access(adr,1)); } getword(adr) pos adr; { return((int)access(adr,sizeof(int*))); } access(aadr,size) pos aadr; int size; { int *word = 0; register struct map *amap = &datmap; long adr = aadr; if(!within(aadr,amap->b1,amap->e1)) { if(within(aadr,amap->b2,amap->e2)) adr += (amap->f2)-(amap->b2); else return(0); } else { adr += (amap->f1)-(amap->b1); } if(lseek(file,adr,0)==-1 || read(file,(char *)&word,size)<size) { return(0); } return((int)word); } within(adr,lbd,ubd) pos adr; long lbd, ubd; { return(adr>=lbd && adr<ubd); } #endif done(exitno) { exit(exitno); } /* search returns 1 if arg is found in array arr */ /* which has length num, and returns 0 if not found */ search(arr, num, arg) int arr[]; int num; int arg; { int i; for (i = 0; i < num; i++) if (arg == arr[i]) return(1); return(0); } /* after the u option */ uconv() { int found; int pwuid; int i, j; /* search thru name array for oarg */ for (i=0; i<nut; i++) { found = -1; for(j=0; j<nud; j++) { if (strncmp(uid_tbl[i].name, ud[j].name, MAXLOGIN)==0) { found = j; break; } } /* if not found and oarg is numeric */ /* then search through number array */ if (found < 0 && (uid_tbl[i].name[0] >= '0' && uid_tbl[i].name[0] <= '9')) { pwuid = atoi(uid_tbl[i].name); for (j=0; j<nud; j++) { if (pwuid == ud[j].uid) { found = j; break; } } } /* if found then enter found index into tbl array */ if ( found != -1 ) { uid_tbl[i].uid = ud[found].uid; strncpy(uid_tbl[i].name,ud[found].name,MAXLOGIN); }else { for(j=i+1; j<nut; j++) { strncpy(uid_tbl[j-1].name,uid_tbl[j].name,MAXLOGIN); } nut--; i--; } } return; } /* for full command (-f flag) print user name instead of number */ /* search thru existing table of userid numbers and if puid is found, */ /* return corresponding name. Else search thru /etc/passwd */ getunam(puid) int puid; { int i; for(i=0; i<nud; i++) if(ud[i].uid == puid) return(i); return(-1); } /* ufind will return 1 if puid is in table ; if not return 0 */ ufind(puid) int puid; { int i; for(i=0; i<nut; i++) if(uid_tbl[i].uid == puid) return(1); return(0); } /* lseek with error checking */ l_lseek(fd, offset, whence) int fd, whence; long offset; { if (lseek(fd, offset, whence) == -1) { fprintf(stderr, "ps: error on lseek\n"); done(1); } } /* read with error checking */ r_read (fd, buf, nbytes) int fd, nbytes; char *buf; { if (read(fd, buf, nbytes) != nbytes) { fprintf(stderr, "ps: error on read\n"); done(1); } } /* special read unlinks psfile on read error */ psread(fd, bp, bs) int fd; char *bp; unsigned bs; { if(read(fd, bp, bs) != bs) { fprintf(stderr, "ps: error on read\n"); unlink(psfile); } } /* special write unlinks psfile on read error */ pswrite(fd, bp, bs) int fd; char *bp; unsigned bs; { if(write(fd, bp, bs) != bs) { fprintf(stderr, "ps: error on write\n"); unlink(psfile); } } /* print starting time of process unless process started more */ /* than 24 hours ago in which case date is printed */ /* sttim is start time and it is compared to curtim (current time ) */ prtim(curtim, sttim) char *curtim, *sttim; { char *p1, *p2; char dayst[3], daycur[3]; if ( strncmp(curtim, sttim, 11) == 0) { p1 = sttim + 11; p2 = p1 + 8; } else { p1 = sttim + 4; p2 = p1 + 7; /* if time is < 24 hours different, then print time */ if (strncmp(curtim+4, sttim+4, 3) == 0) { strncpy(dayst,sttim+8, 2); strcat(dayst,""); strncpy(daycur,curtim+8,2); strcat(daycur,""); if ((atoi(dayst) +1 == atoi(daycur)) && (strncmp(curtim+11,sttim+11,8)<=0)) { p1 = sttim + 11; p2 = p1 + 8; } } } *p2 = '\0'; printf("%9s",p1); } #ifdef u3b #define xp_flag p_flag #define xp_stat p_stat #define xp_pid p_pid #define xp_ppid p_ppid #define xp_cpu p_cpu #define xp_pri p_pri #define xp_nice p_nice #define xp_utime p_utime #define xp_stime p_stime #endif przom(puid) /* print zombie process - zproc overlays mproc */ int puid; { int i; long tm; if (lflg) printf("%3o %c", zproc.xp_flag&0377, "OSWRIZT"[zproc.xp_stat]); /* F S */ if (fflg) { i = getunam(puid); if (i >= 0) printf("%7s", ud[i].name); else printf("%7u", puid); } else if (lflg) printf("%6u", puid); printf("%6u",zproc.xp_pid); /* PID */ if (lflg || fflg) printf("%6u%3d", zproc.xp_ppid, zproc.xp_cpu&0377); /* PPID CPU */ if (lflg) printf("%4d%3d",zproc.xp_pri, zproc.xp_nice); /* PRI NICE */ if (fflg) printf(" "); if (lflg) printf(" "); tm = (zproc.xp_utime + zproc.xp_stime + HZ/2)/HZ; /* TIME */ printf(" %2ld:%.2ld", tm/60, tm%60); printf(" <defunct>"); return; }