📄 minimal.c
字号:
P_start_time = p.pr_start.tv_sec; P_wchan = p.pr_lwp.pr_wchan; P_state = p.pr_lwp.pr_sname; P_nice = p.pr_lwp.pr_nice; P_priority = p.pr_lwp.pr_pri; // or pr_oldpri// P_ruid = p.pr_uid;// P_rgid = p.pr_gid;// P_egid = p.pr_egid;#if 0 // don't support these P_tpgid; P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime; P_cutime, P_cstime, P_timeout, P_alarm; P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip; P_signal, P_blocked, P_sigignore, P_sigcatch; P_nswap, P_cnswap;#endif // we like it Linux-encoded :-) tty_maj = major(p.pr_ttydev); tty_min = minor(p.pr_ttydev); P_tty_num = DEV_ENCODE(tty_maj,tty_min); snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);#if 1 if (tty_maj == 24) snprintf(P_tty_text, sizeof P_tty_text, "pts/%-3u", tty_min); if (P_tty_num == NO_TTY_VALUE) memcpy(P_tty_text, " ? ", 8); if (P_tty_num == DEV_ENCODE(0,0)) memcpy(P_tty_text, "console", 8);#endif if(P_pid != pid) return 0; return 1;}#endif#ifdef __FreeBSD__/* return 1 if it works, or 0 for failure */static int stat2proc(int pid) { char buf[400]; int num; int fd; char* tmp; int tty_maj, tty_min; snprintf(buf, 32, "/proc/%d/status", pid); if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0; num = read(fd, buf, sizeof buf - 1); close(fd); if(num<43) return 0; buf[num] = '\0'; P_state = '-'; // FreeBSD /proc/*/status is seriously fucked. Unlike the Linux // files, we can't use strrchr to find the end of a command name. // Spaces in command names do not get escaped. To avoid spoofing, // one may skip 20 characters and then look _forward_ only to // find a pattern of entries that are {with,with,without} a comma. // The entry without a comma is wchan. Then count backwards! // // Don't bother for now. FreeBSD isn't worth the trouble. tmp = strchr(buf,' '); num = tmp - buf; if (num >= sizeof P_cmd) num = sizeof P_cmd - 1; memcpy(P_cmd,buf,num); P_cmd[num] = '\0'; num = sscanf(tmp+1, "%d %d %d %d " "%d,%d " "%*s " "%ld,%*d " "%ld,%*d " "%ld,%*d " "%*s " "%d %d ", &P_pid, &P_ppid, &P_pgrp, &P_session, &tty_maj, &tty_min, /* SKIP funny flags thing */ &P_start_time, /* SKIP microseconds */ &P_utime, /* SKIP microseconds */ &P_stime, /* SKIP microseconds */ /* SKIP &P_wchan, for now -- it is a string */ &P_euid, &P_euid // don't know which is which );/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */ snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min); P_tty_num = DEV_ENCODE(tty_maj,tty_min);// tty decode is 224 to 256 bytes on i386#if 1 tmp = NULL; if (tty_maj == 5) tmp = " ttyp%c "; if (tty_maj == 12) tmp = " ttyv%c "; if (tty_maj == 28) tmp = " ttyd%c "; if (P_tty_num == NO_TTY_VALUE) tmp = " ? "; if (P_tty_num == DEV_ENCODE(0,0)) tmp = "console"; if (P_tty_num == DEV_ENCODE(12,255)) tmp = "consolectl"; if (tmp) { snprintf( P_tty_text, sizeof P_tty_text, tmp, "0123456789abcdefghijklmnopqrstuvwxyz"[tty_min&31] ); }#endif if(num < 9) return 0; if(P_pid != pid) return 0; return 1;}#endif#ifdef __linux__/* return 1 if it works, or 0 for failure */static int stat2proc(int pid) { char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */ int num; int fd; char* tmp; struct stat sb; /* stat() used to get EUID */ snprintf(buf, 32, "/proc/%d/stat", pid); if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0; num = read(fd, buf, sizeof buf - 1); fstat(fd, &sb); P_euid = sb.st_uid; close(fd); if(num<80) return 0; buf[num] = '\0'; tmp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ *tmp = '\0'; /* replace trailing ')' with NUL */ /* parse these two strings separately, skipping the leading "(". */ memset(P_cmd, 0, sizeof P_cmd); /* clear */ sscanf(buf, "%d (%15c", &P_pid, P_cmd); /* comm[16] in kernel */ num = sscanf(tmp + 2, /* skip space after ')' too */ "%c " "%d %d %d %d %d " "%lu %lu %lu %lu %lu %lu %lu " "%ld %ld %ld %ld %ld %ld " "%lu %lu " "%ld " "%lu %lu %lu %lu %lu %lu " "%u %u %u %u " /* no use for RT signals */ "%lu %lu %lu", &P_state, &P_ppid, &P_pgrp, &P_session, &P_tty_num, &P_tpgid, &P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime, &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_alarm, &P_start_time, &P_vsize, &P_rss, &P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip, &P_signal, &P_blocked, &P_sigignore, &P_sigcatch, &P_wchan, &P_nswap, &P_cnswap );/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */ P_vsize /= 1024; P_rss *= (PAGE_SIZE/1024); memcpy(P_tty_text, " ? ", 8); if (P_tty_num != NO_TTY_VALUE) { int tty_maj = (P_tty_num>>8)&0xfff; int tty_min = (P_tty_num&0xff) | ((P_tty_num>>12)&0xfff00); snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min); } if(num < 30) return 0; if(P_pid != pid) return 0; return 1;}#endifstatic const char *do_time(unsigned long t){ int hh,mm,ss; static char buf[32]; int cnt = 0; t /= HZ; ss = t%60; t /= 60; mm = t%60; t /= 60; hh = t%24; t /= 24; if(t) cnt = snprintf(buf, sizeof buf, "%d-", (int)t); snprintf(cnt + buf, sizeof(buf)-cnt, "%02d:%02d:%02d", hh, mm, ss); return buf;}static const char *do_user(void){ static char buf[32]; static struct passwd *p; static int lastuid = -1; if(P_euid != lastuid){ p = getpwuid(P_euid); if(p) snprintf(buf, sizeof buf, "%-8.8s", p->pw_name); else snprintf(buf, sizeof buf, "%5d ", P_euid); } return buf;}static const char *do_cpu(int longform){ static char buf[8]; strcpy(buf," - "); if(!longform) buf[2] = '\0'; return buf;}static const char *do_mem(int longform){ static char buf[8]; strcpy(buf," - "); if(!longform) buf[2] = '\0'; return buf;}static const char *do_stime(void){ static char buf[32]; strcpy(buf," - "); return buf;}static void print_proc(void){ switch(ps_format){ case 0: printf("%5d %s %s", P_pid, P_tty_text, do_time(P_utime+P_stime)); break; case 'o': printf("%d\n", P_pid); return; /* don't want the command */ case 'l': printf( "0 %c %5d %5d %5d %s %3d %3d - " "%5ld %06x %s %s", P_state, P_euid, P_pid, P_ppid, do_cpu(0), (int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024), (unsigned)(P_wchan&0xffffff), P_tty_text, do_time(P_utime+P_stime) ); break; case 'f': printf( "%8s %5d %5d %s %s %s %s", do_user(), P_pid, P_ppid, do_cpu(0), do_stime(), P_tty_text, do_time(P_utime+P_stime) ); break; case 'j': printf( "%5d %5d %5d %s %s", P_pid, P_pgrp, P_session, P_tty_text, do_time(P_utime+P_stime) ); break; case 'u'|0x80: printf( "%8s %5d %s %s %5ld %4ld %s %c %s %s", do_user(), P_pid, do_cpu(1), do_mem(1), P_vsize, P_rss, P_tty_text, P_state, do_stime(), do_time(P_utime+P_stime) ); break; case 'v'|0x80: printf( "%5d %s %c %s %6d - - %5d %s", P_pid, P_tty_text, P_state, do_time(P_utime+P_stime), (int)P_maj_flt, (int)P_rss, do_mem(1) ); break; case 'j'|0x80: printf( "%5d %5d %5d %5d %s %5d %c %5d %s", P_ppid, P_pid, P_pgrp, P_session, P_tty_text, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime) ); break; case 'l'|0x80: printf( "0 %5d %5d %5d %3d %3d " "%5ld %4ld %06x %c %s %s", P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice, P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, P_tty_text, do_time(P_utime+P_stime) ); break; default: ; } if(show_args) printf(" [%s]\n", P_cmd); else printf(" %s\n", P_cmd);}int main(int argc, char *argv[]){ arg_parse(argc, argv);#if 0 choose_dimensions();#endif if(!old_h_option){ const char *head; switch(ps_format){ default: /* can't happen */ case 0: head = " PID TTY TIME CMD"; break; case 'l': head = "F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD"; break; case 'f': head = "USER PID PPID C STIME TTY TIME CMD"; break; case 'j': head = " PID PGID SID TTY TIME CMD"; break; case 'u'|0x80: head = "USER PID %CPU %MEM VSZ RSS TTY S START TIME COMMAND"; break; case 'v'|0x80: head = " PID TTY S TIME MAJFL TRS DRS RSS %MEM COMMAND"; break; case 'j'|0x80: head = " PPID PID PGID SID TTY TPGID S UID TIME COMMAND"; break; case 'l'|0x80: head = "F UID PID PPID PRI NI VSZ RSS WCHAN S TTY TIME COMMAND"; break; } printf("%s\n",head); } if(want_one_pid){ if(stat2proc(want_one_pid)) print_proc(); else exit(1); }else{ struct dirent *ent; /* dirent handle */ DIR *dir; int ouruid; int found_a_proc; found_a_proc = 0; ouruid = getuid(); dir = opendir("/proc"); while(( ent = readdir(dir) )){ if(*ent->d_name<'0' || *ent->d_name>'9') continue; if(!stat2proc(atoi(ent->d_name))) continue; if(want_one_command){ if(strcmp(want_one_command,P_cmd)) continue; }else{ if(!select_notty && P_tty_num==NO_TTY_VALUE) continue; if(!select_all && P_euid!=ouruid) continue; } found_a_proc++; print_proc(); } closedir(dir); exit(!found_a_proc); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -