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

📄 readproc.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if(unlikely(unlikely(!ent) || unlikely(!ent->d_name))) return 0;    if(likely( likely(*ent->d_name > '0') && likely(*ent->d_name <= '9') )) break;  }  p->tgid = strtoul(ent->d_name, NULL, 10);  p->tid = p->tgid;  memcpy(path, "/proc/", 6);  strcpy(path+6, ent->d_name);  // trust /proc to not contain evil top-level entries  return 1;}//////////////////////////////////////////////////////////////////////////////////// This finds tasks in /proc/*/task/ in the traditional way.// Return non-zero on success.static int simple_nexttid(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t, char *restrict const path) {  static struct direct *ent;		/* dirent handle */  if(PT->taskdir_user != p->tgid){    if(PT->taskdir){      closedir(PT->taskdir);    }    // use "path" as some tmp space    snprintf(path, PROCPATHLEN, "/proc/%d/task", p->tgid);    PT->taskdir = opendir(path);    if(!PT->taskdir) return 0;    PT->taskdir_user = p->tgid;  }  for (;;) {    ent = readdir(PT->taskdir);    if(unlikely(unlikely(!ent) || unlikely(!ent->d_name))) return 0;    if(likely( likely(*ent->d_name > '0') && likely(*ent->d_name <= '9') )) break;  }  t->tid = strtoul(ent->d_name, NULL, 10);  t->tgid = p->tgid;  t->ppid = p->ppid;  // cover for kernel behavior? we want both actually...?  snprintf(path, PROCPATHLEN, "/proc/%d/task/%s", p->tgid, ent->d_name);  return 1;}//////////////////////////////////////////////////////////////////////////////////// This "finds" processes in a list that was given to openproc().// Return non-zero on success. (tgid was handy)static int listed_nextpid(PROCTAB *restrict const PT, proc_t *restrict const p) {  char *restrict const path = PT->path;  pid_t tgid = *(PT->pids)++;  if(likely( tgid )){    snprintf(path, PROCPATHLEN, "/proc/%d", tgid);    p->tgid = tgid;    p->tid = tgid;  // they match for leaders  }  return tgid;}///////////////////////////////////////////////////////////////////////////////////* readproc: return a pointer to a proc_t filled with requested info about the * next process available matching the restriction set.  If no more such * processes are available, return a null pointer (boolean false).  Use the * passed buffer instead of allocating space if it is non-NULL.  *//* This is optimized so that if a PID list is given, only those files are * searched for in /proc.  If other lists are given in addition to the PID list, * the same logic can follow through as for the no-PID list case.  This is * fairly complex, but it does try to not to do any unnecessary work. */proc_t* readproc(PROCTAB *restrict const PT, proc_t *restrict p) {  proc_t *ret;  proc_t *saved_p;  PT->did_fake=0;//  if (PT->taskdir) {//    closedir(PT->taskdir);//    PT->taskdir = NULL;//    PT->taskdir_user = -1;//  }  saved_p = p;  if(!p) p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */  for(;;){    // fills in the path, plus p->tid and p->tgid    if (unlikely(! PT->finder(PT,p) )) goto out;    // go read the process data    ret = PT->reader(PT,p);    if(ret) return ret;  }out:  if(!saved_p) free(p);  // FIXME: maybe set tid to -1 here, for "-" in display?  return NULL;}//////////////////////////////////////////////////////////////////////////////////// readtask: return a pointer to a proc_t filled with requested info about the// next task available.  If no more such tasks are available, return a null// pointer (boolean false).  Use the passed buffer instead of allocating// space if it is non-NULL.proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict t) {  static char path[PROCPATHLEN];       // must hold /proc/2000222000/task/2000222000/cmdline  proc_t *ret;  proc_t *saved_t;  saved_t = t;  if(!t) t = xcalloc(t, sizeof *t); /* passed buf or alloced mem */  // 1. got to fake a thread for old kernels  // 2. for single-threaded processes, this is faster (but must patch up stuff that differs!)  if(task_dir_missing || p->nlwp < 2){    if(PT->did_fake) goto out;    PT->did_fake=1;    memcpy(t,p,sizeof(proc_t));    // use the per-task pending, not per-tgid pending#ifdef SIGNAL_STRING	memcpy(&t->signal, &t->_sigpnd, sizeof t->signal);#else	t->signal = t->_sigpnd;#endif    return t;  }  for(;;){    // fills in the path, plus t->tid and t->tgid    if (unlikely(! PT->taskfinder(PT,p,t,path) )) goto out;  // simple_nexttid    // go read the task data    ret = PT->taskreader(PT,p,t,path);          // simple_readtask    if(ret) return ret;  }out:  if(!saved_t) free(t);  return NULL;}//////////////////////////////////////////////////////////////////////////////////// initiate a process table scanPROCTAB* openproc(int flags, ...) {    va_list ap;    struct stat sbuf;    static int did_stat;    PROCTAB* PT = xmalloc(sizeof(PROCTAB));    if(!did_stat){      task_dir_missing = stat("/proc/self/task", &sbuf);      did_stat = 1;    }    PT->taskdir = NULL;    PT->taskdir_user = -1;    PT->taskfinder = simple_nexttid;    PT->taskreader = simple_readtask;    PT->reader = simple_readproc;    if (flags & PROC_PID){      PT->procfs = NULL;      PT->finder = listed_nextpid;    }else{      PT->procfs = opendir("/proc");      if(!PT->procfs) return NULL;      PT->finder = simple_nextpid;    }    PT->flags = flags;    va_start(ap, flags);		/*  Init args list */    if (flags & PROC_PID)    	PT->pids = va_arg(ap, pid_t*);    else if (flags & PROC_UID) {    	PT->uids = va_arg(ap, uid_t*);	PT->nuid = va_arg(ap, int);    }    va_end(ap);				/*  Clean up args list */    return PT;}// terminate a process table scanvoid closeproc(PROCTAB* PT) {    if (PT){        if (PT->procfs) closedir(PT->procfs);        if (PT->taskdir) closedir(PT->taskdir);        memset(PT,'#',sizeof(PROCTAB));        free(PT);    }}// deallocate the space allocated by readproc if the passed rbuf was NULLvoid freeproc(proc_t* p) {    if (!p)	/* in case p is NULL */	return;    /* ptrs are after strings to avoid copying memory when building them. */    /* so free is called on the address of the address of strvec[0]. */    if (p->cmdline)	free((void*)*p->cmdline);    if (p->environ)	free((void*)*p->environ);    free(p);}//////////////////////////////////////////////////////////////////////////////////void look_up_our_self(proc_t *p) {    char sbuf[1024];    if(file2str("/proc/self", "stat", sbuf, sizeof sbuf) == -1){        fprintf(stderr, "Error, do this: mount -t proc none /proc\n");        _exit(47);    }    stat2proc(sbuf, p);    // parse /proc/self/stat}HIDDEN_ALIAS(readproc);HIDDEN_ALIAS(readtask);/* Convenient wrapper around openproc and readproc to slurp in the whole process * table subset satisfying the constraints of flags and the optional PID list. * Free allocated memory with exit().  Access via tab[N]->member.  The pointer * list is NULL terminated. */proc_t** readproctab(int flags, ...) {    PROCTAB* PT = NULL;    proc_t** tab = NULL;    int n = 0;    va_list ap;    va_start(ap, flags);		/* pass through args to openproc */    if (flags & PROC_UID) {	/* temporary variables to ensure that va_arg() instances	 * are called in the right order	 */	uid_t* u;	int i;	u = va_arg(ap, uid_t*);	i = va_arg(ap, int);	PT = openproc(flags, u, i);    }    else if (flags & PROC_PID)	PT = openproc(flags, va_arg(ap, void*)); /* assume ptr sizes same */    else	PT = openproc(flags);    va_end(ap);    do {					/* read table: */	tab = xrealloc(tab, (n+1)*sizeof(proc_t*));/* realloc as we go, using */	tab[n] = readproc_direct(PT, NULL);     /* final null to terminate */    } while (tab[n++]);				  /* stop when NULL reached */    closeproc(PT);    return tab;}// Try again, this time with threads and selection.proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT) {    proc_t** ptab = NULL;    unsigned n_proc_alloc = 0;    unsigned n_proc = 0;    proc_t** ttab = NULL;    unsigned n_task_alloc = 0;    unsigned n_task = 0;    proc_t*  data = NULL;    unsigned n_alloc = 0;    unsigned long n_used = 0;    proc_data_t *pd;    for(;;){        proc_t *tmp;        if(n_alloc == n_used){          //proc_t *old = data;          n_alloc = n_alloc*5/4+30;  // grow by over 25%          data = realloc(data,sizeof(proc_t)*n_alloc);          //if(!data) return NULL;        }        if(n_proc_alloc == n_proc){          //proc_t **old = ptab;          n_proc_alloc = n_proc_alloc*5/4+30;  // grow by over 25%          ptab = realloc(ptab,sizeof(proc_t*)*n_proc_alloc);          //if(!ptab) return NULL;        }        tmp = readproc_direct(PT, data+n_used);        if(!tmp) break;        if(!want_proc(tmp)) continue;        ptab[n_proc++] = (proc_t*)(n_used++);        if(!(  PT->flags & PROC_LOOSE_TASKS  )) continue;        for(;;){          proc_t *t;          if(n_alloc == n_used){            proc_t *old = data;            n_alloc = n_alloc*5/4+30;  // grow by over 25%            data = realloc(data,sizeof(proc_t)*n_alloc);	    // have to move tmp too	    tmp = data+(tmp-old);            //if(!data) return NULL;          }          if(n_task_alloc == n_task){            //proc_t **old = ttab;            n_task_alloc = n_task_alloc*5/4+1;  // grow by over 25%            ttab = realloc(ttab,sizeof(proc_t*)*n_task_alloc);            //if(!ttab) return NULL;          }          t = readtask_direct(PT, tmp, data+n_used);          if(!t) break;          if(!want_task(t)) continue;          ttab[n_task++] = (proc_t*)(n_used++);        }    }    pd = malloc(sizeof(proc_data_t));    pd->proc = ptab;    pd->task = ttab;    pd->nproc = n_proc;    pd->ntask = n_task;    if(PT->flags & PROC_LOOSE_TASKS){      pd->tab = ttab;      pd->n   = n_task;    }else{      pd->tab = ptab;      pd->n   = n_proc;    }    // change array indexes to pointers    while(n_proc--) ptab[n_proc] = data+(long)(ptab[n_proc]);    while(n_task--) ttab[n_task] = data+(long)(ttab[n_task]);    return pd;}/* * get_proc_stats - lookup a single tasks information and fill out a proc_t * * On failure, returns NULL.  On success, returns 'p' and 'p' is a valid * and filled out proc_t structure. */proc_t * get_proc_stats(pid_t pid, proc_t *p) {	static char path[PATH_MAX], sbuf[1024];	struct stat statbuf;	sprintf(path, "/proc/%d", pid);	if (stat(path, &statbuf)) {		perror("stat");		return NULL;	}	if (file2str(path, "stat", sbuf, sizeof sbuf) >= 0)		stat2proc(sbuf, p);	/* parse /proc/#/stat */	if (file2str(path, "statm", sbuf, sizeof sbuf) >= 0)		statm2proc(sbuf, p);	/* ignore statm errors here */	if (file2str(path, "status", sbuf, sizeof sbuf) >= 0)		status2proc(sbuf, p, 0 /*FIXME*/);	return p;}

⌨️ 快捷键说明

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