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

📄 readproc.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * New Interface to Process Table -- PROCTAB Stream (a la Directory streams) * Copyright (C) 1996 Charles L. Blake. * Copyright (C) 1998 Michael K. Johnson * Copyright 1998-2003 Albert Cahalan * May be distributed under the conditions of the * GNU Library General Public License; a copy is in COPYING */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "version.h"#include "readproc.h"#include "alloc.h"#include "pwcache.h"#include "devname.h"#include "procps.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <stdarg.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <fcntl.h>#include <sys/dir.h>#include <sys/types.h>#include <sys/stat.h>// sometimes it's easier to do this manually, w/o gcc helping#ifdef PROFextern void __cyg_profile_func_enter(void*,void*);#define ENTER(x) __cyg_profile_func_enter((void*)x,(void*)x)#define LEAVE(x) __cyg_profile_func_exit((void*)x,(void*)x)#else#define ENTER(x)#define LEAVE(x)#endif// convert hex string to unsigned long longstatic unsigned long long unhex(const char *restrict cp){    unsigned long long ull = 0;    for(;;){        char c = *cp++;        if(unlikely(c<0x30)) break;        ull = (ull<<4) | (c - (c>0x57) ? 0x57 : 0x30) ;    }    return ull;}static int task_dir_missing;///////////////////////////////////////////////////////////////////////////typedef struct status_table_struct {    unsigned char name[7];        // /proc/*/status field name    unsigned char len;            // name length#ifdef LABEL_OFFSET    long offset;                  // jump address offset#else    void *addr;#endif} status_table_struct;#ifdef LABEL_OFFSET#define F(x) {#x, sizeof(#x)-1, (long)(&&case_##x-&&base)},#else#define F(x) {#x, sizeof(#x)-1, &&case_##x},#endif#define NUL  {"", 0, 0},// Derived from:// gperf -7 --language=ANSI-C --key-positions=1,3,4 -C -n -c sml.gperf//// Suggested method:// Grep this file for "case_", then strip those down to the name.// (leave the colon and newline) So "Pid:\n" and "Threads:\n"// would be lines in the file. (no quote, no escape, etc.)//// Watch out for name size in the status_table_struct (grrr, expanding)// and the number of entries (we mask with 63 for now). The table// must be padded out to 64 entries, maybe 128 in the future.static void status2proc(char *S, proc_t *restrict P, int is_proc){    long Threads = 0;    long Tgid = 0;    long Pid = 0;  static const unsigned char asso[] =    {      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61, 61, 15, 61,      61, 61, 61, 61, 61, 61, 30,  3,  5,  5,      61,  5, 61,  8, 61, 61,  3, 61, 10, 61,       6, 61, 13,  0, 30, 25,  0, 61, 61, 61,      61, 61, 61, 61, 61, 61, 61,  3, 61, 13,       0,  0, 61, 30, 61, 25, 61, 61, 61,  0,      61, 61, 61, 61,  5, 61,  0, 61, 61, 61,       0, 61, 61, 61, 61, 61, 61, 61    };    static const status_table_struct table[] = {      F(VmStk)      NUL NUL      F(State)      NUL      F(VmExe)      F(ShdPnd)      NUL      F(VmData)      NUL      F(Name)      NUL NUL      F(VmRSS)      NUL NUL      F(VmLck)      NUL NUL NUL      F(Gid)      F(Pid)      NUL NUL NUL      F(VmSize)      NUL NUL      F(VmLib)      NUL NUL      F(PPid)      NUL      F(SigCgt)      NUL      F(Threads)      F(SigPnd)      NUL      F(SigIgn)      NUL      F(Uid)      NUL NUL NUL NUL NUL NUL NUL NUL NUL      NUL NUL NUL NUL NUL      F(Tgid)      NUL NUL NUL NUL      F(SigBlk)      NUL NUL NUL    };#undef F#undef NULENTER(0x220);    P->vm_size = 0;    P->vm_lock = 0;    P->vm_rss  = 0;    P->vm_data = 0;    P->vm_stack= 0;    P->vm_exe  = 0;    P->vm_lib  = 0;    P->nlwp    = 0;    P->signal[0] = '\0';  // so we can detect it as missing for very old kernels    goto base;    for(;;){        char *colon;        status_table_struct entry;        // advance to next line        S = strchr(S, '\n');        if(unlikely(!S)) break;  // if no newline        S++;        // examine a field name (hash and compare)    base:        if(unlikely(!*S)) break;        entry = table[63 & (asso[S[3]] + asso[S[2]] + asso[S[0]])];        colon = strchr(S, ':');        if(unlikely(!colon)) break;        if(unlikely(colon[1]!='\t')) break;        if(unlikely(colon-S != entry.len)) continue;        if(unlikely(memcmp(entry.name,S,colon-S))) continue;        S = colon+2; // past the '\t'#ifdef LABEL_OFFSET        goto *(&&base + entry.offset);#else        goto *entry.addr;#endif    case_Name:{        unsigned u = 0;        while(u < sizeof P->cmd - 1u){            int c = *S++;            if(unlikely(c=='\n')) break;            if(unlikely(c=='\0')) break; // should never happen            if(unlikely(c=='\\')){                c = *S++;                if(c=='\n') break; // should never happen                if(!c)      break; // should never happen                if(c=='n') c='\n'; // else we assume it is '\\'            }            P->cmd[u++] = c;        }        P->cmd[u] = '\0';        S--;   // put back the '\n' or '\0'        continue;    }#ifdef SIGNAL_STRING    case_ShdPnd:        memcpy(P->signal, S, 16);        P->signal[16] = '\0';        continue;    case_SigBlk:        memcpy(P->blocked, S, 16);        P->blocked[16] = '\0';        continue;    case_SigCgt:        memcpy(P->sigcatch, S, 16);        P->sigcatch[16] = '\0';        continue;    case_SigIgn:        memcpy(P->sigignore, S, 16);        P->sigignore[16] = '\0';        continue;    case_SigPnd:        memcpy(P->_sigpnd, S, 16);        P->_sigpnd[16] = '\0';        continue;#else    case_ShdPnd:        P->signal = unhex(S);        continue;    case_SigBlk:        P->blocked = unhex(S);        continue;    case_SigCgt:        P->sigcatch = unhex(S);        continue;    case_SigIgn:        P->sigignore = unhex(S);        continue;    case_SigPnd:        P->_sigpnd = unhex(S);        continue;#endif    case_State:        P->state = *S;        continue;    case_Tgid:        Tgid = strtol(S,&S,10);        continue;    case_Pid:        Pid = strtol(S,&S,10);        continue;    case_PPid:        P->ppid = strtol(S,&S,10);        continue;    case_Threads:        Threads = strtol(S,&S,10);        continue;    case_Uid:        P->ruid = strtol(S,&S,10);        P->euid = strtol(S,&S,10);        P->suid = strtol(S,&S,10);        P->fuid = strtol(S,&S,10);        continue;    case_Gid:        P->rgid = strtol(S,&S,10);        P->egid = strtol(S,&S,10);        P->sgid = strtol(S,&S,10);        P->fgid = strtol(S,&S,10);        continue;    case_VmData:        P->vm_data = strtol(S,&S,10);        continue;    case_VmExe:        P->vm_exe = strtol(S,&S,10);        continue;    case_VmLck:        P->vm_lock = strtol(S,&S,10);        continue;    case_VmLib:        P->vm_lib = strtol(S,&S,10);        continue;    case_VmRSS:        P->vm_rss = strtol(S,&S,10);        continue;    case_VmSize:        P->vm_size = strtol(S,&S,10);        continue;    case_VmStk:        P->vm_stack = strtol(S,&S,10);        continue;    }#if 0    // recent kernels supply per-tgid pending signals    if(is_proc && *ShdPnd){	memcpy(P->signal, ShdPnd, 16);	P->signal[16] = '\0';    }#endif    // recent kernels supply per-tgid pending signals#ifdef SIGNAL_STRING    if(!is_proc || !P->signal[0]){	memcpy(P->signal, P->_sigpnd, 16);	P->signal[16] = '\0';    }#else    if(!is_proc || !have_process_pending){	P->signal = P->_sigpnd;    }#endif    // Linux 2.4.13-pre1 to max 2.4.xx have a useless "Tgid"    // that is not initialized for built-in kernel tasks.    // Only 2.6.0 and above have "Threads" (nlwp) info.    if(Threads){       P->nlwp = Threads;       P->tgid = Tgid;     // the POSIX PID value       P->tid  = Pid;      // the thread ID    }else{       P->nlwp = 1;       P->tgid = Pid;       P->tid  = Pid;    }LEAVE(0x220);}///////////////////////////////////////////////////////////////////////// Reads /proc/*/stat files, being careful not to trip over processes with// names like ":-) 1 2 3 4 5 6".static void stat2proc(const char* S, proc_t *restrict P) {    unsigned num;    char* tmp;ENTER(0x160);    /* fill in default values for older kernels */    P->processor = 0;    P->rtprio = -1;    P->sched = -1;    P->nlwp = 0;    S = strchr(S, '(') + 1;    tmp = strrchr(S, ')');    num = tmp - S;

⌨️ 快捷键说明

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