ps.c revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
1#include <stdio.h> 2#include <stdlib.h> 3#include <ctype.h> 4#include <fcntl.h> 5 6#include <string.h> 7 8#include <sys/stat.h> 9#include <sys/types.h> 10#include <dirent.h> 11 12#include <pwd.h> 13 14 15static char *nexttoksep(char **strp, char *sep) 16{ 17 char *p = strsep(strp,sep); 18 return (p == 0) ? "" : p; 19} 20static char *nexttok(char **strp) 21{ 22 return nexttoksep(strp, " "); 23} 24 25#define SHOW_PRIO 1 26#define SHOW_TIME 2 27 28static int display_flags = 0; 29 30static int ps_line(int pid, int tid, char *namefilter) 31{ 32 char statline[1024]; 33 char cmdline[1024]; 34 char user[32]; 35 struct stat stats; 36 int fd, r; 37 char *ptr, *name, *state; 38 int ppid, tty; 39 unsigned wchan, rss, vss, eip; 40 unsigned utime, stime; 41 int prio, nice, rtprio, sched; 42 struct passwd *pw; 43 44 sprintf(statline, "/proc/%d", pid); 45 stat(statline, &stats); 46 47 if(tid) { 48 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid); 49 cmdline[0] = 0; 50 } else { 51 sprintf(statline, "/proc/%d/stat", pid); 52 sprintf(cmdline, "/proc/%d/cmdline", pid); 53 fd = open(cmdline, O_RDONLY); 54 if(fd == 0) { 55 r = 0; 56 } else { 57 r = read(fd, cmdline, 1023); 58 close(fd); 59 if(r < 0) r = 0; 60 } 61 cmdline[r] = 0; 62 } 63 64 fd = open(statline, O_RDONLY); 65 if(fd == 0) return -1; 66 r = read(fd, statline, 1023); 67 close(fd); 68 if(r < 0) return -1; 69 statline[r] = 0; 70 71 ptr = statline; 72 nexttok(&ptr); // skip pid 73 ptr++; // skip "(" 74 75 name = ptr; 76 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')', 77 *ptr++ = '\0'; // and null-terminate name. 78 79 ptr++; // skip " " 80 state = nexttok(&ptr); 81 ppid = atoi(nexttok(&ptr)); 82 nexttok(&ptr); // pgrp 83 nexttok(&ptr); // sid 84 tty = atoi(nexttok(&ptr)); 85 86 nexttok(&ptr); // tpgid 87 nexttok(&ptr); // flags 88 nexttok(&ptr); // minflt 89 nexttok(&ptr); // cminflt 90 nexttok(&ptr); // majflt 91 nexttok(&ptr); // cmajflt 92#if 1 93 utime = atoi(nexttok(&ptr)); 94 stime = atoi(nexttok(&ptr)); 95#else 96 nexttok(&ptr); // utime 97 nexttok(&ptr); // stime 98#endif 99 nexttok(&ptr); // cutime 100 nexttok(&ptr); // cstime 101 prio = atoi(nexttok(&ptr)); 102 nice = atoi(nexttok(&ptr)); 103 nexttok(&ptr); // threads 104 nexttok(&ptr); // itrealvalue 105 nexttok(&ptr); // starttime 106 vss = strtoul(nexttok(&ptr), 0, 10); // vsize 107 rss = strtoul(nexttok(&ptr), 0, 10); // rss 108 nexttok(&ptr); // rlim 109 nexttok(&ptr); // startcode 110 nexttok(&ptr); // endcode 111 nexttok(&ptr); // startstack 112 nexttok(&ptr); // kstkesp 113 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip 114 nexttok(&ptr); // signal 115 nexttok(&ptr); // blocked 116 nexttok(&ptr); // sigignore 117 nexttok(&ptr); // sigcatch 118 wchan = strtoul(nexttok(&ptr), 0, 10); // wchan 119 nexttok(&ptr); // nswap 120 nexttok(&ptr); // cnswap 121 nexttok(&ptr); // exit signal 122 nexttok(&ptr); // processor 123 rtprio = atoi(nexttok(&ptr)); // rt_priority 124 sched = atoi(nexttok(&ptr)); // scheduling policy 125 126 tty = atoi(nexttok(&ptr)); 127 128 if(tid != 0) { 129 ppid = pid; 130 pid = tid; 131 } 132 133 pw = getpwuid(stats.st_uid); 134 if(pw == 0) { 135 sprintf(user,"%d",(int)stats.st_uid); 136 } else { 137 strcpy(user,pw->pw_name); 138 } 139 140 if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) { 141 printf("%-8s %-5d %-5d %-5d %-5d", user, pid, ppid, vss / 1024, rss * 4); 142 if(display_flags&SHOW_PRIO) 143 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched); 144 printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name); 145 if(display_flags&SHOW_TIME) 146 printf(" (u:%d, s:%d)", utime, stime); 147 printf("\n"); 148 } 149 return 0; 150} 151 152 153void ps_threads(int pid, char *namefilter) 154{ 155 char tmp[128]; 156 DIR *d; 157 struct dirent *de; 158 159 sprintf(tmp,"/proc/%d/task",pid); 160 d = opendir(tmp); 161 if(d == 0) return; 162 163 while((de = readdir(d)) != 0){ 164 if(isdigit(de->d_name[0])){ 165 int tid = atoi(de->d_name); 166 if(tid == pid) continue; 167 ps_line(pid, tid, namefilter); 168 } 169 } 170 closedir(d); 171} 172 173int ps_main(int argc, char **argv) 174{ 175 DIR *d; 176 struct dirent *de; 177 char *namefilter = 0; 178 int pidfilter = 0; 179 int threads = 0; 180 181 d = opendir("/proc"); 182 if(d == 0) return -1; 183 184 while(argc > 1){ 185 if(!strcmp(argv[1],"-t")) { 186 threads = 1; 187 } else if(!strcmp(argv[1],"-x")) { 188 display_flags |= SHOW_TIME; 189 } else if(!strcmp(argv[1],"-p")) { 190 display_flags |= SHOW_PRIO; 191 } else if(isdigit(argv[1][0])){ 192 pidfilter = atoi(argv[1]); 193 } else { 194 namefilter = argv[1]; 195 } 196 argc--; 197 argv++; 198 } 199 200 printf("USER PID PPID VSIZE RSS %sWCHAN PC NAME\n", 201 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":""); 202 while((de = readdir(d)) != 0){ 203 if(isdigit(de->d_name[0])){ 204 int pid = atoi(de->d_name); 205 if(!pidfilter || (pidfilter == pid)) { 206 ps_line(pid, 0, namefilter); 207 if(threads) ps_threads(pid, namefilter); 208 } 209 } 210 } 211 closedir(d); 212 return 0; 213} 214 215