⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 top.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CASEUP_SCALE   static char nextup[] =  { 'K', 'M', 'G', 'T', 0 };#else   static char nextup[] =  { 'k', 'm', 'g', 't', 0 };#endif   static char buf[TNYBUFSIZ];   double *dp;   char *up;      /* try an unscaled version first... */   if (width >= snprintf(buf, sizeof(buf), "%lu", num)) return buf;      /* now try successively higher types until it fits */   for (up = nextup + type, dp = scale; *dp; ++dp, ++up) {         /* the most accurate version */      if (width >= snprintf(buf, sizeof(buf), "%.1f%c", num / *dp, *up))         return buf;         /* the integer version */      if (width >= snprintf(buf, sizeof(buf), "%ld%c", (unsigned long)(num / *dp), *up))         return buf;   }      /* well shoot, this outta' fit... */   return "?";}        /*         * Do some scaling stuff.         * format 'tics' to fit 'width'. */static const char *scale_tics (TIC_t tics, const int width){#ifdef CASEUP_SCALE#define HH "%uH"#define DD "%uD"#define WW "%uW"#else#define HH "%uh"#define DD "%ud"#define WW "%uw"#endif   static char buf[TNYBUFSIZ];   unsigned long nt;    // narrow time, for speed on 32-bit   unsigned cc;         // centiseconds   unsigned nn;         // multi-purpose whatever   nt  = (tics * 100ull) / Hertz;   cc  = nt % 100;                              // centiseconds past second   nt /= 100;                                   // total seconds   nn  = nt % 60;                               // seconds past the minute   nt /= 60;                                    // total minutes   if (width >= snprintf(buf, sizeof(buf), "%lu:%02u.%02u", nt, nn, cc))      return buf;   if (width >= snprintf(buf, sizeof buf, "%lu:%02u", nt, nn))      return buf;   nn  = nt % 60;                               // minutes past the hour   nt /= 60;                                    // total hours   if (width >= snprintf(buf, sizeof buf, "%lu,%02u", nt, nn))      return buf;   nn = nt;                                     // now also hours   if (width >= snprintf(buf, sizeof buf, HH, nn))      return buf;   nn /= 24;                                    // now days   if (width >= snprintf(buf, sizeof buf, DD, nn))      return buf;   nn /= 7;                                     // now weeks   if (width >= snprintf(buf, sizeof buf, WW, nn))      return buf;      // well shoot, this outta' fit...   return "?";#undef HH#undef DD#undef WW}#include <pwd.h>static int selection_type;static uid_t selection_uid;// FIXME: this is "temporary" code we hopestatic int good_uid(const proc_t *restrict const pp){   switch(selection_type){   case 'p':      return 1;   case 0:      return 1;   case 'U':      if (pp->ruid == selection_uid) return 1;      if (pp->suid == selection_uid) return 1;      if (pp->fuid == selection_uid) return 1;      // FALLTHROUGH   case 'u':      if (pp->euid == selection_uid) return 1;      // FALLTHROUGH   default:      ;  // don't know what it is; find bugs fast   }   return 0;}// swiped from ps, and ought to be in libprocstatic const char *parse_uid(const char *restrict const str, uid_t *restrict const ret){   struct passwd *passwd_data;   char *endp;   unsigned long num;   static const char uidrange[] = "User ID out of range.";   static const char uidexist[] = "User name does not exist.";   num = strtoul(str, &endp, 0);   if(*endp != '\0'){  /* hmmm, try as login name */      passwd_data = getpwnam(str);      if(!passwd_data)    return uidexist;      num = passwd_data->pw_uid;   }   if(num > 0xfffffffeUL) return uidrange;   *ret = num;   return 0;}/*######  Library Alternatives  ##########################################*/        /*         * Handle our own memory stuff without the risk of leaving the         * user's terminal in an ugly state should things go sour. */static void *alloc_c (unsigned numb) MALLOC;static void *alloc_c (unsigned numb){   void * p;   if (!numb) ++numb;   if (!(p = calloc(1, numb)))      std_err("failed memory allocate");   return p;}static void *alloc_r (void *q, unsigned numb) MALLOC;static void *alloc_r (void *q, unsigned numb){   void *p;   if (!numb) ++numb;   if (!(p = realloc(q, numb)))      std_err("failed memory allocate");   return p;}        /*         * This guy's modeled on libproc's 'five_cpu_numbers' function except         * 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 CPU_t *cpus_refresh (CPU_t *cpus){   static FILE *fp = NULL;   int i;   int num;   // enough for a /proc/stat CPU line (not the intr line)   char buf[SMLBUFSIZ];   /* by opening this file once, we'll avoid the hit on minor page faults      (sorry Linux, but you'll have to close it for us) */   if (!fp) {      if (!(fp = fopen("/proc/stat", "r")))         std_err(fmtmk("Failed /proc/stat open: %s", strerror(errno)));      /* 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(CPU_t));   }   rewind(fp);   fflush(fp);   // first value the last slot with the cpu summary line   if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");   cpus[Cpu_tot].x = 0;  // FIXME: can't tell by kernel version number   cpus[Cpu_tot].y = 0;  // FIXME: can't tell by kernel version number   cpus[Cpu_tot].z = 0;  // FIXME: can't tell by kernel version number   num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",      &cpus[Cpu_tot].u,      &cpus[Cpu_tot].n,      &cpus[Cpu_tot].s,      &cpus[Cpu_tot].i,      &cpus[Cpu_tot].w,      &cpus[Cpu_tot].x,      &cpus[Cpu_tot].y,      &cpus[Cpu_tot].z   );   if (num < 4)         std_err("failed /proc/stat read");   // and just in case we're 2.2.xx compiled without SMP support...   if (Cpu_tot == 1) {      cpus[1].id = 0;      memcpy(cpus, &cpus[1], sizeof(CPU_t));   }   // now value each separate cpu's tics   for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) {      if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");      cpus[i].x = 0;  // FIXME: can't tell by kernel version number      cpus[i].y = 0;  // FIXME: can't tell by kernel version number      cpus[i].z = 0;  // FIXME: can't tell by kernel version number      num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",         &cpus[i].id,         &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z      );      if (num < 4)            std_err("failed /proc/stat read");   }   return cpus;}        /*         * Refresh procs *Helper* function to eliminate yet one more need         * 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 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 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   TIC_t tics;   if (unlikely(!this)) {      static struct timeval oldtimev;      struct timeval timev;      struct timezone timez;      HST_t *hist_tmp;      float et;      gettimeofday(&timev, &timez);      et = (timev.tv_sec - oldtimev.tv_sec)         + (float)(timev.tv_usec - oldtimev.tv_usec) / 1000000.0;      oldtimev.tv_sec = timev.tv_sec;      oldtimev.tv_usec = timev.tv_usec;      // if in Solaris mode, adjust our scaling for all cpus      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;      // reuse memory each time around      hist_tmp = hist_sav;      hist_sav = hist_new;      hist_new = hist_tmp;      // 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;   }   switch (this->state) {      case 'R':         Frame_running++;         break;      case 'S':      case 'D':         Frame_sleepin++;         break;      case 'T':         Frame_stopped++;         break;      case 'Z':         Frame_zombied++;         break;   }   if (unlikely(Frame_maxtask+1 >= hist_siz)) {      hist_siz = hist_siz * 5 / 4 + 100;  // grow by at least 25%      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      calcs and saves that go unused, like the old top! */   hist_new[Frame_maxtask].pid  = this->tid;   hist_new[Frame_maxtask].tics = tics = (this->utime + this->stime);#if 0{  int i;   int lo = 0;   int hi = maxt_sav - 1;   // find matching entry from previous frame and make ticks elapsed   while (lo <= hi) {      i = (lo + hi) / 2;      if (this->tid < hist_sav[i].pid)         hi = i - 1;      else if (likely(this->tid > hist_sav[i].pid))         lo = i + 1;      else {         tics -= hist_sav[i].tics;         break;      }   }}#else{   HST_t tmp;   const HST_t *ptr;   tmp.pid = this->tid;   ptr = bsearch(&tmp, hist_sav, maxt_sav, sizeof tmp, sort_HST_t);   if(ptr) tics -= ptr->tics;}#endif   // we're just saving elapsed tics, to be converted into %cpu if   // this task wins it's displayable screen row lottery... */   this->pcpu = tics;// if (Frames_maxcmdln) { }   // shout this to the world with the final call (or us the next time in)   Frame_maxtask++;}        /*         * This guy's modeled on libproc's 'readproctab' function except         * we reuse and extend any prior proc_t's.  He's been customized         * for our specific needs and to avoid the use of <stdarg.h> */static proc_t **procs_refresh (proc_t **table, int flags){#define PTRsz  sizeof(proc_t *)#define ENTsz  sizeof(proc_t)   static unsigned savmax = 0;          // first time, Bypass: (i)   proc_t *ptsk = (proc_t *)-1;         // first time, Force: (ii)   unsigned curmax = 0;                 // every time  (jeeze)   PROCTAB* PT;   static int show_threads_was_enabled = 0; // optimization   prochlp(NULL);                       // prep for a new frame   if (Monpidsidx)      PT = openproc(flags, Monpids);   else      PT = openproc(flags);   // i) Allocated Chunks:  *Existing* table;  refresh + reuse   if (!(CHKw(Curwin, Show_THREADS))) {      while (curmax < savmax) {         if (table[curmax]->cmdline) {            unsigned idx;            // Skip if Show_THREADS was never enabled            if (show_threads_was_enabled) {               for (idx = curmax + 1; idx < savmax; idx++) {                  if (table[idx]->cmdline == table[curmax]->cmdline)                     table[idx]->cmdline = NULL;               }            }            free(*table[curmax]->cmdline);            table[curmax]->cmdline = NULL;         }         if (unlikely(!(ptsk = readproc(PT, table[curmax])))) break;         prochlp(ptsk);                    // tally & complete this proc_t         ++curmax;      }   }   else {                          // show each thread in a process separately      while (curmax < savmax) {         proc_t *ttsk;         if (unlikely(!(ptsk = readproc(PT, NULL)))) break;         show_threads_was_enabled = 1;         while (curmax < savmax) {            unsigned idx;            if (table[curmax]->cmdline) {               // threads share the same cmdline storage.  'table' is               // qsort()ed, so must look through the rest of the table.               for (idx = curmax + 1; idx < savmax; idx++) {                  if (table[idx]->cmdline == table[curmax]->cmdline)                     table[idx]->cmdline = NULL;               }               free(*table[curmax]->cmdline);  // only free once

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -