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

📄 readproc.c

📁 Linux下进程监控相关源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
proc_t* readproc(PROCTAB* PT, proc_t* rbuf) {    static struct direct *ent;		/* dirent handle */    static struct stat sb;		/* stat buffer */    static char path[32], sbuf[512];	/* bufs for stat,statm */    int allocated = 0, matched = 0;	/* flags */    proc_t *p = NULL;    /* loop until a proc matching restrictions is found or no more processes */    /* I know this could be a while loop -- this way is easier to indent ;-) */next_proc:				/* get next PID for consideration *//*printf("PT->flags is 0x%08x\n", PT->flags);*/#define flags (PT->flags)    if (Do(PID)) {	if (!*PT->pids)			/* set to next item in pids */	    return NULL;	sprintf(path, "/proc/%d", *(PT->pids)++);	matched = 1;    } else {					/* get next numeric /proc ent */	while ((ent = readdir(PT->procfs)) &&	       (*ent->d_name < '0' || *ent->d_name > '9'))	    ;	if (!ent || !ent->d_name)	    return NULL;	sprintf(path, "/proc/%s", ent->d_name);    }    if (stat(path, &sb) == -1)		/* no such dirent (anymore) */	goto next_proc;    if (Do(UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))	goto next_proc;			/* not one of the requested uids */    if (!allocated) {				 /* assign mem for return buf */	p = rbuf ? rbuf : xcalloc(p, sizeof *p); /* passed buf or alloced mem */	allocated = 1;				 /* remember space is set up */    }    p->euid = sb.st_uid;			/* need a way to get real uid */    if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1)	goto next_proc;			/* error reading /proc/#/stat */    stat2proc(sbuf, p);				/* parse /proc/#/stat */    if (!matched && Do(TTY) && !XinL(dev_t, p->tty, PT->ttys))	goto next_proc;			/* not one of the requested ttys */    if (!matched && Do(ANYTTY) && p->tty == -1)	goto next_proc;			/* no controlling terminal */    if (!matched && Do(STAT) && !strchr(PT->stats,p->state))	goto next_proc;			/* not one of the requested states */    if (Do(FILLMEM)) {				/* read, parse /proc/#/statm */	if ((file2str(path, "statm", sbuf, sizeof sbuf)) != -1 )	    statm2proc(sbuf, p);		/* ignore statm errors here */    }						/* statm fields just zero */    if (Do(FILLSTATUS)) {         /* read, parse /proc/#/status */       if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){           status2proc(sbuf, p, 0 /*FIXME*/);       }    }    /* some number->text resolving which is time consuming */    if (Do(FILLUSR)){	strncpy(p->euser,   user_from_uid(p->euid), sizeof p->euser);        strncpy(p->egroup, group_from_gid(p->egid), sizeof p->egroup);        if(Do(FILLSTATUS)) {            strncpy(p->ruser,   user_from_uid(p->ruid), sizeof p->ruser);            strncpy(p->rgroup, group_from_gid(p->rgid), sizeof p->rgroup);            strncpy(p->suser,   user_from_uid(p->suid), sizeof p->suser);            strncpy(p->sgroup, group_from_gid(p->sgid), sizeof p->sgroup);            strncpy(p->fuser,   user_from_uid(p->fuid), sizeof p->fuser);            strncpy(p->fgroup, group_from_gid(p->fgid), sizeof p->fgroup);        }    }    if (Do(FILLCMD))				/* read+parse /proc/#/cmdline */	p->cmdline = file2strvec(path, "cmdline");    if (Do(FILLENV))				/* read+parse /proc/#/environ */	p->environ = file2strvec(path, "environ");        if (p->state == 'Z')			/* fixup cmd for zombies */	strncat(p->cmd," <defunct>", sizeof p->cmd);    return p;}#undef flags/* ps_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. * Unfortunately, the reverse filtering option in which any PID *except* the * ones listed is pursued. */proc_t* ps_readproc(PROCTAB* PT, proc_t* rbuf) {    static struct direct *ent;		/* dirent handle */    static struct stat sb;		/* stat buffer */    static char path[32], sbuf[512];	/* bufs for stat,statm */    int allocated = 0 /* , matched = 0 */ ;	/* flags */    proc_t *p = NULL;    /* loop until a proc matching restrictions is found or no more processes */    /* I know this could be a while loop -- this way is easier to indent ;-) */next_proc:				/* get next PID for consideration *//*printf("PT->flags is 0x%08x\n", PT->flags);*/#define flags (PT->flags)	while ((ent = readdir(PT->procfs)) &&	       (*ent->d_name < '0' || *ent->d_name > '9'))	    ;	if (!ent || !ent->d_name)	    return NULL;	sprintf(path, "/proc/%s", ent->d_name);    if (stat(path, &sb) == -1)		/* no such dirent (anymore) */	goto next_proc;    if (!allocated) {				 /* assign mem for return buf */	p = rbuf ? rbuf : xcalloc(p, sizeof *p); /* passed buf or alloced mem */	allocated = 1;				 /* remember space is set up */    }    p->euid = sb.st_uid;			/* need a way to get real uid */    if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1)	goto next_proc;			/* error reading /proc/#/stat */    stat2proc(sbuf, p);				/* parse /proc/#/stat *//*    if (Do(FILLMEM)) {*/				/* read, parse /proc/#/statm */	if ((file2str(path, "statm", sbuf, sizeof sbuf)) != -1 )	    statm2proc(sbuf, p);		/* ignore statm errors here *//*    }			*/			/* statm fields just zero */  /*  if (Do(FILLSTATUS)) { */        /* read, parse /proc/#/status */       if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){           status2proc(sbuf, p, 0 /*FIXME*/);       }/*    }*/    /* some number->text resolving which is time consuming */ /*   if (Do(FILLUSR)){ */	strncpy(p->euser,   user_from_uid(p->euid), sizeof p->euser);        strncpy(p->egroup, group_from_gid(p->egid), sizeof p->egroup);/*        if(Do(FILLSTATUS)) { */            strncpy(p->ruser,   user_from_uid(p->ruid), sizeof p->ruser);            strncpy(p->rgroup, group_from_gid(p->rgid), sizeof p->rgroup);            strncpy(p->suser,   user_from_uid(p->suid), sizeof p->suser);            strncpy(p->sgroup, group_from_gid(p->sgid), sizeof p->sgroup);            strncpy(p->fuser,   user_from_uid(p->fuid), sizeof p->fuser);            strncpy(p->fgroup, group_from_gid(p->fgid), sizeof p->fgroup);/*        }*//*    }*//*    if (Do(FILLCMD))	*/			/* read+parse /proc/#/cmdline */	p->cmdline = file2strvec(path, "cmdline");/*    if (Do(FILLENV))	*/			/* read+parse /proc/#/environ */	p->environ = file2strvec(path, "environ");        if (p->state == 'Z')			/* fixup cmd for zombies */	strncat(p->cmd," <defunct>", sizeof p->cmd);    return p;}#undef flagsvoid look_up_our_self(proc_t *p) {    static char path[32], sbuf[512];	/* bufs for stat,statm */    sprintf(path, "/proc/%d", getpid());    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*/);}/* Convenient wrapper around openproc and readproc to slurp in the whole process * tree subset satisfying the constraints of flags and the optional PID list. * Free allocated memory with freeproctree().  The tree structure is a classic * left-list children + right-list siblings.  The algorithm is a two-pass of the * process table.  Since most process trees will have children with strictly * increasing PIDs, most of the structure will be picked up in the first pass. * The second loop then cleans up any nodes which turn out to have preceeded * their parent in /proc order. *//* Traverse tree 't' breadth-first looking for a process with pid p */proc_t* LookupPID(proc_t* t, pid_t p) {    proc_t* tmp = NULL;    if (!t)	return NULL;    if (t->pid == p)				/* look here/terminate recursion */	return t;    if ((tmp = LookupPID(t->l, p)))		/* recurse over children */	return tmp;    for (; t; t=t->r)				/* recurse over siblings */	if ((tmp = LookupPID(tmp, p)))	    return tmp;    return NULL;}proc_t* readproctree(int flags, ...) {    static proc_t tree;    PROCTAB* PT = NULL;    proc_t *node, *tmp=NULL, *tmp2=NULL;    va_list ap;        /* pass through apropriate arguments to openproc */    va_start(ap, flags);    if (Do(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 (Do(PID) || Do(TTY) || Do(STAT))	PT = openproc(flags, va_arg(ap, void*));    else	PT = openproc(flags);    va_end(ap);    /* first pass: build tree, putting orphans on the first level */    tree.l = tree.r = NULL;    while ((node = readproc(PT,0)))	if ((tmp = LookupPID(&tree, node->ppid))) {	    node->r = tmp->l->r;	/* node --> left list of parent */	    tmp->l->r = node;	} else {	    node->r = tree.r;		/* node --> right list of 'tree' */	    tree.r = node;	}    /* second pass: scan tree for PPIDs of level-1 nodes moving links as necessary */    for (node = &tree; node; node = node->r)	if ((tmp = LookupPID(&tree, node->r->ppid))) {	    tmp2 = node->r;			/* unlink from right list of 'tree' */	    node->r = node->r->r;	    tmp2->r = tmp->l->r;		/* insert as child of found node */	    tmp->l->r = node;	}    closeproc(PT);    return &tree;}/* 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 freeproctab().  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 (Do(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 (Do(PID) || Do(TTY) || Do(STAT))	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(PT, NULL);		  /* final null to terminate */    } while (tab[n++]);				  /* stop when NULL reached */    closeproc(PT);    return tab;}/* deallocate a table of pointers to proc structures */void freeproctab(proc_t** tab) {    proc_t** p;    for(p = tab; *p; p++)	freeproc(*p);    free(tab);}

⌨️ 快捷键说明

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