sources-request@mirror.UUCP (08/01/86)
Submitted by: "Michael A. Callahan" <cca!uokvax!mikec> Mod.sources: Volume 6, Issue 83 Archive-name: bsd.ps.patch [ I ran this on a 4.2BSD 750, and it worked. I took Mike's initial comments, formatted them into the manpage, and published the diff as part of the sharefile. I also threw together the Makefile. The technique of storing data that changes infrequently in a file in order to speed up ps is probably a good one for any Un*x system, and is in fact done in other versions of ps I've seen. Sorry the diffs aren't context; Mike's weren't, and I opted for consistency. --r$ ] The diff's that follow are speedup modifications for ps.c. These mods cut the system time of ps by more than half, and trim back the user time a bit also. The main difference is that the ttys in /dev are not stat'ed each time ps runs. Instead a file is created in /etc when the machine boots via /etc/rc, and that file is used instead. Also in this file is kept a name list of /vmunix. Mike Callahan University of Oklahoma ihnp4!okstate!uokvax!mikec cbosgd!okstate!uokvax!mikec #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # Wrapped by rs@mirror.UUCP on Fri Jul 25 19:38:44 EDT 1986 # Contents: Makefile ps.1.patch ps.c.patch echo x - Makefile sed 's/^XX//' > "Makefile" <<'@//E*O*F Makefile//' XXCFLAGS=-O -DECN XXps: ps.c XX cc $(CFLAGS) -o ps ps.c -lm @//E*O*F Makefile// chmod u=rw,g=rw,o=rw Makefile echo x - ps.1.patch sed 's/^XX//' > "ps.1.patch" <<'@//E*O*F ps.1.patch//' XX135,163d134 XX< .TP 5 XX< .B U XX< This flag instructs XX< .I ps XX< recreate its data files; all the files in XX< .I /etc/ttys XX< are stat'd, and the data is recorded in XX< .IR /etc/psdatabase ; XX< the namelist of XX< .I /vmunix XX< is stored in XX< .IR /etc/psdatabase . XX< This information changes only when the ttys are changed, or when a new XX< kernel is booted. XX< It is a good idea to put ``/bin/ps -U'' in XX< .IR /etc/rc.local . XX< .TP 5 XX< .BI L login XX< This flag will do a ``ps x'' as the login name specified; i.e., is as XX< if the user with the indicated login name had run the command. XX< .TP 5 XX< .B R XX< This will show the running processes in the system; it is faster than XX< .IR top (1L). XX< .TP 5 XX< .BI N # XX< This flag will show all processes with a nice value greater than XX< or equal to #; e.g., ``ps lN4'' shows all the automatically-niced XX< processes. @//E*O*F ps.1.patch// chmod u=rw,g=rw,o=rw ps.1.patch echo x - ps.c.patch sed 's/^XX//' > "ps.c.patch" <<'@//E*O*F ps.c.patch//' XX% diff ps.c.old ps.c XX21a22,24 XX> #ifdef ECN XX> #include <sys/file.h> XX> #endif XX23a27 XX> #ifdef ECN /* share nlist with w so keep fields same */ XX48a53,58 XX> { "_swapdev" }, XX> #define X_SWAPDEV 12 XX> { "_avenrun" }, XX> #define X_AVENRUN 13 XX> { "_boottime" }, XX> #define X_BOOTTIME 14 XX50a61,89 XX> #else XX> struct nlist nl[] = { XX> { "_proc" }, XX> #define X_PROC 0 XX> { "_Usrptmap" }, XX> #define X_USRPTMA 1 XX> { "_usrpt" }, XX> #define X_USRPT 2 XX> { "_text" }, XX> #define X_TEXT 3 XX> { "_nswap" }, XX> #define X_NSWAP 4 XX> { "_maxslp" }, XX> #define X_MAXSLP 5 XX> { "_ccpu" }, XX> #define X_CCPU 6 XX> { "_ecmx" }, XX> #define X_ECMX 7 XX> { "_nproc" }, XX> #define X_NPROC 8 XX> { "_ntext" }, XX> #define X_NTEXT 9 XX> { "_dmmin" }, XX> #define X_DMMIN 10 XX> { "_dmmax" }, XX> #define X_DMMAX 11 XX> { "" }, XX> }; XX> #endif XX91a131,133 XX> #ifdef ECN XX> struct proc proc[400]; /* 400 = a few, for less syscalls */ XX> #else XX92a135 XX> #endif XX106a150,153 XX> #ifdef ECN XX> int Rflg, Nflg, nvalue, Uflg; XX> char *mylogin, *lptr; XX> #endif XX139a187,189 XX> #ifdef ECN XX> char bigoutbuf[BUFSIZ]; XX> #endif ECN XX150a201,203 XX> #ifdef ECN XX> setbuffer(stdout, bigoutbuf, BUFSIZ); XX> #endif ECN XX198a252,280 XX> #ifdef ECN XX> case 'R': XX> Rflg++; XX> xflg++; XX> gflg++; XX> aflg++; XX> break; XX> case 'L': XX> if (*ap) XX> lptr = ap; XX> xflg++; XX> gflg++; XX> while (*ap) XX> ap++; XX> break; XX> case 'N': XX> if (*ap) XX> nvalue = atoi(ap) + 20; XX> aflg++; XX> gflg++; XX> xflg++; XX> Nflg++; XX> while (*ap) XX> ap++; XX> break; XX> case 'U': XX> Uflg++; XX> break; XX> #endif XX231a314,325 XX> #ifdef ECN XX> if (lptr) { XX> struct passwd *pw, *getpwnam(); XX> if ((pw = getpwnam(lptr)) == NULL) { XX> fprintf(stderr, "Unknown user: %s\n", lptr); XX> exit(1); XX> } else { XX> uid = pw->pw_uid; XX> } XX> } else XX> uid = getuid(); XX> #else XX232a327 XX> #endif ECN XX236a332,334 XX> #ifdef ECN XX> for (i=0; i<nproc; i += 400) { XX> #else XX237a336 XX> #endif XX240,241c339,345 XX< if (j > 8) XX< j = 8; XX--- XX> #ifdef ECN XX> if (j > 400) XX> j = 400; XX> #else XX> if (j > 400) XX> j = 400; XX> #endif XX252a357,367 XX> if (Rflg) { XX> if (mproc->p_stat == SRUN) XX> save(); XX> continue; XX> } XX> if (Nflg) { XX> if ((int)mproc->p_nice >= nvalue) { XX> save(); XX> } XX> continue; XX> } XX358a474,490 XX> #ifdef ECN XX> register int fd; XX> if (Uflg) XX> return; XX> else { XX> if (argc > 1) XX> nlist(argv[1],nl); XX> else { XX> if ((fd = open("/etc/psnlist", O_RDONLY)) < 0) XX> nlist("/vmunix", nl); XX> else { XX> read(fd, nl, sizeof(nl)); XX> close(fd); XX> } XX> } XX> } XX> #else XX360a493 XX> #endif ECN XX436a570,575 XX> #ifdef ECN XX> #define MAXTTYS 150 XX> struct ttys *hash_ttys[256]; /* 256 used to find minor */ XX> struct ttys saved_tty_stat[MAXTTYS]; /* fixed sized used to quickly read in */ XX> int next_stty = 0; XX> XX438a578,667 XX> register int fd; XX> XX> if (Uflg) { XX> if ((fd = open("/etc/psnlist", O_CREAT|O_RDWR, 0444)) >= 0) { XX> nlist("/vmunix", nl); XX> write(fd, nl, sizeof(nl)); XX> close(fd); XX> } else { XX> perror("/etc/psnlist"); XX> exit(1); XX> } XX> domanual(); XX> dosavettys(); XX> } XX> XX> if ((fd = open("/etc/psdatabase", O_RDONLY)) <= 0) { XX> domanual(); XX> return; XX> } XX> read(fd, hash_ttys, sizeof(hash_ttys)); XX> read(fd, saved_tty_stat, sizeof(saved_tty_stat)); XX> close(fd); XX> } XX> XX> dosavettys() XX> { XX> register int fd; XX> XX> if ((fd = open("/etc/psdatabase", O_CREAT|O_RDWR, 0444)) <= 0) XX> return; XX> write(fd, hash_ttys, sizeof(hash_ttys)); XX> write(fd, saved_tty_stat, sizeof(saved_tty_stat)); XX> close(fd); XX> exit(0); XX> } XX> XX> domanual() XX> { XX> register FILE *fp; XX> register int i; XX> register char c; XX> struct stat sbuf; XX> XX> if ((fp = fopen("/etc/ttys", "r")) == NULL) { XX> perror("/etc/ttys"); XX> exit(1); XX> } XX> i = 0; XX> while((c = getc(fp)) != EOF) { XX> if (c == '\n') { /* jump the first 2 chars */ XX> saved_tty_stat[next_stty].name[i] = '\0'; XX> i = 0; XX> if (stat(saved_tty_stat[next_stty].name,&sbuf)==0 && XX> (sbuf.st_mode & S_IFMT) == S_IFCHR) XX> saved_tty_stat[next_stty].ttyd = sbuf.st_rdev; XX> else XX> saved_tty_stat[next_stty].ttyd = -2; XX> saved_tty_stat[next_stty].next = XX> hash_ttys[saved_tty_stat[next_stty].ttyd % 256]; XX> hash_ttys[saved_tty_stat[next_stty].ttyd % 256] = XX> &saved_tty_stat[next_stty]; XX> next_stty++; XX> if ((c = getc(fp)) == EOF) XX> return; XX> if ((c = getc(fp)) == EOF) XX> return; XX> } else XX> saved_tty_stat[next_stty].name[i++] = c; XX> } XX> } XX> XX> char * XX> gettty() XX> { XX> register struct ttys *dp; XX> register char *p; XX> XX> for(dp = hash_ttys[u.u_ttyd % 256]; dp; dp = dp->next) XX> if (dp->ttyd == u.u_ttyd) { XX> p = dp->name; XX> if (p[0] == 't' && p[1] == 't' && p[2] == 'y') XX> p += 3; XX> return(p); XX> } XX> return("?"); XX> } XX> XX> #else ECN XX> getdev() XX> { XX596a826 XX> #endif ECN XX1103a1334,1336 XX> #ifdef ECN XX> struct passwd *getpwuid(); XX> #else XX1105a1339 XX> #endif XX1118a1353,1359 XX> #ifdef ECN XX> if ((pw = getpwuid(uid)) == NULL) XX> return((char *)NULL); XX> strncpy(n->nt_name, pw->pw_name, NMAX); XX> n->nt_uid = uid; XX> return(n->nt_name); XX> #else XX1145a1387 XX> #endif @//E*O*F ps.c.patch// chmod u=rw,g=rw,o=rw ps.c.patch echo Inspecting for damage in transit... temp=/tmp/sharin$$; dtemp=/tmp/sharout$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 3 10 54 Makefile 30 181 840 ps.1.patch 273 892 5101 ps.c.patch 306 1083 5995 total !!! wc Makefile ps.1.patch ps.c.patch | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if test -s $dtemp then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0