📄 oldps.c
字号:
/* * ps.c - show process status * * Copyright (c) 1992 Branko Lankester * * Snarfed and HEAVILY modified for procps by Michael K. Johnson, * (johnsonm@sunsite.unc.edu). What is used is what is required to have a * common interface. * * Massive modifications by Charles Blake (cblake@bbn.com). Rewrite * of the system process table code, multilevel sorting, device number * database, forest feature (contributed by ...), environment variables, GNU * style long options, pid list filtering (contributed by Michael Shields). * * Michael K. Johnson <johnsonm@redhat.com> again in charge, merging * patches that have accumulated over a long time. * * Changes Copyright (C) 1993, 1994, 1997 Michael K. Johnson, * and Copyright (C) 1995, 1996 Charles Blake * See file COPYING for copyright details. */#include <proc/version.h>#include <proc/readproc.h>#include <proc/procps.h>#include <proc/psdata.h>#include <proc/devname.h>#include <proc/tree.h>#include <proc/sysinfo.h>#include <proc/status.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <pwd.h>#include <time.h>#include <limits.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/resource.h>#include <sys/param.h>void show_short(char*, proc_t*);void show_long (char*, proc_t*);void show_user (char*, proc_t*);void show_jobs (char*, proc_t*);void show_sig (char*, proc_t*);void show_vm (char*, proc_t*);void show_m (char*, proc_t*);void show_regs (char*, proc_t*);/* this struct replaces the previously parallel fmt_fnc and hdrs */struct { void (*format)(char*,proc_t*); char CL_option_char; const char* default_sort; const char* header;} mode[] = { { show_short, 0 , "Up", " PID TTY STAT TIME COMMAND" }, { show_long, 'l', "Pp", " FLAGS UID PID PPID PRI NI SIZE RSS WCHAN STA TTY TIME COMMAND" }, { show_user, 'u', "up", "USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND" }, { show_jobs, 'j', "gPp"," PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND" }, { show_sig, 's', "p", " UID PID SIGNAL BLOCKED IGNORED CATCHED STAT TTY TIME COMMAND" }, { show_vm, 'v', "r", " PID TTY STAT TIME PAGEIN TSIZ DSIZ RSS LIM %MEM COMMAND" }, { show_m, 'm', "r", " PID TTY MAJFLT MINFLT TRS DRS SIZE SWAP RSS SHRD LIB DT COMMAND" }, { show_regs, 'X', "p", "NR PID STACK ESP EIP TMOUT ALARM STAT TTY TIME COMMAND" }, { NULL, 0, NULL, NULL }};/* some convenient integer constants corresponding to the above rows. */enum PS_MODALITY { PS_D = 0, PS_L, PS_U, PS_J, PS_S, PS_V, PS_M, PS_X };extern int sort_depth;extern int sort_direction[];extern int (*sort_function[])(/* void* a, void* b */);int parse_sort_opt (const char*);int parse_long_sort(const char*);char * prtime (char *s, unsigned long t, unsigned long rel);void usage (char* context);void set_cmdspc (int w_opts);void show_procs (unsigned maxcmd, int do_header, int, void*,int);void show_cmd_env (char* tskcmd, char** cmd, char** env, unsigned maxch);void show_a_proc (proc_t* the_proc, unsigned maxcmd);void show_time (char *s, proc_t * p);void add_node (char *s, proc_t *task);int node_cmp (const void *s1, const void *s2);void show_tree (int n, int depth, char *continued);void show_forest (void);int CL_fmt = 0;/* process list filtering command line options */int CL_all, CL_kern_comm, CL_no_ctty, CL_run_only;char * CL_ctty;pid_t * CL_pids; /* zero-terminated list, dynamically allocated *//* process display modification command line options */int CL_show_env, CL_num_outp, /* numeric fields for user, wchan, tty */ CL_sort = 1, CL_forest, CL_Sum, CL_pg_shift = (PAGE_SHIFT - 10); /* default: show k instead of pages *//* Globals */unsigned cmdspc = 80; /* space left for cmd+env after table per row */int GL_current_time; /* some global system parameters */unsigned GL_main_mem;long GL_time_now;int GL_wchan_nout; /* this is can also be set on the command-line */int main(int argc, char **argv) { char *p; int width = 0, do_header = 1, psdbsucc = 0, user_ord = 0, next_arg = 0, toppid = 0, pflags, N = 1; void* args = NULL; dev_t tty[2] = { 0 }; uid_t uid[1]; do { --argc; /* shift to next arg. */ ++argv; for (p = *argv; p && *p; ++p) { switch (*p) { case '-': /* "--" ==> long name options */ if (*(p+1) == '-') { if (strncmp(p+2,"sort",4)==0) { if (parse_long_sort(p+7) == -1) usage("unrecognized long sort option\n"); user_ord = 1; next_arg = 1; break; } else if (strncmp(p+2, "help", 4) == 0) { usage(NULL); dump_keys(); return 0; } else if (strncmp(p+2, "version", 6) == 0) { display_version(); return 0; } else if (*(p+2) != '\0') /* just '-- '; not an error */ usage("ps: unknown long option\n"); } if (!getenv("I_WANT_A_BROKEN_PS")) { fprintf(stderr, "warning: `-' deprecated; use `ps %s', not `ps %s'\n", (p+1), p); } break; case 'l': CL_fmt = PS_L; /* replaceable by a */ break; case 'u': CL_fmt = PS_U; /* loop over mode[] */ break; case 'j': CL_fmt = PS_J; break; case 's': CL_fmt = PS_S; break; case 'v': CL_fmt = PS_V; break; case 'm': CL_fmt = PS_M; break; case 'X': CL_fmt = PS_X; /* regs */ break; case 'r': CL_run_only = 1; /* list filters */ break; case 'a': CL_all = 1; break; case 'x': CL_no_ctty = 1; break; case 't': CL_ctty = p + 1; next_arg = 1; break; case 'e': CL_show_env = 1; /* output modifiers */ break; case 'f': CL_forest = 1; CL_kern_comm = 0; break; case 'c': CL_kern_comm = 1; break; case 'w': ++width; break; case 'h': do_header = 0; break; case 'n': CL_num_outp = 1; GL_wchan_nout = 1; break; case 'S': CL_Sum = 1; break; case 'p': CL_pg_shift = 0; break; case 'o': CL_sort = !CL_sort; break; case 'O': if (parse_sort_opt(p+1) == -1) usage("short form sort flag parse error\n"); user_ord = 1; next_arg = 1; break; case 'V': display_version(); exit(0); default: /* Step through, reading+alloc space for comma-delim pids */ if (isdigit(*p)) { while (isdigit(*p)) { CL_pids = xrealloc(CL_pids, (toppid + 2)*sizeof(pid_t)); CL_pids[toppid++] = atoi(p); while (isdigit(*p)) p++; if (*p == ',') p++; } CL_pids[toppid] = 0; next_arg = 1; } if (*p) usage("unrecognized option or trailing garbage\n"); } if (next_arg) { next_arg = 0; break; /* end loop over chars in this argument */ } } } while (argc > 1); if (!CL_sort) /* since the unsorted mode is intended to be speedy */ CL_forest = 0; /* turn off the expensive forest option as well. */ if (CL_fmt == PS_L) { if (open_psdb(NULL)) GL_wchan_nout = 1; else psdbsucc = 1; } set_cmdspc(width); if (!(GL_main_mem = read_total_main()) || !(GL_current_time = uptime(0,0))) return 1; GL_time_now = time(0L); if (CL_sort && !user_ord) parse_sort_opt(mode[CL_fmt].default_sort); /* NOTE: all but option parsing has really been done to enable * multiple uid/tty/state filtering as well as multiple pid filtering */ pflags = PROC_ANYTTY; /* defaults */ if (!CL_kern_comm) pflags |= PROC_FILLCMD; /* verbosity flags */ if (CL_fmt == PS_M) pflags |= PROC_FILLMEM; if (CL_show_env) pflags |= PROC_FILLENV; if (!CL_num_outp) pflags |= PROC_FILLUSR; if (CL_no_ctty) pflags &= ~PROC_ANYTTY; /* filter flags */ if (CL_run_only) { pflags |= PROC_STAT; args = "RD"; } else if (!CL_all) { pflags |= PROC_UID; args = uid; uid[0] = getuid(); pflags &= ~PROC_STAT; } if (CL_pids) { pflags |= PROC_PID; args = CL_pids; pflags &= ~PROC_UID; pflags &= ~PROC_STAT; } if (CL_ctty) { if ((tty[0] = tty_to_dev(CL_ctty)) == (dev_t)-1) { fprintf(stderr, "the name `%s' is not a tty\n", CL_ctty); exit(1); } pflags = (pflags | PROC_TTY) & ~(PROC_ANYTTY|PROC_STAT|PROC_UID|PROC_PID); args = tty; } show_procs(cmdspc, do_header, pflags, args, N); if (psdbsucc) close_psdb(); return 0;}/* print a context dependent usage message and maybe exit */void usage(char* context) { fprintf(stderr, "%s" "usage: ps acehjlnrsSuvwx{t<tty>|#|O[-]u[-]U..} \\\n" " --sort:[-]key1,[-]key2,...\n" " --help gives you this message\n" " --version prints version information\n", context ? context : ""); if (context) exit(1); /* prevent bad exit status by calling usage(NULL) */}/* set maximum chars displayed on a line based on screen size. * Always allow for the header, with n+1 lines of output per row. */void set_cmdspc(int n) { struct winsize win; int h = strlen(mode[CL_fmt].header), c = strlen("COMMAND"); if (ioctl(1, TIOCGWINSZ, &win) != -1 && win.ws_col > 0) cmdspc = win.ws_col; if (n > 100) n = 100; /* max of 100 'w' options */ if (cmdspc > h) cmdspc = cmdspc*(n+1) - h + c; else cmdspc = cmdspc*n + c;}const char *ttyc(int tty, int pid){ static char outbuf[8]; if(CL_num_outp) snprintf(outbuf, sizeof outbuf, "%4.4x", tty); else dev_to_tty(outbuf, 4, tty, pid, ABBREV_TTY|ABBREV_DEV|ABBREV_PTS); return outbuf;}/* This is the main driver routine that iterates over the process table. */void show_procs(unsigned maxcmd, int do_header, int pflags, void* args, int N) { static proc_t buf; /* less dynamic memory allocation when not sorting */ PROCTAB* tab; proc_t **ptable = NULL, *next, *retbuf = NULL; int n = 0; /* initiate process table scan */ tab = openproc(pflags, args, N); if (do_header) puts(mode[CL_fmt].header); /* print header */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -