?? minimal.c
字號(hào):
/* * Copyright 1998,2004 by Albert Cahalan; all rights reserved. * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. *//* This is a minimal /bin/ps, designed to be smaller than the old ps * while still supporting some of the more important features of the * new ps. (for total size, note that this ps does not need libproc) * It is suitable for Linux-on-a-floppy systems only. * * Maintainers: do not compile or install for normal systems. * Anyone needing this will want to tweak their compiler anyway. */#include <pwd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/ioctl.h>#include <sys/types.h>#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>#include <dirent.h>#define DEV_ENCODE(M,m) ( \ ( (M&0xfff) << 8) | ( (m&0xfff00) << 12) | (m&0xff) \)///////////////////////////////////////////////////////#ifdef __sun__#include <sys/mkdev.h>#define _STRUCTURED_PROC 1#include <sys/procfs.h>#define NO_TTY_VALUE DEV_ENCODE(-1,-1)#define HZ 1 // only bother with seconds#endif///////////////////////////////////////////////////////#ifdef __FreeBSD__#include <sys/param.h>#include <sys/sysctl.h>#include <sys/stat.h>#include <sys/proc.h>#include <sys/user.h>#define NO_TTY_VALUE DEV_ENCODE(-1,-1)#define HZ 1 // only bother with seconds#endif///////////////////////////////////////////////////////#ifdef __linux__#include <asm/param.h> /* HZ */#include <asm/page.h> /* PAGE_SIZE */#define NO_TTY_VALUE DEV_ENCODE(0,0)#ifndef HZ#warning HZ not defined, assuming it is 100#define HZ 100#endif#endif///////////////////////////////////////////////////////////#ifndef PAGE_SIZE#warning PAGE_SIZE not defined, assuming it is 4096#define PAGE_SIZE 4096#endifstatic char P_tty_text[16];static char P_cmd[16];static char P_state;static int P_euid;static int P_pid;static int P_ppid, P_pgrp, P_session, P_tty_num, P_tpgid;static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_alarm;static unsigned long P_start_time, P_vsize;static long P_rss;static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;static unsigned P_signal, P_blocked, P_sigignore, P_sigcatch;static unsigned long P_wchan, P_nswap, P_cnswap;#if 0static int screen_cols = 80;static int w_count;#endifstatic int want_one_pid;static const char *want_one_command;static int select_notty;static int select_all;static int ps_format;static int old_h_option;/* we only pretend to support this */static int show_args; /* implicit with -f and all BSD options */static int bsd_c_option; /* this option overrides the above */static int ps_argc; /* global argc */static char **ps_argv; /* global argv */static int thisarg; /* index into ps_argv */static char *flagptr; /* current location in ps_argv[thisarg] */static void usage(void){ fprintf(stderr, "-C select by command name (minimal ps only accepts one)\n" "-p select by process ID (minimal ps only accepts one)\n" "-e all processes (same as ax)\n" "a all processes w/ tty, including other users\n" "x processes w/o controlling ttys\n" "-f full format\n" "-j,j job control format\n" "v virtual memory format\n" "-l,l long format\n" "u user-oriented format\n" "-o user-defined format (limited support, only \"ps -o pid=\")\n" "h no header\n"/* "-A all processes (same as ax)\n" "c true command name\n" "-w,w wide output\n"*/ ); exit(1);}/* * Return the next argument, or call the usage function. * This handles both: -oFOO -o FOO */static const char *get_opt_arg(void){ const char *ret; ret = flagptr+1; /* assume argument is part of ps_argv[thisarg] */ if(*ret) return ret; if(++thisarg >= ps_argc) usage(); /* there is nothing left */ /* argument is the new ps_argv[thisarg] */ ret = ps_argv[thisarg]; if(!ret || !*ret) usage(); return ret;}/* return the PID, or 0 if nothing good */static void parse_pid(const char *str){ char *endp; int num; if(!str) goto bad; num = strtol(str, &endp, 0); if(*endp != '\0') goto bad; if(num<1) goto bad; if(want_one_pid) goto bad; want_one_pid = num; return;bad: usage();}/***************** parse SysV options, including Unix98 *****************/static void parse_sysv_option(void){ do{ switch(*flagptr){ /**** selection ****/ case 'C': /* end */ if(want_one_command) usage(); want_one_command = get_opt_arg(); return; /* can't have any more options */ case 'p': /* end */ parse_pid(get_opt_arg()); return; /* can't have any more options */ case 'A': case 'e': select_all++; select_notty++;case 'w': /* here for now, since the real one is not used */ break; /**** output format ****/ case 'f': show_args = 1; /* FALL THROUGH */ case 'j': case 'l': if(ps_format) usage(); ps_format = *flagptr; break; case 'o': /* end */ /* We only support a limited form: "ps -o pid=" (yes, just "pid=") */ if(strcmp(get_opt_arg(),"pid=")) usage(); if(ps_format) usage(); ps_format = 'o'; old_h_option++; return; /* can't have any more options */ /**** other stuff ****/#if 0 case 'w': w_count++; break;#endif default: usage(); } /* switch */ }while(*++flagptr);}/************************* parse BSD options **********************/static void parse_bsd_option(void){ do{ switch(*flagptr){ /**** selection ****/ case 'a': select_all++; break; case 'x': select_notty++; break; case 'p': /* end */ parse_pid(get_opt_arg()); return; /* can't have any more options */ /**** output format ****/ case 'j': case 'l': case 'u': case 'v': if(ps_format) usage(); ps_format = 0x80 | *flagptr; /* use 0x80 to tell BSD from SysV */ break; /**** other stuff ****/ case 'c': bsd_c_option++;#if 0 break;#endif case 'w':#if 0 w_count++;#endif break; case 'h': old_h_option++; break; default: usage(); } /* switch */ }while(*++flagptr);}#if 0#include <termios.h>/* not used yet */static void choose_dimensions(void){ struct winsize ws; char *columns; /* screen_cols is 80 by default */ if(ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>30) screen_cols = ws.ws_col; columns = getenv("COLUMNS"); if(columns && *columns){ long t; char *endptr; t = strtol(columns, &endptr, 0); if(!*endptr && (t>30) && (t<(long)999999999)) screen_cols = (int)t; } if(w_count && (screen_cols<132)) screen_cols=132; if(w_count>1) screen_cols=999999999;}#endifstatic void arg_parse(int argc, char *argv[]){ int sel = 0; /* to verify option sanity */ ps_argc = argc; ps_argv = argv; thisarg = 0; /**** iterate over the args ****/ while(++thisarg < ps_argc){ flagptr = ps_argv[thisarg]; switch(*flagptr){ case '0' ... '9': show_args = 1; parse_pid(flagptr); break; case '-': flagptr++; parse_sysv_option(); break; default: show_args = 1; parse_bsd_option(); break; } } /**** sanity check and clean-up ****/ if(want_one_pid) sel++; if(want_one_command) sel++; if(select_notty || select_all) sel++; if(sel>1 || select_notty>1 || select_all>1 || bsd_c_option>1 || old_h_option>1) usage(); if(bsd_c_option) show_args = 0;}#ifdef __sun__/* return 1 if it works, or 0 for failure */static int stat2proc(int pid) { struct psinfo p; // /proc/*/psinfo, struct psinfo, psinfo_t char buf[32]; int num; int fd; int tty_maj, tty_min; snprintf(buf, sizeof buf, "/proc/%d/psinfo", pid); if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0; num = read(fd, &p, sizeof p); close(fd); if(num != sizeof p) return 0; num = PRFNSZ; if (num >= sizeof P_cmd) num = sizeof P_cmd - 1; memcpy(P_cmd, p.pr_fname, num); // p.pr_fname or p.pr_lwp.pr_name P_cmd[num] = '\0'; P_pid = p.pr_pid; P_ppid = p.pr_ppid; P_pgrp = p.pr_pgid; P_session = p.pr_sid; P_euid = p.pr_euid; P_rss = p.pr_rssize; P_vsize = p.pr_size;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -