From c7e7b44284df1d3b701fcf33c321b7c98386bcea Mon Sep 17 00:00:00 2001 From: albert <> Date: Wed, 4 Dec 2002 22:48:30 +0000 Subject: [PATCH] not done yet --- top.c | 994 +++++++++++++++++++++++++++------------------------------- top.h | 222 +++++++------ 2 files changed, 584 insertions(+), 632 deletions(-) diff --git a/top.c b/top.c index 515ddf40..ca6b5d37 100644 --- a/top.c +++ b/top.c @@ -22,10 +22,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -55,29 +55,33 @@ /* The original and new terminal attributes */ static struct termios Savedtty, Rawtty; -static int Ttychanged = 0; +static int Ttychanged = 0; /* Program name used in error messages and local 'rc' file name */ static char *Myname; - /* The Name of the local config file, dynamically constructed */ -static char RCfile [OURPATHSZ]; + /* Name of user config file (dynamically constructed) and our + 'Current' rcfile contents, initialized with defaults but may be + overridden with the local rcfile (old or new-style) values */ +static char Rc_name [OURPATHSZ]; +static RCF_t Rc = DEF_RCFILE; + /* The run-time acquired page size */ -static int Page_size; +static int Page_size; /* SMP, Irix/Solaris mode, Linux 2.5.xx support */ -static int Cpu_tot, - *Cpu_map; +static int Cpu_tot, + *Cpu_map; /* assume no IO-wait stats, overridden if linux 2.5.41 */ static const char *States_fmts = STATES_line2x4; /* Specific process id monitoring support */ -static pid_t Monpids [MONPIDMAX] = { 0 }; -static int Monpidsidx = 0; +static pid_t Monpids [MONPIDMAX] = { 0 }; +static int Monpidsidx = 0; /* A postponed error message */ -static char Msg_delayed [SMLBUFSIZ]; -static int Msg_awaiting = 0; +static char Msg_delayed [SMLBUFSIZ]; +static int Msg_awaiting = 0; /* Configurable Display support ##################################*/ @@ -86,28 +90,20 @@ static int Msg_awaiting = 0; basis (see the WIN_t). Max_lines is the total number of screen rows after deducting summary information overhead. */ /* Current terminal screen size. */ -static int Screen_cols, Screen_rows, Max_lines; +static int Screen_cols, Screen_rows, Max_lines; /* This is really the number of lines needed to display the summary information (0 - nn), but is used as the relative row where we stick the cursor between frames. */ -static int Msg_row; - - /* Global/Non-windows mode stuff that IS persistent (in rcfile) */ -static int Mode_altscr = 0; /* 'A' - 'Alt' display mode (multi windows) */ - /* 11/02 - next no longer alters a proc_t, it COULD be window based! */ -static int Mode_irixps = 1; /* 'I' - Irix vs. Solaris mode (SMP-only) */ -static float Delay_time = DEF_DELAY; /* how long to sleep between updates */ - - /* Global/Non-windows mode stuff for the persistance itself */ -static int Crufty_config = 0; /* if we read an old config, write one too */ +static int Msg_row; /* Global/Non-windows mode stuff that is NOT persistent */ -static int No_ksyms = -1, /* set to '0' if ksym avail, '1' otherwise */ - PSDBopen = 0, /* set to '1' if psdb opened (now postponed) */ - Batch = 0, /* batch mode, collect no input, dumb output */ - Loops = -1, /* number of iterations, -1 loops forever */ - Secure_mode = 0; /* set if some functionality restricted */ +static int Crufty_rcf = 0, // if we read an old config, write one too + No_ksyms = -1, // set to '0' if ksym avail, '1' otherwise + PSDBopen = 0, // set to '1' if psdb opened (now postponed) + Batch = 0, // batch mode, collect no input, dumb output + Loops = -1, // number of iterations, -1 loops forever + Secure_mode = 0; // set if some functionality restricted /* Some cap's stuff to reduce runtime calls -- to accomodate 'Batch' mode, they begin life as empty strings */ @@ -122,7 +118,7 @@ static char Cap_clr_eol [CAPBUFSIZ] = "", Caps_off [CAPBUFSIZ] = ""; static int Cap_can_goto = 0; - /* Some optimization stuff reducing output demands... + /* Some optimization stuff, to reduce output demands... The Pseudo_ guys are managed by wins_resize and frame_make. They are exploited in a macro and represent 90% of our optimization. The Stdout_buf is transparent to our code and regardless of whose @@ -146,18 +142,20 @@ static WIN_t *Winstk [GROUPSMAX], /* Frame oriented stuff that can't remain local to any 1 function and/or that would be too cumbersome managed as parms, - and/or that are simply more efficiently handled as globals */ -static int Frame_libflgs; // current PROC_FIILxxx flags (0 = need new) -static unsigned Frame_maxtask; // last known number of active tasks - // ie. current 'size' of proc table -static unsigned Frame_running, // state categories for this frame + and/or that are simply more efficiently handled as globals + (first 2 persist beyond a single frame, changed infrequently) */ +static int Frams_libflags; // current PROC_FIILxxx flags (0 = need new) +//atic int Frams_maxcmdln; // the largest from the 4 windows +static unsigned Frame_maxtask; // last known number of active tasks + // ie. current 'size' of proc table +static unsigned Frame_running, // state categories for this frame Frame_sleepin, Frame_stopped, Frame_zombied; -static float Frame_tscale; // so we can '*' vs. '/' WHEN 'pcpu' -static int Frame_srtflg, // the subject window's sort direction - Frame_ctimes, // the subject window's ctimes flag - Frame_cmdlin; // the subject window's cmdlin flag +static float Frame_tscale; // so we can '*' vs. '/' WHEN 'pcpu' +static int Frame_srtflg, // the subject window's sort direction + Frame_ctimes, // the subject window's ctimes flag + Frame_cmdlin; // the subject window's cmdlin flag /* ////////////////////////////////////////////////////////////// */ @@ -168,17 +166,17 @@ static int Frame_srtflg, // the subject window's sort direction * values. Note that 2 of these routines serve double duty -- * 2 columns each. */ -_SC_NUMx(P_PID, pid) -_SC_NUMx(P_PPD, ppid) -_SC_NUMx(P_PGD, pgrp) -_SC_NUMx(P_UID, euid) -_SC_STRx(P_USR, euser) -_SC_STRx(P_GRP, egroup) -_SC_NUMx(P_TTY, tty) -_SC_NUMx(P_PRI, priority) -_SC_NUMx(P_NCE, nice) -_SC_NUMx(P_CPN, processor) -_SC_NUM1(P_CPU, pcpu) +SCB_NUMx(P_PID, pid) +SCB_NUMx(P_PPD, ppid) +SCB_NUMx(P_PGD, pgrp) +SCB_NUMx(P_UID, euid) +SCB_STRx(P_USR, euser) +SCB_STRx(P_GRP, egroup) +SCB_NUMx(P_TTY, tty) +SCB_NUMx(P_PRI, priority) +SCB_NUMx(P_NCE, nice) +SCB_NUMx(P_CPN, processor) +SCB_NUM1(P_CPU, pcpu) // also serves P_TM2 ! static int sort_P_TME (const proc_t **P, const proc_t **Q) { @@ -198,15 +196,15 @@ static int sort_P_TME (const proc_t **P, const proc_t **Q) return SORT_eq; } -_SC_NUM1(P_VRT, size) -_SC_NUM2(P_SWP, size, resident) -_SC_NUM1(P_RES, resident) // also serves P_MEM ! -_SC_NUM1(P_COD, trs) -_SC_NUM1(P_DAT, drs) -_SC_NUM1(P_SHR, share) -_SC_NUM1(P_FLT, maj_flt) -_SC_NUM1(P_DRT, dt) -_SC_NUMx(P_STA, state) +SCB_NUM1(P_VRT, size) +SCB_NUM2(P_SWP, size, resident) +SCB_NUM1(P_RES, resident) // also serves P_MEM ! +SCB_NUM1(P_COD, trs) +SCB_NUM1(P_DAT, drs) +SCB_NUM1(P_SHR, share) +SCB_NUM1(P_FLT, maj_flt) +SCB_NUM1(P_DRT, dt) +SCB_NUMx(P_STA, state) static int sort_P_CMD (const proc_t **P, const proc_t **Q) { @@ -222,11 +220,11 @@ static int sort_P_CMD (const proc_t **P, const proc_t **Q) return Frame_srtflg * strcmp((*Q)->cmd, (*P)->cmd); } -_SC_NUM1(P_WCH, wchan) -_SC_NUM1(P_FLG, flags) +SCB_NUM1(P_WCH, wchan) +SCB_NUM1(P_FLG, flags) /* ///////////////////////////////// special sort for prochlp() ! */ -static int sort_HIST_t (const HIST_t *P, const HIST_t *Q) +static int sort_HST_t (const HST_t *P, const HST_t *Q) { return -1 * ( Q->pid - P->pid ); } @@ -288,7 +286,7 @@ static inline char *scat (char *restrict dst, const char *restrict src) * in some proc cmdlines, a choice was offered twix space or null. */ static char *strim (int sp, char *str) { - static const char ws[] = "\b\f\n\r\t\v"; + static const char ws[] = "\b\e\f\n\r\t\v"; char *p; if (sp) @@ -327,12 +325,11 @@ static void bye_bye (int eno, const char *str) fprintf(stderr, "\nbye_bye's Summary report:" "\n\tProgram" - "\n\t Linux version = %u.%u.%u" + "\n\t Linux version = %u.%u.%u, %s" + "\n\t Hertz = %u (%u bytes, %u-bit time)" "\n\t Page_size = %d, Cpu_tot = %d, sizeof(proc_t) = %u" - "\n\t %s, using Hertz = %u (%u bytes, %u-bit time)" - "\n\t sizeof(CPUS_t) = %u, sizeof(HIST_t) = %u (%u HIST_t's/Page)" - "\n\t CPU_FMTS_JUST1 = %s" - "\n\t CPU_FMTS_MULTI = %s" + "\n\t sizeof(CPU_t) = %u, sizeof(HST_t) = %u (%u HST_t's/Page)" + "\n\t Crufty? %s" "\n\tTerminal: %s" "\n\t device = %s, ncurses = v%s" "\n\t max_colors = %d, max_pairs = %d" @@ -357,10 +354,11 @@ static void bye_bye (int eno, const char *str) , LINUX_VERSION_MAJOR(linux_version_code) , LINUX_VERSION_MINOR(linux_version_code) , LINUX_VERSION_PATCH(linux_version_code) + , procps_version + , (unsigned)Hertz, sizeof(Hertz), sizeof(Hertz) * 8 , Page_size, Cpu_tot, sizeof(proc_t) - , procps_version, (unsigned)Hertz, sizeof(Hertz), sizeof(Hertz) * 8 - , sizeof(CPUS_t), sizeof(HIST_t), Page_size / sizeof(HIST_t) - , CPU_FMTS_JUST1, CPU_FMTS_MULTI + , sizeof(CPU_t), sizeof(HST_t), Page_size / sizeof(HST_t) + , Crufty_rcf ? "Thar be dogshit - turn off the fan!" : "Whew, shoes clean." #ifdef PRETENDNOCAP , "dumb" #else @@ -417,7 +415,7 @@ static void std_err (const char *str) -- OUR msg won't get lost in screen clutter, like so many others! */ snprintf(buf, sizeof(buf), "\t%s: %s\n", Myname, str); if (!Ttychanged) { - fprintf(stderr, buf); + fprintf(stderr, "%s\n", buf); exit(1); } /* not to worry, he'll change our exit code to 1 due to 'buf' */ @@ -734,7 +732,7 @@ static const char *scale_num (unsigned num, const int width, const unsigned type /* * Do some scaling stuff. * format 'tics' to fit 'width'. */ -static const char *scale_tics (TICS_t tics, const int width) +static const char *scale_tics (TIC_t tics, const int width) { #ifdef CASEUP_SCALE #define HH "%uH" @@ -812,11 +810,11 @@ static void *alloc_r (void *q, unsigned numb) /* * This guy's modeled on libproc's 'five_cpu_numbers' function except - * we preserve all cpu data in our CPUS_t array which is organized + * we preserve all cpu data in our CPU_t array which is organized * as follows: * cpus[0] thru cpus[n] == tics for each separate cpu * cpus[Cpu_tot] == tics from the 1st /proc/stat line */ -static CPUS_t *cpus_refresh (CPUS_t *cpus) +static CPU_t *cpus_refresh (CPU_t *cpus) { static FILE *fp = NULL; int i; @@ -828,10 +826,10 @@ static CPUS_t *cpus_refresh (CPUS_t *cpus) if (!fp) { if (!(fp = fopen("/proc/stat", "r"))) std_err(fmtmk("Failed /proc/stat open: %s", strerror(errno))); - /* note: we allocate one more CPUS_t than Cpu_tot so that the last slot + /* note: we allocate one more CPU_t than Cpu_tot so that the last slot can hold tics representing the /proc/stat cpu summary (the first line read) -- that slot supports our View_CPUSUM toggle */ - cpus = alloc_c((1 + Cpu_tot) * sizeof(CPUS_t)); + cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t)); } rewind(fp); fflush(fp); @@ -842,7 +840,7 @@ static CPUS_t *cpus_refresh (CPUS_t *cpus) , &cpus[Cpu_tot].u, &cpus[Cpu_tot].n, &cpus[Cpu_tot].s, &cpus[Cpu_tot].i, &cpus[Cpu_tot].w)) std_err("failed /proc/stat read"); // and just in case we're 2.2.xx compiled without SMP support... - if (1 == Cpu_tot) memcpy(cpus, &cpus[1], sizeof(CPUS_t)); + if (1 == Cpu_tot) memcpy(cpus, &cpus[1], sizeof(CPU_t)); // now value each separate cpu's tics for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) { @@ -863,21 +861,21 @@ static CPUS_t *cpus_refresh (CPUS_t *cpus) * to loop through our darn proc_t table. He's responsible for: * 1) calculating the elapsed time since the previous frame * 2) counting the number of tasks in each state (run, sleep, etc) - * 3) maintaining the HIST_t's and priming the proc_t pcpu field + * 3) maintaining the HST_t's and priming the proc_t pcpu field * 4) establishing the total number tasks for this frame */ static void prochlp (proc_t *this) { - static HIST_t *hist_sav = NULL; - static HIST_t *hist_new = NULL; + static HST_t *hist_sav = NULL; + static HST_t *hist_new = NULL; static unsigned hist_siz = 0; // number of structs static unsigned maxt_sav; // prior frame's max tasks - TICS_t tics; + TIC_t tics; if (!this) { static struct timeval oldtimev; struct timeval timev; struct timezone timez; - HIST_t *hist_tmp; + HST_t *hist_tmp; float et; gettimeofday(&timev, &timez); @@ -887,7 +885,7 @@ static void prochlp (proc_t *this) oldtimev.tv_usec = timev.tv_usec; // if in Solaris mode, adjust our scaling for all cpus - Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Mode_irixps ? 1 : Cpu_tot)); + Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : Cpu_tot)); maxt_sav = Frame_maxtask; Frame_maxtask = Frame_running = Frame_sleepin = Frame_stopped = Frame_zombied = 0; @@ -895,8 +893,8 @@ static void prochlp (proc_t *this) hist_tmp = hist_sav; hist_sav = hist_new; hist_new = hist_tmp; - // prep for our binary search by sorting the last frame's HIST_t's - qsort(hist_sav, maxt_sav, sizeof(HIST_t), (QSORT_t)sort_HIST_t); + // prep for our binary search by sorting the last frame's HST_t's + qsort(hist_sav, maxt_sav, sizeof(HST_t), (QFP_t)sort_HST_t); return; } @@ -918,8 +916,8 @@ static void prochlp (proc_t *this) if (Frame_maxtask+1 >= hist_siz) { hist_siz = hist_siz * 5 / 4 + 100; // grow by at least 25% - hist_sav = alloc_r(hist_sav, sizeof(HIST_t) * hist_siz); - hist_new = alloc_r(hist_new, sizeof(HIST_t) * hist_siz); + hist_sav = alloc_r(hist_sav, sizeof(HST_t) * hist_siz); + hist_new = alloc_r(hist_new, sizeof(HST_t) * hist_siz); } /* calculate time in this process; the sum of user time (utime) and system time (stime) -- but PLEASE dont waste time and effort on @@ -944,10 +942,11 @@ static void prochlp (proc_t *this) } } } - /* we're just saving elapsed tics, to be converted into %cpu if - this task wins it's displayable screen row lottery... */ + // we're just saving elapsed tics, to be converted into %cpu if + // this task wins it's displayable screen row lottery... */ this->pcpu = tics; - + strim(1, this->cmd); +// if (Frams_maxcmdln) // shout this to the world with the final call (or us the next time in) Frame_maxtask++; } @@ -1011,7 +1010,8 @@ static proc_t **procs_refresh (proc_t **table, int flags) } -/*###### field table ##############################################*/ +/*###### Field Table/RCfile compatability support ######################*/ + /* These are the Fieldstab.lflg values used here and in reframewins. (own identifiers as documentation and protection against changes) */ #define L_stat PROC_FILLSTAT @@ -1022,18 +1022,19 @@ static proc_t **procs_refresh (proc_t **table, int flags) #define L_GROUP L_status | PROC_FILLGRP #define L_NONE 0 // from either 'stat' or 'status' (preferred), via bits not otherwise used -#define L_EITHER ~(L_stat|L_statm|L_status|L_CMDLINE|L_EUSER|L_GROUP) +#define L_EITHER PROC_SPARE_1 // for reframewins and summary_show 1st pass #define L_DEFAULT PROC_FILLSTAT -#define SF(f) (QSORT_t)sort_P_ ## f + // a temporary macro, soon to be undef'd... +#define SF(f) (QFP_t)sort_P_ ## f /* These are our gosh darn 'Fields' ! They MUST be kept in sync with pflags !! note: for integer data, the length modifiers found in .fmts may NOT reflect the true field type found in proc_t -- this plus a cast when/if displayed provides minimal width protection. */ -static FTAB_t Fieldstab[] = { +static FLD_t Fieldstab[] = { /* .lflg anomolies: P_UID, L_NONE - natural outgrowth of 'stat()' in readproc (euid) P_CPU, L_stat - never filled by libproc, but requires times (pcpu) @@ -1070,7 +1071,7 @@ static FTAB_t Fieldstab[] = { #endif // next entry's special: '.head' will be formatted using table entry's own // '.fmts' plus runtime supplied conversion args! - { "XxXx", "Command ", "%-*.*s ", -1, -1, SF(CMD), "Command name/line", L_stat }, + { "XxXx", "Command ", "%-*.*s ", -1, -1, SF(CMD), "Command name/line", L_EITHER }, { "YyUu", "WCHAN ", "%-9.9s ", -1, -1, SF(WCH), "Sleeping in Function", L_stat }, // next entry's special: the 0's will be replaced with '.'! #ifdef CASEUP_HEXES @@ -1090,152 +1091,152 @@ static FTAB_t Fieldstab[] = { }; #undef SF -// convert, or NULL for failure -static const FTAB_t * idx_to_ptr(int i){ - if (i<0) return NULL; - if (i>=MAXTBL(Fieldstab)) return NULL; - return Fieldstab+i; -} - -// convert, or -1 for failure -static int ptr_to_idx(const FTAB_t *p){ - int i; - if (p=MAXTBL(Fieldstab)) return -1; - return i; -} - -// convert -static int ptr_to_jim(const FTAB_t *p, int off){ - return p->keys[off]; -} -// convert -static int ptr_to_rik(const FTAB_t *p, int off){ - return p->keys[off+2]; -} + /* All right, those-that-follow -- Listen Up! + * For the above table keys and the following present/future rc file + * compatibility support, you have Mr. Albert D. Cahalan to thank. + * He must have been in a 'Christmas spirit'. Were it left to me, + * this top would never have gotten that close to the former top's + * crufty rcfile. Not only is it illogical, it's odoriferous ! + */ -// convert -static int idx_to_jim(int i, int off){ - return Fieldstab[i].keys[off]; -} + // used as 'to' and/or 'from' args in the ft_xxx utilities... +#define FT_NEW_fmt 0 +#define FT_OLD_fmt 2 -// convert -static int idx_to_rik(int i, int off){ - return Fieldstab[i].keys[off+2]; -} -// convert, or -1 for failure -static int jim_to_idx(int c){ + // convert, or 0 for failure +static int ft_cvt_char (const int fr, const int to, int c) { int j = -1; + while (++j < MAXTBL(Fieldstab)) { - if (c == Fieldstab[j].keys[0]) return j; - if (c == Fieldstab[j].keys[1]) return j; + if (c == Fieldstab[j].keys[fr]) return Fieldstab[j].keys[to]; + if (c == Fieldstab[j].keys[fr+1]) return Fieldstab[j].keys[to+1]; } - return -1; + return 0; } -// convert, or -1 for failure -static int rik_to_idx(int c){ + + // convert +static inline int ft_get_char (const int fr, int i) { + int c; + if (i < 0) return 0; + if (i >= MAXTBL(Fieldstab)) return 0; + c = Fieldstab[i].keys[fr]; + if (c == '.') c = 0; // '.' marks a bad entry + return c; +} + + + // convert, or -1 for failure +static int ft_get_idx (const int fr, int c) { int j = -1; + while (++j < MAXTBL(Fieldstab)) { - if (c == Fieldstab[j].keys[2]) return j; - if (c == Fieldstab[j].keys[3]) return j; + if (c == Fieldstab[j].keys[fr]) return j; + if (c == Fieldstab[j].keys[fr+1]) return j; } return -1; } -// convert, or NULL for failure -static const FTAB_t * rik_to_ptr(int c){ + + // convert, or NULL for failure +static const FLD_t *ft_get_ptr (const int fr, int c) { int j = -1; + while (++j < MAXTBL(Fieldstab)) { - if (c == Fieldstab[j].keys[2]) return Fieldstab+j; - if (c == Fieldstab[j].keys[3]) return Fieldstab+j; + if (c == Fieldstab[j].keys[fr]) return Fieldstab+j; + if (c == Fieldstab[j].keys[fr+1]) return Fieldstab+j; } return NULL; } -// convert, or NULL for failure -static const FTAB_t * jim_to_ptr(int c){ - int j = -1; - while (++j < MAXTBL(Fieldstab)) { - if (c == Fieldstab[j].keys[0]) return Fieldstab+j; - if (c == Fieldstab[j].keys[1]) return Fieldstab+j; - } - return NULL; + + // convert, or NULL for failure +static const FLD_t *ft_idx_to_ptr (const int i) { + if (i < 0) return NULL; + if (i >= MAXTBL(Fieldstab)) return NULL; + return Fieldstab + i; } -// convert, or 0 for failure -static int rik_to_jim(int c){ - int j = -1; - while (++j < MAXTBL(Fieldstab)) { // find a Rik-to-Jim conversion for the letter - if (c == Fieldstab[j].keys[2]) return Fieldstab[j].keys[0]; - if (c == Fieldstab[j].keys[3]) return Fieldstab[j].keys[1]; - } - return 0; + + // convert, or -1 for failure +static int ft_ptr_to_idx (const FLD_t *p) { + int i; + if (p < Fieldstab) return -1; + i = p - Fieldstab; + if (i >= MAXTBL(Fieldstab)) return -1; + return i; } -// convert, or 0 for failure -static int jim_to_rik(int c){ - int j = -1; - while (++j < MAXTBL(Fieldstab)) { // find a Jim-to-Rik conversion for the letter - if (c == Fieldstab[j].keys[0]) return Fieldstab[j].keys[2]; - if (c == Fieldstab[j].keys[1]) return Fieldstab[j].keys[3]; + +#if (0) +static void rc_bugless (const RCF_t *const rc) { + const RCW_t *w; + int i = 0; + + fprintf(stderr,"\n%d %d %f %d\n" + , rc->mode_altscr, rc->mode_irixps, rc->delay_time, rc->win_index); + while(i < 4) { + w = &rc->win[i++]; + fprintf(stderr, "<%s> <%s> %d %08x %d %d %d %d %d\n" + , w->winname, w->fieldscur, w->sortindx, w->winflags, w->maxtasks + , w->summclr, w->msgsclr, w->headclr, w->taskclr); } - return 0; } +#endif - -/*###### Startup routines ##############################################*/ /* - * No mater what *they* say, we handle the really really BIG and - * IMPORTANT stuff upon which all those lessor functions depend! */ -static void before (char *me) -{ + * '$HOME/Rc_name' contains multiple lines - 2 global + 3 per window. + * line 1: an eyecatcher, with a shameless advertisement + * line 2: an id, Mode_altcsr, Mode_irixps, Delay_time and Curwin. + * For each of the 4 windows: + * line a: contains winname, fieldscur + * line b: contains winflags, sortindx, maxtasks + * line c: contains summclr, msgsclr, headclr, taskclr */ +static int rc_read_new (const char *const buf, RCF_t *rc) { int i; + int cnt; + const char *cp; - /* setup our program name -- big! */ - Myname = strrchr(me, '/'); - if (Myname) ++Myname; else Myname = me; + cp = strstr(buf, "\n\n" RCF_EYECATCHER); + if (!cp) return -1; + cp = strchr(cp + 2, '\n'); + if (!cp++) return -2; - /* establish cpu particulars -- even bigger! */ -#ifdef PRETEND4CPUS - Cpu_tot = 4; -#else - Cpu_tot = smp_num_cpus; -#endif - Cpu_map = alloc_r(NULL, sizeof(int) * Cpu_tot); - for (i = 0; i < Cpu_tot; i++) - Cpu_map[i] = i; - if(linux_version_code > LINUX_VERSION(2, 5, 41)) - States_fmts = STATES_line2x5; + cnt = sscanf(cp, "Id:a, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%f, Curwin=%d\n" + , &rc->mode_altscr, &rc->mode_irixps, &rc->delay_time, &rc->win_index); + if (cnt != 4) return -3; + cp = strchr(cp, '\n'); + if (!cp++) return -4; - /* get virtual page size -- nearing huge! */ - Page_size = getpagesize(); -} + for (i = 0; i < GROUPSMAX; i++) { + RCW_t *ptr = &rc->win[i]; + cnt = sscanf(cp, "%s\tfieldscur=%s\n", ptr->winname, ptr->fieldscur); + if (cnt != 2) return 5+100*i; // OK to have less than 4 windows + if (WINNAMSIZ <= strlen(ptr->winname)) return -6; + if (strlen(DEF_FIELDS) != strlen(ptr->fieldscur)) return -7; + cp = strchr(cp, '\n'); + if (!cp++) return -(8+100*i); + cnt = sscanf(cp, "\twinflags=%d, sortindx=%u, maxtasks=%d \n" + , &ptr->winflags, &ptr->sortindx, &ptr->maxtasks); + if (cnt != 3) return -(9+100*i); + cp = strchr(cp, '\n'); + if (!cp++) return -(10+100*i); -static void print_rc (const RCF_t *const rc){ - const rcwin *w; - int i = 0; - fprintf(stderr,"\n%d %d %d %f %d\n", rc->Secure_mode, rc->Mode_altscr, rc->Mode_irixps, rc->Delay_time, rc->Curwin); - while(i<4){ - w = &rc->win[i]; - fprintf( - stderr, - "<%s> <%s> %d %08x %d %d %d %d %d\n", - w->winname, w->fieldscur, w->sortindx, - w->winflags, w->maxtasks, w->summclr, w->msgsclr, w->headclr, w->taskclr - ); - i++; + cnt = sscanf(cp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d \n" + , &ptr->summclr, &ptr->msgsclr, &ptr->headclr, &ptr->taskclr); + if (cnt != 4) return -(11+100*i); + cp = strchr(cp, '\n'); + if (!cp++) return -(12+100*i); } + return 13; } -static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const rc) -{ +static int rc_read_old (const char *const buf, RCF_t *rc) { unsigned u; const char *cp; unsigned c_show = 0; @@ -1244,84 +1245,82 @@ static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const char scoreboard[256]; memset(scoreboard, '\0', sizeof scoreboard); - (void)num; - - cp = fbuf+2; // skip the "\n\n" we stuck at the beginning + cp = buf+2; // skip the "\n\n" we stuck at the beginning u = 0; - for(;;){ - if(u+1 >= sizeof rc->win[0].fieldscur) return -1; + for (;;) { + if (u+1 >= sizeof rc->win[0].fieldscur) return -1; int c = *cp++; - if(c=='\0') return -2; - if(c=='\n') break; + if (c == '\0') return -2; + if (c == '\n') break; if (c & ~0x7f) return -3; if (~c & 0x20) c_show |= 1 << (c & 0x1f); // 0x20 means lowercase means hidden - if(scoreboard[c|0xe0u]) badchar++; // duplicates not allowed + if (scoreboard[c|0xe0u]) badchar++; // duplicates not allowed scoreboard[c|0xe0u]++; - if(c=='|') continue; // Rik's top ships with a garbage character - if(c=='[') c='Y'; // Rik's top ships with 3x of "#C" - if(c=='{') c='y'; // another one... and '}' to please Jim's editor - if(c=='N') c='n'; // usage differs, so turn this off - if(c=='Q') c='q'; // usage differs, so turn this off - if(c=='R') c='r'; // usage differs, so turn this off - c = rik_to_jim(c); - if(!c) return -4; // error value - if(c=='.') return -5; // error value - if(scoreboard[c&0x1fu]) badchar++; // duplicates not allowed + if (c == '|') continue; // Rik's top ships with a garbage character + if (c == '[') c = 'Y'; // Rik's top ships with 3x of "#C" + if (c == '{') c = 'y'; // another one... and '}' to please Jim's editor + if (c == 'N') c = 'n'; // usage differs, so turn this off + if (c == 'Q') c = 'q'; // usage differs, so turn this off + if (c == 'R') c = 'r'; // usage differs, so turn this off + ft_cvt_char(FT_OLD_fmt, FT_NEW_fmt, c); + if (!c) return -4; // error value + if (c == '.') return -5; // error value + if (scoreboard[c&0x1fu]) badchar++; // duplicates not allowed scoreboard[c&0x1fu]++; rc->win[0].fieldscur[u++] = c; } rc->win[0].fieldscur[u++] = '\0'; - if(u<21) return -6; // catch junk, but not good files (had 23 chars in one) - if(u>33) return -7; // catch junk, but not good files (had 29 chars in one) -//fprintf(stderr,"badchar: %d\n",badchar); sleep(2); - if(badchar>3) return -8; // too much junk - if (!c_show) return -9; // nothing was shown + if (u < 21) return -6; // catch junk, not good files (had 23 chars in one) + if (u > 33) return -7; // catch junk, not good files (had 29 chars in one) +// fprintf(stderr,"badchar: %d\n",badchar); sleep(2); + if (badchar > 3) return -8; // too much junk + if (!c_show) return -9; // nothing was shown // Due to Rik blindly accepting damem's broken patches, procps-2.0.10 // has 3 ("three"!!!) instances of "#C", "LC", or "CPU". Fix that here. // Some people are maintainers, and others are human patchbots. // The 'y' and 'Y' above have become 'j' and 'J' after translation. - if(scoreboard['j' & 0x1fu] > 1){ // more than one "#C" column + if (scoreboard['j' & 0x1fu] > 1) { // more than one "#C" column int letter; char *fields = rc->win[0].fieldscur; - char *tmp = strchr(fields,'J'); + char *tmp = strchr(fields, 'J'); if (tmp) { - *tmp='.'; // save one by hiding it + *tmp = '.'; // save one by hiding it letter = 'J'; } else { - tmp = strchr(fields,'j'); - *tmp='.'; + tmp = strchr(fields, 'j'); + *tmp = '.'; letter = 'j'; } - while (( tmp=strchr(fields,'J') )) *tmp='j'; // cannonicalize it - while (( tmp=strchr(fields,'j') )) { + while ((tmp = strchr(fields, 'J'))) *tmp='j'; // cannonicalize it + while ((tmp = strchr(fields, 'j'))) { char *dst = tmp; - char *src = tmp+1; + char *src = tmp + 1; int n = strlen(src) + 1; - memmove(dst,src,n); + memmove(dst, src, n); } - tmp = strchr(fields,'.'); // find back saved spot + tmp = strchr(fields, '.'); // find back saved spot *tmp = letter; } // rest of file is optional, but better look right if it exists if (!*cp) return 12; - if (*cp < '2' || *cp > '9') return -13; // stupid, and why isn't a '1' valid? - rc->Delay_time = *cp - '0'; + if (*cp < '2' || *cp > '9') return -13; // stupid, and why isn't '1' valid? + rc->delay_time = *cp - '0'; - memset(scoreboard, '\0', sizeof scoreboard); - for(;;){ - int c = *++cp & 0xffu; // protect scoreboard[] from negative char - if (!c) return -14; // not OK to hit EOL w/o '\n' - if (c=='\n') break; + memset(scoreboard, '\0', sizeof(scoreboard)); + for (;;) { + int c = *++cp & 0xffu; // protect scoreboard[] from negative char + if (!c) return -14; // not OK to hit EOL w/o '\n' + if (c == '\n') break; switch (c) { - case '0' ... '9': case ' ': case '.': - return -15; // not supposed to have digits here + case '0' ... '9': + return -15; // not supposed to have digits here - case 's': - rc->Secure_mode = 1; + case 's': // mostly for global rcfile + rc->mode_secure = 1; break; case 'S': rc->win[0].winflags |= Show_CTIMES; @@ -1332,7 +1331,7 @@ static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const case 'i': rc->win[0].winflags &= ~Show_IDLEPS; break; - case 'H': // 'H' means to show threads + case 'H': // 'H' = show threads (yea, sure) //rc->win[0].winflags |= ; break; case 'm': @@ -1345,7 +1344,7 @@ static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const rc->win[0].winflags &= ~View_STATES; break; case 'I': - rc->Mode_irixps = 0; + rc->mode_irixps = 0; break; case 'M': @@ -1358,7 +1357,7 @@ static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const break; case 'A': c = 0; // for scoreboard - rc->win[0].sortindx = P_PID; // should be by start_time + rc->win[0].sortindx = P_PID; // was by start_time (non-display) break; case 'T': c = 0; // for scoreboard @@ -1373,159 +1372,72 @@ static int read_config_rik (const char * const fbuf, ssize_t num, RCF_t * const // just ignore it, except for the scoreboard of course break; } - if(scoreboard[c]) return -16; // duplicates not allowed + if (scoreboard[c]) return -16; // duplicates not allowed scoreboard[c] = 1; } return 17; } - /* - * '$HOME/RCfile' contains multiple lines - 2 global + 3 per window. - * line 1: a shameless advertisement - * line 2: an id, Mode_altcsr, Mode_irixps, Delay_time and Curwin. - * If running in secure mode via the /etc/rcfile, - * Delay_time will be ignored except for root. - * For each of the 4 windows: - * line a: contains w->rc.winname, rc.fieldscur - * line b: contains w->rc.winflags, rc.sortindx, rc.maxtasks - * line c: contains w->rc.summclr, rc.msgsclr, rc.headclr, rc.taskclr */ -static int read_config_jim (const char * const fbuf, ssize_t num, RCF_t * const rc) -{ - int i; - int cnt; - const char *cp; - (void)num; - - cp = strstr(fbuf,"\n\nRCfile for "); - if (!cp) return -1; - cp = strchr(cp+2,'\n'); - if (!cp++) return -2; - cnt = sscanf(cp, "Id:a, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%f, Curwin=%d\n" - , &rc->Mode_altscr, &rc->Mode_irixps, &rc->Delay_time, &rc->Curwin); - if (cnt != 4) return -3; - cp = strchr(cp,'\n'); - if (!cp++) return -4; +static void rc_write_new (FILE *fp) { + int i; + fprintf(fp, RCF_EYECATCHER "\"%s with windows\"\t\t# shameless braggin'\n" + , Myname); + fprintf(fp, RCF_DEPRECATED + "Mode_altscr=%d, Mode_irixps=%d, Delay_time=%.3f, Curwin=%d\n" + , Rc.mode_altscr, Rc.mode_irixps, Rc.delay_time, Curwin - Winstk[0]); for (i = 0; i < GROUPSMAX; i++) { - rcwin *ptr = &rc->win[i]; - cnt = sscanf(cp, "%s\tfieldscur=%s\n", ptr->winname, ptr->fieldscur); - if (cnt!=2) return 5+100*i; - if (WINNAMSIZ <= strlen(ptr->winname)) return -6; - if (strlen(DEF_FIELDS) != strlen(ptr->fieldscur)) return -7; - cp = strchr(cp,'\n'); - if (!cp++) return -(8+100*i); - - cnt = sscanf(cp, "\twinflags=%d, sortindx=%u, maxtasks=%d \n" - , &ptr->winflags - , &ptr->sortindx - , &ptr->maxtasks); - if (cnt!=3) return -(9+100*i); - cp = strchr(cp,'\n'); - if (!cp++) return -(10+100*i); - - cnt = sscanf(cp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d \n" - , &ptr->summclr - , &ptr->msgsclr - , &ptr->headclr - , &ptr->taskclr); - if (cnt!=4) return -(11+100*i); - cp = strchr(cp,'\n'); - if (!cp++) return -(12+100*i); - } - return 13; -} - -static void configs_read (void) -{ - char fbuf[1600]; - const char *home; - int fd; - RCF_t sys_rcfile; - RCF_t usr_rcfile; - - memcpy(&sys_rcfile, &RCf_Defaults, sizeof(sys_rcfile)); - fd = open(SYS_RCFILE, O_RDONLY); - if (fd>0) { - ssize_t num; - fbuf[0] = '\n'; - fbuf[1] = '\n'; - num = read(fd, fbuf+2, sizeof(fbuf)-3); - if (num>0) { - fbuf[num+2] = '\0'; - read_config_rik(fbuf,num,&sys_rcfile); // not setting Crufty_config - read_config_jim(fbuf,num,&sys_rcfile); - } - close(fd); - } + char buf[40]; + char *cp = Winstk[i]->rc.fieldscur; + int j = 0; - memcpy(&usr_rcfile, &RCf_Defaults, sizeof(usr_rcfile)); - home = getenv("HOME"); - if (home && *home) { - snprintf(RCfile, sizeof(RCfile), "%s/.%src", home, Myname); - fd = open(RCfile, O_RDONLY); - if (fd>0) { - ssize_t num; - fbuf[0] = '\n'; - fbuf[1] = '\n'; - num = read(fd, fbuf+2, sizeof(fbuf)-3); - if (num>0) { -//int i; - fbuf[num+2] = '\0'; -// fprintf(stderr, "%d\n", read_config_rik(fbuf,num,&usr_rcfile)); for(;;); - if (read_config_rik(fbuf,num,&usr_rcfile) > 0) Crufty_config = 1; - else memcpy(&usr_rcfile, &RCf_Defaults, sizeof(usr_rcfile)); // maybe mangled -//if(i<=0){ fprintf(stderr,"FAILURE: read_config_rik returned %d\n",i); for(;;); } - read_config_jim(fbuf,num,&usr_rcfile); + while (j < 36) { + int c = *cp++ & 0xff; + switch (c) { + case '.': + case 1 ... ' ': + case 0x7f ... 0xff: + continue; // throw away junk (some of it) + default: + buf[j++] = c; // gets the '\0' too } - close(fd); + if (!c) break; } + fprintf(fp, "%s\tfieldscur=%s\n" + , Winstk[i]->rc.winname, buf); + fprintf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n" + , Winstk[i]->rc.winflags, Winstk[i]->rc.sortindx, Winstk[i]->rc.maxtasks); + fprintf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" + , Winstk[i]->rc.summclr, Winstk[i]->rc.msgsclr + , Winstk[i]->rc.headclr, Winstk[i]->rc.taskclr); } - - memcpy(&Winstk[0]->rc, &usr_rcfile.win[0], sizeof(rcwin)); - memcpy(&Winstk[1]->rc, &usr_rcfile.win[1], sizeof(rcwin)); - memcpy(&Winstk[2]->rc, &usr_rcfile.win[2], sizeof(rcwin)); - memcpy(&Winstk[3]->rc, &usr_rcfile.win[3], sizeof(rcwin)); - Mode_altscr = usr_rcfile.Mode_altscr; - Mode_irixps = usr_rcfile.Mode_irixps; - Curwin = Winstk[usr_rcfile.Curwin]; - - /* lastly, establish the true runtime secure mode and delay time */ - if (getuid()) { - Secure_mode = sys_rcfile.Secure_mode; - } else { - Secure_mode = 0; - } - if (Secure_mode) { - Delay_time = sys_rcfile.Delay_time; - } else { - Delay_time = usr_rcfile.Delay_time; - } -//print_rc(&sys_rcfile); -//print_rc(&usr_rcfile); } -static void write_config_rik(FILE *fp, const RCF_t * const rc){ - char buf[40]; - char *cp = Winstk[0]->rc.fieldscur; + +static void rc_write_old (FILE *fp) { + char buf[SMLBUFSIZ]; + char *cp = Curwin->rc.fieldscur; int j = 0; int tmp; + while (j < 36) { int c = *cp++ & 0xff; - if(c=='M') c='L'; - if(c=='m') c='l'; + if (c == 'M') c = 'L'; + if (c == 'm') c = 'l'; switch (c) { - case 1 ... ' ': case '.': - case 'X': // trying not to crash Rik's top (move COMMAND) + case 'x': // try not to crash Rik's top (move COMMAND) + case 'X': // try not to crash Rik's top (move COMMAND) + case 1 ... ' ': case 0x7f ... 0xff: - continue; // throw away junk (some of it) + continue; // throw away junk (some of it) default: - c = jim_to_rik(c); - if(!c) continue; // skip one we can't represent + c = ft_cvt_char(FT_NEW_fmt, FT_OLD_fmt, c); + if (!c) continue; // skip one we can't represent break; case '\0': - buf[j++] = 'X'; // trying not to crash Rik's top (move COMMAND) + buf[j++] = 'X'; // try not to crash Rik's top (move COMMAND) break; } buf[j++] = c; @@ -1535,29 +1447,30 @@ static void write_config_rik(FILE *fp, const RCF_t * const rc){ fprintf(fp, "%s\n", buf); cp = buf; - tmp = (int)(rc->Delay_time + 0.5); + tmp = (int)(Rc.delay_time + 0.5); if (tmp < 2) tmp = 2; if (tmp > 9) tmp = 9; *cp++ = tmp + '0'; - tmp = rc->win[0].winflags; - if ( rc->Secure_mode) *cp++ = 's'; + tmp = Curwin->rc.winflags; +// if ( Secure_mode) *cp++ = 's'; // stupid to have in local rcfile if ( tmp & Show_CTIMES) *cp++ = 'S'; if ( tmp & Show_CMDLIN) *cp++ = 'c'; if (~tmp & Show_IDLEPS) *cp++ = 'i'; - //if () *cp++ = 'H'; +// if ( ) *cp++ = 'H'; // 'H' = show threads (yea, sure) if (~tmp & View_MEMORY) *cp++ = 'm'; if (~tmp & View_LOADAV) *cp++ = 'l'; if (~tmp & View_STATES) *cp++ = 't'; - if (!rc->Mode_irixps) *cp++ = 'I'; - switch (rc->win[0].sortindx) { + if (!Rc.mode_irixps) *cp++ = 'I'; + + switch (Curwin->rc.sortindx) { case P_MEM: *cp++ = 'M'; break; case P_CPU: *cp++ = 'P'; break; -// case P_???: sort by start_time +// case P_???: // was by start_time (non-display) // *cp++ = 'A'; // break; case P_TM2: @@ -1567,73 +1480,116 @@ static void write_config_rik(FILE *fp, const RCF_t * const rc){ *cp++ = 'N'; break; } - - *cp++ = '\n'; - *cp++ = '\n'; - *cp++ = '\n'; *cp++ = '\0'; - fprintf(fp, "%s\n", buf); + fprintf(fp, "%s\n\n\n", buf); // important "\n\n" separator! +} + + +static const char *rc_write_whatever (void) { + FILE *fp = fopen(Rc_name, "w"); + + if (!fp) return strerror(errno); + if (Crufty_rcf) rc_write_old(fp); + rc_write_new(fp); + fclose(fp); + return NULL; } -static void write_config_jim(FILE *fp){ + +/*###### Startup routines ##############################################*/ + + /* + * No mater what *they* say, we handle the really really BIG and + * IMPORTANT stuff upon which all those lessor functions depend! */ +static void before (char *me) +{ int i; - fprintf(fp, "RCfile for \"%s with windows\"\t\t# shameless braggin'\n" - , Myname); - fprintf(fp, "Id:%c, " - "Mode_altscr=%d, Mode_irixps=%d, Delay_time=%.3f, Curwin=%d\n" - , RCF_FILEID - , Mode_altscr, Mode_irixps, Delay_time, Curwin - Winstk[0]); - for (i = 0; i < GROUPSMAX; i++) { - char buf[40]; - char *cp = Winstk[i]->rc.fieldscur; - int j = 0; - while (j < 36) { - int c = *cp++ & 0xff; - switch (c) { - case 1 ... ' ': - case '.': - case 0x7f ... 0xff: - continue; // throw away junk (some of it) - default: - buf[j++] = c; // gets the '\0' too - } - if (!c) break; + + /* setup our program name -- big! */ + Myname = strrchr(me, '/'); + if (Myname) ++Myname; else Myname = me; + + /* establish cpu particulars -- even bigger! */ +#ifdef PRETEND4CPUS + Cpu_tot = 4; +#else + Cpu_tot = smp_num_cpus; +#endif + Cpu_map = alloc_r(NULL, sizeof(int) * Cpu_tot); + for (i = 0; i < Cpu_tot; i++) + Cpu_map[i] = i; + if (linux_version_code > LINUX_VERSION(2, 5, 41)) + States_fmts = STATES_line2x5; + + /* get virtual page size -- nearing huge! */ + Page_size = getpagesize(); +} + + /* + * First attempt to read the /etc/rcfile which contains two lines + * consisting of the secure mode switch and an update interval. + * It's presence limits what ordinary users are allowed to do. + * + * Then build the local rcfile name and try to read a crufty old-top + * rcfile (whew, odoriferous), which may contain an embedded new-style + * rcfile. Whether embedded or standalone, new-style rcfile values + * will always override that crufty stuff! + * note: If running in secure mode via the /etc/rcfile, + * Delay_time will be ignored except for root. */ +static void configs_read (void) +{ + char fbuf[MEDBUFSIZ]; + const char *cp; + int i, fd; + RCF_t rcf; + float delay = Rc.delay_time; + + // who says life's not fair -- at least the sys rcfiles are compatable + fd = open(SYS_RCFILESPEC, O_RDONLY); + if (fd > 0) { + ssize_t num; + num = read(fd, fbuf, sizeof(fbuf) - 1); + if (num > 0) { + if ((cp = strchr(fbuf, 's'))) Secure_mode = 1; + cp++; + if ((cp = strchr(cp, '\n'))) sscanf(cp+1, "%f", &Rc.delay_time); } - fprintf(fp, "%s\tfieldscur=%s\n" - , Winstk[i]->rc.winname, buf); - fprintf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n" - , Winstk[i]->rc.winflags - , Winstk[i]->rc.sortindx - , Winstk[i]->rc.maxtasks); - fprintf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" - , Winstk[i]->rc.summclr - , Winstk[i]->rc.msgsclr - , Winstk[i]->rc.headclr - , Winstk[i]->rc.taskclr); + close(fd); } -} -static const char * write_config(void){ - RCF_t usr_rcfile; - FILE *fp = fopen(RCfile, "w"); + snprintf(Rc_name, sizeof(Rc_name), ".%src", Myname); + if (getenv("HOME")) + snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", getenv("HOME"), Myname); - memcpy(&usr_rcfile.win[0], &Winstk[0]->rc, sizeof(rcwin)); - memcpy(&usr_rcfile.win[1], &Winstk[1]->rc, sizeof(rcwin)); - memcpy(&usr_rcfile.win[2], &Winstk[2]->rc, sizeof(rcwin)); - memcpy(&usr_rcfile.win[3], &Winstk[3]->rc, sizeof(rcwin)); - usr_rcfile.Mode_altscr = Mode_altscr; - usr_rcfile.Mode_irixps = Mode_irixps; - usr_rcfile.Curwin = Curwin - Winstk[0]; - usr_rcfile.Secure_mode = Secure_mode; - usr_rcfile.Delay_time = Delay_time; + rcf = Rc; + fd = open(Rc_name, O_RDONLY); + if (fd > 0) { + ssize_t num; + num = read(fd, fbuf+2, sizeof(fbuf) -3); + if (num > 0) { + fbuf[0] = '\n'; + fbuf[1] = '\n'; + fbuf[num+2] = '\0'; + if (rc_read_old(fbuf, &rcf) > 0) Crufty_rcf = 1; + else rcf = Rc; // on failure, maybe mangled + rc_read_new(fbuf, &rcf); + delay = rcf.delay_time; + } + close(fd); + } - if (!fp) return strerror(errno); - if(Crufty_config) write_config_rik(fp, &usr_rcfile); - write_config_jim(fp); - fclose(fp); - return NULL; + // update Rc defaults, establish a Curwin and fix up the window stack + Rc.mode_altscr = rcf.mode_altscr; + Rc.mode_irixps = rcf.mode_irixps; + Curwin = Winstk[(rcf.win_index)]; + for (i = 0; i < GROUPSMAX; i++) Winstk[i]->rc = rcf.win[i]; + + // lastly, establish the true runtime secure mode and delay time + Secure_mode = getuid() ? Secure_mode : 0; + if (!Secure_mode || !getuid()) Rc.delay_time = delay; } + /* * Parse command line arguments. * Note: it's assumed that the rc file(s) have already been read @@ -1733,7 +1689,7 @@ static void parse_args (char **args) if (Secure_mode || 0 > tmp_delay) msg_save("Delay time Not changed"); else - Delay_time = tmp_delay; + Rc.delay_time = tmp_delay; } } @@ -1795,21 +1751,20 @@ static void display_fields (const char *fields, const char *xtra) /* we're relying on callers to first clear the screen and thus avoid screen flicker if they're too lazy to handle their own asterisk (*) logic */ putp(Curwin->cap_bold); - for (i = 0; i < MAXTBL(Fieldstab); ++i) { - int c; - int b = (NULL != strchr(fields, i + 'A')); + for (i = 0; fields[i]; ++i) { + const FLD_t *f = ft_get_ptr(FT_NEW_fmt, fields[i]); + int b = isupper(fields[i]); + if (!f) continue; // hey, should be std_err! /* advance past any leading spaces */ - for (p = Fieldstab[i].head; ' ' == *p; ++p) + for (p = f->head; ' ' == *p; ++p) ; - c = jim_to_rik(b ? i + 'A' : i + 'a'); - if (!c) continue; PUTT("%s%s%c %c: %-10s = %s" , tg2((i / rmax) * cmax, (i % rmax) + yRSVD) , b ? Curwin->cap_bold : Cap_norm , b ? '*' : ' ' - , c + , fields[i] , p - , Fieldstab[i].desc); + , f->desc); } if (xtra) { putp(Curwin->capclr_rownorm); @@ -1839,13 +1794,13 @@ static void fields_reorder (void) putp(Cap_clr_scr); putp(Cap_curs_huge); - display_fields(Curwin->rc.fieldscur, FIELDS_xtra); for (;;) { + display_fields(Curwin->rc.fieldscur, FIELDS_xtra); show_special(1, fmtmk(FIELDS_current , Cap_home, Curwin->rc.fieldscur, Curwin->grpname, prompt)); chin(0, &c, 1); + if (!ft_get_ptr(FT_NEW_fmt, c)) break; i = toupper(c) - 'A'; - if (i < 0 || i >= MAXTBL(Fieldstab)) break; if (((p = strchr(Curwin->rc.fieldscur, i + 'A'))) || ((p = strchr(Curwin->rc.fieldscur, i + 'a')))) { if (isupper(c)) p--; @@ -1880,8 +1835,8 @@ static void fields_sort (void) show_special(1, fmtmk(SORT_fields , Cap_home, *p, Curwin->grpname, prompt)); chin(0, &c, 1); + if (!ft_get_ptr(FT_NEW_fmt, c)) break; i = toupper(c) - 'A'; - if (i < 0 || i >= MAXTBL(Fieldstab)) break; *p = tolower(*p); x = i; } @@ -1908,8 +1863,8 @@ static void fields_toggle (void) show_special(1, fmtmk(FIELDS_current , Cap_home, Curwin->rc.fieldscur, Curwin->grpname, prompt)); chin(0, &c, 1); - i = rik_to_jim(c) & 0x1f; // was: i = toupper(c) - 'A'; - if (i < 0 || i >= MAXTBL(Fieldstab)) break; + if (!ft_get_ptr(FT_NEW_fmt, c)) break; + i = toupper(c) - 'A'; if ((p = strchr(Curwin->rc.fieldscur, i + 'A'))) *p = i + 'a'; else if ((p = strchr(Curwin->rc.fieldscur, i + 'a'))) @@ -1934,10 +1889,11 @@ static void reframewins (void) const char *h; int i, needpsdb = 0; -// Frame_libflgs = 0; // should be called only when it's zero +// Frams_libflags = 0; // should be called only when it's zero +// Frams_maxcmdln = 0; // to become the largest from the 4 windows w = Curwin; do { - if (!Mode_altscr || CHKw(w, VISIBLE_tsk)) { + if (!Rc.mode_altscr || CHKw(w, VISIBLE_tsk)) { // build window's procflags array and establish a tentative maxpflgs for (i = 0, w->maxpflgs = 0; w->rc.fieldscur[i]; i++) { if (isupper(w->rc.fieldscur[i])) @@ -1947,7 +1903,7 @@ static void reframewins (void) /* build a preliminary columns header not to exceed screen width while accounting for a possible leading window number */ *(s = w->columnhdr) = '\0'; - if (Mode_altscr) s = scat(s, " "); + if (Rc.mode_altscr) s = scat(s, " "); for (i = 0; i < w->maxpflgs; i++) { h = Fieldstab[w->procflags[i]].head; // oops, won't fit -- we're outta here... @@ -1967,19 +1923,22 @@ static void reframewins (void) rebuild the all-important PROC_FILLxxx flags that will be used until/if we're we're called again */ *(s = w->columnhdr) = '\0'; - if (Mode_altscr) s = scat(s, fmtmk("%d", w->winnum)); + if (Rc.mode_altscr) s = scat(s, fmtmk("%d", w->winnum)); for (i = 0; i < w->maxpflgs; i++) { h = Fieldstab[w->procflags[i]].head; if (P_WCH == w->procflags[i]) needpsdb = 1; if (P_CMD == w->procflags[i]) { s = scat(s, fmtmk(Fieldstab[P_CMD].fmts, w->maxcmdln, w->maxcmdln, h)); - if (CHKw(w, Show_CMDLIN)) Frame_libflgs |= L_CMDLINE; + if (CHKw(w, Show_CMDLIN)) { + Frams_libflags |= L_CMDLINE; +// if (w->maxcmdln > Frams_maxcmdln) Frams_maxcmdln = w->maxcmdln; + } } else s = scat(s, h); - Frame_libflgs |= Fieldstab[w->procflags[i]].lflg; + Frams_libflags |= Fieldstab[w->procflags[i]].lflg; } } - if (Mode_altscr) w = w->next; + if (Rc.mode_altscr) w = w->next; } while (w != Curwin); // do we need the kernel symbol table (and is it already open?) @@ -1992,11 +1951,11 @@ static void reframewins (void) PSDBopen = 1; } } - if (Frame_libflgs & L_EITHER) { - Frame_libflgs &= ~L_EITHER; - if (!(Frame_libflgs & L_stat)) Frame_libflgs |= L_status; + if (Frams_libflags & L_EITHER) { + Frams_libflags &= ~L_EITHER; + if (!(Frams_libflags & L_stat)) Frams_libflags |= L_status; } - if (!Frame_libflgs) Frame_libflgs = L_DEFAULT; + if (!Frams_libflags) Frams_libflags = L_DEFAULT; } @@ -2209,7 +2168,7 @@ static void wins_resize (int dont_care_sig) Pseudo_scrn = alloc_r(Pseudo_scrn, Pseudo_size); // force rebuild of column headers AND libproc/readproc requirements - Frame_libflgs = 0; + Frams_libflags = 0; } @@ -2220,38 +2179,16 @@ static void wins_resize (int dont_care_sig) * [ --- life-is-NOT-fair --- ] */ static void windows_stage1 (void) { - static struct { - const char *name; - const char *flds; - const int sort; - const int clrs[4]; /* summ, msgs, heads, task */ - } wtab[] = { - { "Def", DEF_FIELDS, P_CPU, - { COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED } }, - { "Job", JOB_FIELDS, P_PID, - { COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN } }, - { "Mem", MEM_FIELDS, P_MEM, - { COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA } }, - { "Usr", USR_FIELDS, P_USR, - { COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW } }, - }; WIN_t *w; int i; - /* get all our window structs in one big chunk */ + // get all our window structs in one big chunk w = alloc_c(sizeof(WIN_t) * GROUPSMAX); for (i = 0; i < GROUPSMAX; i++) { Winstk[i] = w; w->winnum = i + 1; - strcpy(w->rc.winname, wtab[i].name); - strcpy(w->rc.fieldscur, wtab[i].flds); - w->rc.sortindx = wtab[i].sort; - w->rc.winflags = DEF_WINFLGS; - w->rc.summclr = wtab[i].clrs[0]; - w->rc.msgsclr = wtab[i].clrs[1]; - w->rc.headclr = wtab[i].clrs[2]; - w->rc.taskclr = wtab[i].clrs[3]; + w->rc = Rc.win[i]; w->captab[0] = Cap_norm; w->captab[1] = Cap_norm; w->captab[2] = w->cap_bold; @@ -2269,7 +2206,6 @@ static void windows_stage1 (void) Winstk[3]->next = Winstk[0]; Winstk[0]->prev = Winstk[3]; Curwin = Winstk[0]; - Mode_altscr = 0; } @@ -2313,11 +2249,11 @@ static void do_key (unsigned c) break; case 'a': - if (Mode_altscr) Curwin = Curwin->next; + if (Rc.mode_altscr) Curwin = Curwin->next; break; case 'A': - Mode_altscr = !Mode_altscr; + Rc.mode_altscr = !Rc.mode_altscr; wins_resize(0); break; @@ -2347,8 +2283,8 @@ static void do_key (unsigned c) show_msg(err_secure); else { float tmp = - get_float(fmtmk("Change delay from %.1f to", Delay_time)); - if (-1 < tmp) Delay_time = tmp; + get_float(fmtmk("Change delay from %.1f to", Rc.delay_time)); + if (-1 < tmp) Rc.delay_time = tmp; } break; @@ -2362,7 +2298,7 @@ static void do_key (unsigned c) break; case 'g': - if (Mode_altscr) { + if (Rc.mode_altscr) { char tmp[GETBUFSIZ]; strcpy(tmp, ask4str(fmtmk("Rename window '%s' to (1-3 chars)" , Curwin->rc.winname))); @@ -2384,7 +2320,7 @@ static void do_key (unsigned c) , procps_version , Curwin->grpname , CHKw(Curwin, Show_CTIMES) ? "On" : "Off" - , Delay_time + , Rc.delay_time , Secure_mode ? "On" : "Off" , Secure_mode ? "" : KEYS_help_unsecured)); chin(0, &ch, 1); @@ -2412,13 +2348,13 @@ static void do_key (unsigned c) case 'I': #ifdef WARN_NOT_SMP if (Cpu_tot > 1) { - Mode_irixps = !Mode_irixps; - show_msg(fmtmk("Irix mode %s", Mode_irixps ? "On" : "Off")); + Rc.mode_irixps = !Rc.mode_irixps; + show_msg(fmtmk("Irix mode %s", Rc.mode_irixps ? "On" : "Off")); } else show_msg(err_smp); #else - Mode_irixps = !Mode_irixps; - show_msg(fmtmk("Irix mode %s", Mode_irixps ? "On" : "Off")); + Rc.mode_irixps = !Rc.mode_irixps; + show_msg(fmtmk("Irix mode %s", Rc.mode_irixps ? "On" : "Off")); #endif break; @@ -2500,15 +2436,15 @@ static void do_key (unsigned c) break; case 'w': - if (Mode_altscr) Curwin = Curwin->prev; + if (Rc.mode_altscr) Curwin = Curwin->prev; break; case 'W': - { const char *err = write_config(); + { const char *err = rc_write_whatever(); if (err) - show_msg(fmtmk("\aFailed '%s' open: %s", RCfile, err)); + show_msg(fmtmk("\aFailed '%s' open: %s", Rc_name, err)); else - show_msg(fmtmk("Wrote configuration to '%s'", RCfile)); + show_msg(fmtmk("Wrote configuration to '%s'", Rc_name)); } break; @@ -2538,11 +2474,11 @@ static void do_key (unsigned c) break; case '-': - if (Mode_altscr) TOGw(Curwin, VISIBLE_tsk); + if (Rc.mode_altscr) TOGw(Curwin, VISIBLE_tsk); break; case '_': - if (Mode_altscr) wins_reflag(Flags_TOG, VISIBLE_tsk); + if (Rc.mode_altscr) wins_reflag(Flags_TOG, VISIBLE_tsk); break; case '=': @@ -2552,12 +2488,12 @@ static void do_key (unsigned c) break; case '+': - if (Mode_altscr) SETw(Curwin, EQUWINS_cwo); + if (Rc.mode_altscr) SETw(Curwin, EQUWINS_cwo); break; case '<': if (VIZCHKc) { - PFLG_t *p = Curwin->procflags + Curwin->maxpflgs - 1; + FLG_t *p = Curwin->procflags + Curwin->maxpflgs - 1; while (*p != Curwin->rc.sortindx) --p; if (--p >= Curwin->procflags) Curwin->rc.sortindx = *p; @@ -2566,7 +2502,7 @@ static void do_key (unsigned c) case '>': if (VIZCHKc) { - PFLG_t *p = Curwin->procflags; + FLG_t *p = Curwin->procflags; while (*p != Curwin->rc.sortindx) ++p; if (++p < Curwin->procflags + Curwin->maxpflgs) Curwin->rc.sortindx = *p; @@ -2580,7 +2516,7 @@ static void do_key (unsigned c) { static struct { const unsigned xkey; const char *xmsg; - const PFLG_t sort; + const FLG_t sort; } xtab[] = { { 'M', "Memory", P_MEM, }, { 'N', "Numerical", P_PID, }, { 'P', "CPU", P_CPU, }, { 'T', "Time", P_TM2 }, }; @@ -2619,7 +2555,7 @@ static void do_key (unsigned c) ( At this point we have a human being involved and so have all the time ) ( in the world. We can afford a few extra cpu cycles every now & then! ) */ - Frame_libflgs = 0; + Frams_libflags = 0; } @@ -2631,12 +2567,12 @@ static void do_key (unsigned c) * 2) modest smp boxes with room for each cpu's percentages * 3) massive smp guys leaving little or no room for process * display and thus requiring the cpu summary toggle */ -static void summaryhlp (CPUS_t *cpu, const char *pfx) +static void summaryhlp (CPU_t *cpu, const char *pfx) { /* we'll trim to zero if we get negative time ticks, which has happened with some SMP kernels (pre-2.4?) */ -#define TRIMz(x) ((tz = (STIC_t)(x)) < 0 ? 0 : tz) - STIC_t u_frme, s_frme, n_frme, i_frme, w_frme, tot_frme, tz; +#define TRIMz(x) ((tz = (SIC_t)(x)) < 0 ? 0 : tz) + SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, tot_frme, tz; float scale; u_frme = cpu->u - cpu->u_sav; @@ -2680,7 +2616,7 @@ static void summaryhlp (CPUS_t *cpu, const char *pfx) static proc_t **summary_show (void) { static proc_t **p_table = NULL; - static CPUS_t *smpcpu = NULL; + static CPU_t *smpcpu = NULL; // whoa first time, gotta' prime the pump... if (!p_table) { @@ -2689,13 +2625,12 @@ static proc_t **summary_show (void) sleep(1); } else putp(Batch ? "\n\n" : Cap_home); - - p_table = procs_refresh(p_table, Frame_libflgs); + p_table = procs_refresh(p_table, Frams_libflags); /* ** Display Uptime and Loadavg */ if (CHKw(Curwin, View_LOADAV)) { - if (!Mode_altscr) + if (!Rc.mode_altscr) show_special(0, fmtmk(LOADAV_line, Myname, sprint_uptime())); else show_special(0, fmtmk(CHKw(Curwin, VISIBLE_tsk) @@ -2723,7 +2658,7 @@ static proc_t **summary_show (void) char tmp[SMLBUFSIZ]; // display each cpu's states separately for (i = 0; i < Cpu_tot; i++) { - snprintf(tmp, sizeof(tmp), " Cpu%-2d:", Mode_irixps ? i : Cpu_map[i]); + snprintf(tmp, sizeof(tmp), " Cpu%-2d:", Rc.mode_irixps ? i : Cpu_map[i]); summaryhlp(&smpcpu[i], tmp); } } @@ -2761,17 +2696,18 @@ static void task_show (const WIN_t *q, const proc_t *p) pad += q->len_rowhigh; \ if (!(CHKw(q, Show_HIROWS) && 'R' == p->state)) pad += q->len_rownorm; \ } } while (0) + // the format for 'command line' display in absence of same (kernel thread) char rbuf[ROWBUFSIZ], *rp; int j, x, pad; // we must begin a row with a possible window number in mind... *(rp = rbuf) = '\0'; - if ((pad = Mode_altscr)) rp = scat(rp, " "); + if ((pad = Rc.mode_altscr)) rp = scat(rp, " "); for (x = 0; x < q->maxpflgs; x++) { char cbuf[ROWBUFSIZ], _z[ROWBUFSIZ]; - PFLG_t i = q->procflags[x]; // support for our field/column + FLG_t i = q->procflags[x]; // support for our field/column const char *f = Fieldstab[i].fmts; // macro AND sometimes the fmt unsigned s = Fieldstab[i].scale; // string must be altered ! unsigned w = Fieldstab[i].width; @@ -2870,7 +2806,7 @@ static void task_show (const WIN_t *q, const proc_t *p) break; case P_TME: case P_TM2: - { TICS_t t = p->utime + p->stime; + { TIC_t t = p->utime + p->stime; if (CHKw(q, Show_CTIMES)) t += (p->cutime + p->cstime); MKCOL(scale_tics(t, w)); @@ -2928,8 +2864,8 @@ static void window_show (proc_t **ppt, WIN_t *q, int *lscr) #ifdef SORT_SUPRESS // the 1 flag that DOES and 2 flags that MAY impact our proc table qsort #define srtMASK ~( Qsrt_NORMAL | Show_CMDLIN | Show_CTIMES ) - static PFLG_t sav_indx = 0; - static int sav_flgs = -1; + static FLG_t sav_indx = 0; + static int sav_flgs = -1; #endif int i, lwin; @@ -3043,7 +2979,7 @@ static void frame_make (void) /* note: except for PROC_PID, all libproc flags are managed by reframewins(), who also builds each window's column headers */ - if (!Frame_libflgs) { + if (!Frams_libflags) { reframewins(); memset(Pseudo_scrn, '\0', Pseudo_size); } @@ -3057,7 +2993,7 @@ static void frame_make (void) // sure hope each window's columns header begins with a newline... putp(tg2(0, Msg_row)); - if (!Mode_altscr) { + if (!Rc.mode_altscr) { // only 1 window to show so, piece o' cake Curwin->winlines = Curwin->rc.maxtasks; window_show(ppt, Curwin, &scrlins); @@ -3137,10 +3073,10 @@ int main (int dont_care_argc, char **argv) if (!Loops) end_pgm(0); if (Batch) - sleep((unsigned)Delay_time); + sleep((unsigned)Rc.delay_time); else { // Linux reports time not slept, - tv.tv_sec = Delay_time; // so we must reinit every time. - tv.tv_usec = (Delay_time - (int)Delay_time) * 1000000; + tv.tv_sec = Rc.delay_time; // so we must reinit every time. + tv.tv_usec = (Rc.delay_time - (int)Rc.delay_time) * 1000000; FD_ZERO(&fs); FD_SET(STDIN_FILENO, &fs); if (0 < select(STDIN_FILENO+1, &fs, NULL, NULL, &tv) diff --git a/top.h b/top.h index fca5956c..2cabee36 100644 --- a/top.h +++ b/top.h @@ -60,6 +60,8 @@ /* the above might seem pretty stingy, until you consider that with every one of top's fields displayed we're talking a 160 byte column header -- so that will provide for all fields plus a 350+ byte command line */ +#define WINNAMSIZ 4 +#define CAPTABMAX 9 #define PFLAGSSIZ 32 #define CAPBUFSIZ 32 #define CLRBUFSIZ 64 @@ -67,6 +69,7 @@ #define TNYBUFSIZ 32 #define SMLBUFSIZ 256 #define OURPATHSZ 1024 +#define MEDBUFSIZ 1024 #define BIGBUFSIZ 2048 #define USRNAMSIZ GETBUFSIZ #define ROWBUFSIZ SCREENMAX + CLRBUFSIZ @@ -87,23 +90,23 @@ #define SORT_gt ( Frame_srtflg > 0 ? -1 : 1 ) #define SORT_eq 0 - /* Used to reference and create sort callback functions -- + /* Used to create *most* of the sort callback functions note: some of the callbacks are NOT your father's callbacks, they're highly optimized to save them ol' precious cycles! */ -#define _SC_NUM1(f,n) \ +#define SCB_NUM1(f,n) \ static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ if ( (*P)->n < (*Q)->n ) return SORT_lt; \ if ( (*P)->n > (*Q)->n ) return SORT_gt; \ return SORT_eq; } -#define _SC_NUM2(f,n1,n2) \ +#define SCB_NUM2(f,n1,n2) \ static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ if ( ((*P)->n1 - (*P)->n2) < ((*Q)->n1 - (*Q)->n2) ) return SORT_lt; \ if ( ((*P)->n1 - (*P)->n2) > ((*Q)->n1 - (*Q)->n2) ) return SORT_gt; \ return SORT_eq; } -#define _SC_NUMx(f,n) \ +#define SCB_NUMx(f,n) \ static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ return Frame_srtflg * ( (*Q)->n - (*P)->n ); } -#define _SC_STRx(f,s) \ +#define SCB_STRx(f,s) \ static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ return Frame_srtflg * strcmp((*Q)->s, (*P)->s); } @@ -154,43 +157,64 @@ /*###### Some Typedef's and Enum's #####################################*/ /* This typedef just ensures consistent 'process flags' handling */ -typedef unsigned PFLG_t; +typedef unsigned FLG_t; /* These typedefs attempt to ensure consistent 'ticks' handling */ -typedef unsigned long long TICS_t; -typedef long long STIC_t; +typedef unsigned long long TIC_t; +typedef long long SIC_t; - /* Sorted columns support. */ -typedef int (*QSORT_t)(const void *, const void *); + /* Sort support, callback funtion signature */ +typedef int (*QFP_t)(const void *, const void *); /* This structure consolidates the information that's used in a variety of display roles. */ -typedef struct { - const char keys[4]; // order: Jim-on Jim-off Rik-on Rik-off - const char *head; /* name for column headings + toggle/reorder fields */ - const char *fmts; /* sprintf format string for field display */ - const int width; /* field width, if applicable */ - const int scale; /* scale_num type, if applicable */ - const QSORT_t sort; /* sort function */ - const char *desc; /* description for toggle/reorder fields */ - const int lflg; /* PROC_FILLxxx flag(s) required for this field */ -} FTAB_t; +typedef struct FLD_t { + const char keys [4]; // order: New-on New-off Old-on Old-off + const char *head; // name for col heads + toggle/reorder fields + const char *fmts; // sprintf format string for field display + const int width; // field width, if applicable + const int scale; // scale_num type, if applicable + const QFP_t sort; // sort function + const char *desc; // description for toggle/reorder fields + const int lflg; // PROC_FILLxxx flag(s) needed by this field +} FLD_t; /* This structure stores one piece of critical 'history' information from one frame to the next -- we don't calc and save data that goes unused like the old top! */ -typedef struct { - int pid; - TICS_t tics; -} HIST_t; +typedef struct HST_t { + int pid; + TIC_t tics; +} HST_t; /* This structure stores a frame's cpu tics used in history calculations. It exists primarily for SMP support but serves all environments. */ -typedef struct { - TICS_t u, n, s, i, w; // as represented in /proc/stat - TICS_t u_sav, s_sav, n_sav, i_sav, w_sav; // in the order of our display -} CPUS_t; +typedef struct CPU_t { + TIC_t u, n, s, i, w; // as represented in /proc/stat + TIC_t u_sav, s_sav, n_sav, i_sav, w_sav; // in the order of our display +} CPU_t; + + /* These 2 types support rcfile compatibility */ +typedef struct RCW_t { // the 'window' portion of an rcfile + FLG_t sortindx; // sort field, represented as a procflag + int winflags, // 'view', 'show' and 'sort' mode flags + maxtasks, // user requested maximum, 0 equals all + summclr, // color num used in summ info + msgsclr, // " in msgs/pmts + headclr, // " in cols head + taskclr; // " in task rows + char winname [WINNAMSIZ], // window name, user changeable + fieldscur [PFLAGSSIZ]; // fields displayed and ordered +} RCW_t; + +typedef struct RCF_t { // the complete rcfile (new style) + int mode_altscr; // 'A' - Alt display mode (multi task windows) + int mode_irixps; // 'I' - Irix vs. Solaris mode (SMP-only) + float delay_time; // 'd' or 's' - How long to sleep twixt updates + int win_index; // Curwin, as index + RCW_t win [4]; // a 'WIN_t.rc' for each of the 4 windows +} RCF_t; /* The scaling 'type' used with scale_num() -- this is how the passed number is interpreted should scaling be necessary */ @@ -214,9 +238,7 @@ enum pflag { /* (kind of a header within a header: constants, macros & types) */ #define GROUPSMAX 4 /* the max number of simultaneous windows */ -#define WINNAMSIZ 4 /* max size of a window's basic name */ -#define GRPNAMSIZ 6 /* window's name + number as in: '#:...' */ -#define CAPTABMAX 9 /* a window's captab used by show_special */ +#define GRPNAMSIZ WINNAMSIZ+2 /* window's name + number as in: '#:...' */ #define Flags_TOG 1 /* these are used to direct wins_reflag */ #define Flags_SET 2 @@ -258,68 +280,47 @@ enum pflag { #define TOGw(q,f) q->rc.winflags ^= (f) #define SETw(q,f) q->rc.winflags |= (f) #define OFFw(q,f) q->rc.winflags &= ~(f) -#define VIZCHKc (!Mode_altscr || Curwin->rc.winflags & VISIBLE_tsk) \ +#define VIZCHKc (!Rc.mode_altscr || Curwin->rc.winflags & VISIBLE_tsk) \ ? 1 : win_warn() -#define VIZTOGc(f) (!Mode_altscr || Curwin->rc.winflags & VISIBLE_tsk) \ +#define VIZTOGc(f) (!Rc.mode_altscr || Curwin->rc.winflags & VISIBLE_tsk) \ ? TOGw(Curwin, f) : win_warn() -typedef struct rcwin { - char winname [WINNAMSIZ], /* window name, user changeable */ - fieldscur [PFLAGSSIZ]; /* fields displayed and ordered */ - int winflags; /* 'view', 'show' and 'sort' mode flags */ - PFLG_t sortindx; /* sort field, as a procflag */ - int maxtasks, /* user requested maximum, 0 equals all */ - summclr, /* color num used in summ info */ - msgsclr, /* " in msgs/pmts */ - headclr, /* " in cols head */ - taskclr; /* " in task display */ -} rcwin; - -typedef struct rcf { // global/system-wide - int Secure_mode; // Secure_mode (not in Jim-format files) - int Mode_altscr; // Mode_altscr - int Mode_irixps; // Mode_irixps - float Delay_time; // Delay_time - int Curwin; // Curwin - rcwin win[4]; // each of 4 windows -} RCF_t; - /* This structure stores configurable information for each window. By expending a little effort in its creation and user requested maintainence, the only real additional per frame cost of having windows is an extra sort -- but that's just on ptrs! */ -typedef struct win { - struct win *next, /* next window in window stack */ - *prev; /* prior window in window stack */ - char *captab [CAPTABMAX]; /* captab needed by show_special */ - int winnum, /* window's num (array pos + 1) */ - winlines; /* task window's rows (volatile) */ - PFLG_t procflags [PFLAGSSIZ]; /* fieldscur subset, as enum */ - int maxpflgs, /* number of procflags (upcase fieldscur) */ - maxcmdln; /* max length of a process' command line */ - int len_rownorm, /* lengths of the corresponding terminfo */ - len_rowhigh; /* strings to avoid repeated strlen calls */ - rcwin rc; /* stuff that gets saved in a .toprc file */ - char capclr_sum [CLRBUFSIZ], /* terminfo strings built from */ - capclr_msg [CLRBUFSIZ], /* above clrs (& rebuilt too), */ - capclr_pmt [CLRBUFSIZ], /* but NO recurring costs !!! */ - capclr_hdr [CLRBUFSIZ], /* note: sum, msg and pmt strs */ - capclr_rowhigh [CLRBUFSIZ], /* are only used when this */ - capclr_rownorm [CLRBUFSIZ]; /* window is the 'Curwin'! */ - char cap_bold [CAPBUFSIZ]; /* support for View_NOBOLD toggle */ - char grpname [GRPNAMSIZ], /* window number:name, printable */ - columnhdr [SCREENMAX], /* column headings for procflags */ - colusrnam [USRNAMSIZ]; /* if selected by the 'u' command */ +typedef struct WIN_t { + struct WIN_t *next, // next window in window stack + *prev; // prior window in window stack + char *captab [CAPTABMAX]; // captab needed by show_special + int winnum, // window's num (array pos + 1) + winlines; // task window's rows (volatile) + FLG_t procflags [PFLAGSSIZ]; // fieldscur subset, as enum + int maxpflgs, // number of procflags (upcase fieldscur) + maxcmdln; // max length of a process' command line + int len_rownorm, // lengths of the corresponding terminfo + len_rowhigh; // strings to avoid repeated strlen calls + RCW_t rc; // stuff that gets saved in the rcfile + char capclr_sum [CLRBUFSIZ], // terminfo strings built from + capclr_msg [CLRBUFSIZ], // above clrs (& rebuilt too), + capclr_pmt [CLRBUFSIZ], // but NO recurring costs !!! + capclr_hdr [CLRBUFSIZ], // note: sum, msg and pmt strs + capclr_rowhigh [CLRBUFSIZ], // are only used when this + capclr_rownorm [CLRBUFSIZ]; // window is the 'Curwin'! + char cap_bold [CAPBUFSIZ]; // support for View_NOBOLD toggle + char grpname [GRPNAMSIZ], // window number:name, printable + columnhdr [SCREENMAX], // column headings for procflags + colusrnam [USRNAMSIZ]; // if selected by the 'u' command } WIN_t; /* ////////////////////////////////////////////////////////////// */ /*###### Display Support *Data* ########################################*/ - /* An rcfile 'footprint' used to invalidate existing local rcfile - and the global rcfile path + name */ -#define RCF_FILEID 'a' -#define SYS_RCFILE "/etc/toprc" + /* Configuration files support */ +#define SYS_RCFILESPEC "/etc/toprc" +#define RCF_EYECATCHER "RCfile for " +#define RCF_DEPRECATED "Id:a, " /* The default fields displayed and their order, if nothing is specified by the loser, oops user */ @@ -331,6 +332,24 @@ typedef struct win { /* Used by fields_sort, placed here for peace-of-mind */ #define NUL_FIELDS "abcdefghijklmnopqrstuvwxyz" + + /* The default values for the local config file */ +#define DEF_RCFILE { \ + 0, 1, DEF_DELAY, 0, { \ + { P_CPU, DEF_WINFLGS, 0, \ + COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED, \ + "Def", DEF_FIELDS }, \ + { P_PID, DEF_WINFLGS, 0, \ + COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN, \ + "Job", JOB_FIELDS }, \ + { P_MEM, DEF_WINFLGS, 0, \ + COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA, \ + "Mem", MEM_FIELDS }, \ + { P_USR, DEF_WINFLGS, 0, \ + COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW, \ + "Usr", USR_FIELDS } \ + } } + /* These are the possible fscanf formats used in /proc/stat reads during history processing. ( 5th number only for Linux 2.5.41 and above ) */ @@ -349,20 +368,6 @@ typedef struct win { #define CMDLINE_FMTS "( %s )" #endif - -RCF_t RCf_Defaults = { - 0, 0, 1, 3.0f, 0, { - { "Def", DEF_FIELDS, DEF_WINFLGS, P_CPU, 0, - COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED }, - { "Job", JOB_FIELDS, DEF_WINFLGS, P_PID, 0, - COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN }, - { "Mem", MEM_FIELDS, DEF_WINFLGS, P_MEM, 0, - COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA }, - { "Usr", USR_FIELDS, DEF_WINFLGS, P_USR, 0, - COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW } - } -}; - /* Summary Lines specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define LOADAV_line "%s -%s\n" @@ -547,15 +552,13 @@ RCF_t RCf_Defaults = { /*###### Some Prototypes (ha!) #########################################*/ - /* None of these are necessary when the source file is properly - * organized -- they're here for documentation purposes ! - * Note also that functions are alphabetical within a group to aid - * source code navigation, which often influences the identifers. */ + /* These 'prototypes' are here for documentation purposes and in + * preparation for a soon-to-occur top.c bust-up! */ /*------ Sort callbacks ------------------------------------------------*/ /* for each possible field, in the form of: */ /*atic int sort_P_XXX (const proc_t **P, const proc_t **Q); */ /* additional specialized sort callback(s) */ -/*atic int sort_HIST_t (const HIST_t *P, const HIST_t *Q); */ +/*atic int sort_HST_t (const HST_t *P, const HST_t *Q); */ /*------ Tiny useful routine(s) ----------------------------------------*/ //atic int chin (int ech, char *buf, unsigned cnt); //atic const char *fmtmk (const char *fmts, ...); @@ -578,20 +581,33 @@ RCF_t RCf_Defaults = { //atic float get_float (const char *prompt); //atic int get_int (const char *prompt); //atic const char *scale_num (unsigned num, const int width, const unsigned type); -//atic const char *scale_tics (TICS_t tics, const int width); +//atic const char *scale_tics (TIC_t tics, const int width); /*------ Library Alternatives ------------------------------------------*/ //atic void *alloc_c (unsigned numb) MALLOC; //atic void *alloc_r (void *q, unsigned numb) MALLOC; -//atic CPUS_t *cpus_refresh (CPUS_t *cpus); +//atic CPU_t *cpus_refresh (CPU_t *cpus); //atic void prochlp (proc_t *this); //atic proc_t **procs_refresh (proc_t **table, int flags); +/*------ Field Table/RCfile compatability support ----------------------*/ +/*atic FLD_t Fieldstab[] = { ... } */ +//atic int ft_cvt_char (const int fr, const int to, int c); +//atic inline int ft_get_char (const int fr, int i); +//atic int ft_get_idx (const int fr, int c); +//atic const FLD_t *ft_get_ptr (const int fr, int c); +//atic const FLD_t *ft_idx_to_ptr (const int i); +//atic int ft_ptr_to_idx (const FLD_t *p); +//atic void rc_bugless (const RCF_t *const rc); +//atic int rc_read_new (const char *const buf, RCF_t *rc); +//atic int rc_read_old (const char *const buf, RCF_t *rc); +//atic void rc_write_new (FILE *fp); +//atic void rc_write_old (FILE *fp); +//atic const char *rc_write_whatever (void); /*------ Startup routines ----------------------------------------------*/ //atic void before (char *me); //atic void configs_read (void); //atic void parse_args (char **args); //atic void whack_terminal (void); /*------ Field Selection/Ordering routines -----------------------------*/ -/*atic FTAB_t Fieldstab[] = { ... } */ //atic void display_fields (const char *fields, const char *xtra); //atic void fields_reorder (void); //atic void fields_sort (void); @@ -609,7 +625,7 @@ RCF_t RCf_Defaults = { //atic void windows_stage2 (void); /*------ Main Screen routines ------------------------------------------*/ //atic void do_key (unsigned c); -//atic void summaryhlp (CPUS_t *cpu, const char *pfx); +//atic void summaryhlp (CPU_t *cpu, const char *pfx); //atic proc_t **summary_show (void); //atic void task_show (const WIN_t *q, const proc_t *p); //atic void window_show (proc_t **ppt, WIN_t *q, int *lscr); -- 2.40.0