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

📄 readproc.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if(unlikely(num >= sizeof P->cmd)) num = sizeof P->cmd - 1;    memcpy(P->cmd, S, num);    P->cmd[num] = '\0';    S = tmp + 2;                 // skip ") "    num = sscanf(S,       "%c "       "%d %d %d %d %d "       "%lu %lu %lu %lu %lu "       "%Lu %Lu %Lu %Lu "  /* utime stime cutime cstime */       "%ld %ld "       "%d "       "%ld "       "%Lu "  /* start_time */       "%lu "       "%ld "       "%lu %"KLF"u %"KLF"u %"KLF"u %"KLF"u %"KLF"u "       "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */       "%"KLF"u %*lu %*lu "       "%d %d "       "%lu %lu",       &P->state,       &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid,       &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt,       &P->utime, &P->stime, &P->cutime, &P->cstime,       &P->priority, &P->nice,       &P->nlwp,       &P->alarm,       &P->start_time,       &P->vsize,       &P->rss,       &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, &P->kstk_eip,/*     P->signal, P->blocked, P->sigignore, P->sigcatch,   */ /* can't use */       &P->wchan, /* &P->nswap, &P->cnswap, */  /* nswap and cnswap dead for 2.4.xx and up *//* -- Linux 2.0.35 ends here -- */       &P->exit_signal, &P->processor,  /* 2.2.1 ends with "exit_signal" *//* -- Linux 2.2.8 to 2.5.17 end here -- */       &P->rtprio, &P->sched  /* both added to 2.5.18 */    );    if(!P->nlwp){      P->nlwp = 1;    }LEAVE(0x160);}/////////////////////////////////////////////////////////////////////////static void statm2proc(const char* s, proc_t *restrict P) {    int num;    num = sscanf(s, "%ld %ld %ld %ld %ld %ld %ld",	   &P->size, &P->resident, &P->share,	   &P->trs, &P->lrs, &P->drs, &P->dt);/*    fprintf(stderr, "statm2proc converted %d fields.\n",num); */}static int file2str(const char *directory, const char *what, char *ret, int cap) {    static char filename[80];    int fd, num_read;    sprintf(filename, "%s/%s", directory, what);    fd = open(filename, O_RDONLY, 0);    if(unlikely(fd==-1)) return -1;    num_read = read(fd, ret, cap - 1);    close(fd);    if(unlikely(num_read<=0)) return -1;    ret[num_read] = '\0';    return num_read;}static char** file2strvec(const char* directory, const char* what) {    char buf[2048];	/* read buf bytes at a time */    char *p, *rbuf = 0, *endbuf, **q, **ret;    int fd, tot = 0, n, c, end_of_file = 0;    int align;    sprintf(buf, "%s/%s", directory, what);    fd = open(buf, O_RDONLY, 0);    if(fd==-1) return NULL;    /* read whole file into a memory buffer, allocating as we go */    while ((n = read(fd, buf, sizeof buf - 1)) > 0) {	if (n < (int)(sizeof buf - 1))	    end_of_file = 1;	if (n == 0 && rbuf == 0)	    return NULL;	/* process died between our open and read */	if (n < 0) {	    if (rbuf)		free(rbuf);	    return NULL;	/* read error */	}	if (end_of_file && buf[n-1])		/* last read char not null */	    buf[n++] = '\0';			/* so append null-terminator */	rbuf = xrealloc(rbuf, tot + n);		/* allocate more memory */	memcpy(rbuf + tot, buf, n);		/* copy buffer into it */	tot += n;				/* increment total byte ctr */	if (end_of_file)	    break;    }    close(fd);    if (n <= 0 && !end_of_file) {	if (rbuf) free(rbuf);	return NULL;		/* read error */    }    endbuf = rbuf + tot;			/* count space for pointers */    align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1));    for (c = 0, p = rbuf; p < endbuf; p++)    	if (!*p)	    c += sizeof(char*);    c += sizeof(char*);				/* one extra for NULL term */    rbuf = xrealloc(rbuf, tot + c + align);	/* make room for ptrs AT END */    endbuf = rbuf + tot;			/* addr just past data buf */    q = ret = (char**) (endbuf+align);		/* ==> free(*ret) to dealloc */    *q++ = p = rbuf;				/* point ptrs to the strings */    endbuf--;					/* do not traverse final NUL */    while (++p < endbuf)     	if (!*p)				/* NUL char implies that */	    *q++ = p+1;				/* next string -> next char */    *q = 0;					/* null ptr list terminator */    return ret;}// warning: interface may changeint read_cmdline(char *restrict const dst, unsigned sz, unsigned pid){    char name[32];    int fd;    unsigned n = 0;    dst[0] = '\0';    snprintf(name, sizeof name, "/proc/%u/cmdline", pid);    fd = open(name, O_RDONLY);    if(fd==-1) return 0;    for(;;){        ssize_t r = read(fd,dst+n,sz-n);        if(r==-1){            if(errno==EINTR) continue;            break;        }        n += r;        if(n==sz) break; // filled the buffer        if(r==0) break;  // EOF    }    close(fd);    if(n){        int i;        if(n==sz) n--;        dst[n] = '\0';        i=n;        while(i--){            int c = dst[i];            if(c<' ' || c>'~') dst[i]=' ';        }    }    return n;}/* These are some nice GNU C expression subscope "inline" functions. * The can be used with arbitrary types and evaluate their arguments * exactly once. *//* Test if item X of type T is present in the 0 terminated list L */#   define XinL(T, X, L) ( {			\	    T  x = (X), *l = (L);		\	    while (*l && *l != x) l++;		\	    *l == x;				\	} )/* Test if item X of type T is present in the list L of length N */#   define XinLN(T, X, L, N) ( {		\	    T x = (X), *l = (L);		\	    int i = 0, n = (N);			\	    while (i < n && l[i] != x) i++;	\	    i < n && l[i] == x;			\	} )//////////////////////////////////////////////////////////////////////////////////// This reads process info from /proc in the traditional way, for one process.// The pid (tgid? tid?) is already in p, and a path to it in path, with some// room to spare.static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict const p) {    static struct stat sb;		// stat() buffer    static char sbuf[1024];	// buffer for stat,statm    char *restrict const path = PT->path;    unsigned flags = PT->flags;    if (unlikely(stat(path, &sb) == -1))	/* no such dirent (anymore) */	goto next_proc;    if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))	goto next_proc;			/* not one of the requested uids */    p->euid = sb.st_uid;			/* need a way to get real uid */    p->egid = sb.st_gid;			/* need a way to get real gid */    if (flags & PROC_FILLSTAT) {         /* read, parse /proc/#/stat */	if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 ))	    goto next_proc;			/* error reading /proc/#/stat */	stat2proc(sbuf, p);				/* parse /proc/#/stat */    }    if (unlikely(flags & PROC_FILLMEM)) {	/* read, parse /proc/#/statm */	if (likely( file2str(path, "statm", sbuf, sizeof sbuf) != -1 ))	    statm2proc(sbuf, p);		/* ignore statm errors here */    }						/* statm fields just zero */    if (flags & PROC_FILLSTATUS) {         /* read, parse /proc/#/status */       if (likely( file2str(path, "status", sbuf, sizeof sbuf) != -1 )){           status2proc(sbuf, p, 1);       }    }    // if multithreaded, some values are crap    if(p->nlwp > 1){      p->wchan = (KLONG)~0ull;    }    /* some number->text resolving which is time consuming and kind of insane */    if (flags & PROC_FILLUSR){	memcpy(p->euser,   user_from_uid(p->euid), sizeof p->euser);        if(flags & PROC_FILLSTATUS) {            memcpy(p->ruser,   user_from_uid(p->ruid), sizeof p->ruser);            memcpy(p->suser,   user_from_uid(p->suid), sizeof p->suser);            memcpy(p->fuser,   user_from_uid(p->fuid), sizeof p->fuser);        }    }    /* some number->text resolving which is time consuming and kind of insane */    if (flags & PROC_FILLGRP){        memcpy(p->egroup, group_from_gid(p->egid), sizeof p->egroup);        if(flags & PROC_FILLSTATUS) {            memcpy(p->rgroup, group_from_gid(p->rgid), sizeof p->rgroup);            memcpy(p->sgroup, group_from_gid(p->sgid), sizeof p->sgroup);            memcpy(p->fgroup, group_from_gid(p->fgid), sizeof p->fgroup);        }    }    if ((flags & PROC_FILLCOM) || (flags & PROC_FILLARG))	/* read+parse /proc/#/cmdline */	p->cmdline = file2strvec(path, "cmdline");    else        p->cmdline = NULL;    if (unlikely(flags & PROC_FILLENV))			/* read+parse /proc/#/environ */	p->environ = file2strvec(path, "environ");    else        p->environ = NULL;        return p;next_proc:    return NULL;}//////////////////////////////////////////////////////////////////////////////////// This reads /proc/*/task/* data, for one task.// p is the POSIX process (task group summary) (not needed by THIS implementation)// t is the POSIX thread (task group member, generally not the leader)// path is a path to the task, with some room to spare.static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t, char *restrict const path) {    static struct stat sb;		// stat() buffer    static char sbuf[1024];	// buffer for stat,statm    unsigned flags = PT->flags;//printf("hhh\n");    if (unlikely(stat(path, &sb) == -1))	/* no such dirent (anymore) */	goto next_task;//    if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))//	goto next_task;			/* not one of the requested uids */    t->euid = sb.st_uid;			/* need a way to get real uid */    t->egid = sb.st_gid;			/* need a way to get real gid *///printf("iii\n");    if (flags & PROC_FILLSTAT) {         /* read, parse /proc/#/stat */	if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 ))	    goto next_task;			/* error reading /proc/#/stat */	stat2proc(sbuf, t);				/* parse /proc/#/stat */    }    if (unlikely(flags & PROC_FILLMEM)) {	/* read, parse /proc/#/statm */#if 0	if (likely( file2str(path, "statm", sbuf, sizeof sbuf) != -1 ))	    statm2proc(sbuf, t);		/* ignore statm errors here */#else	t->size     = p->size;	t->resident = p->resident;	t->share    = p->share;	t->trs      = p->trs;	t->lrs      = p->lrs;	t->drs      = p->drs;	t->dt       = p->dt;#endif    }						/* statm fields just zero */    if (flags & PROC_FILLSTATUS) {         /* read, parse /proc/#/status */       if (likely( file2str(path, "status", sbuf, sizeof sbuf) != -1 )){           status2proc(sbuf, t, 0);       }    }    /* some number->text resolving which is time consuming */    if (flags & PROC_FILLUSR){	memcpy(t->euser,   user_from_uid(t->euid), sizeof t->euser);        if(flags & PROC_FILLSTATUS) {            memcpy(t->ruser,   user_from_uid(t->ruid), sizeof t->ruser);            memcpy(t->suser,   user_from_uid(t->suid), sizeof t->suser);            memcpy(t->fuser,   user_from_uid(t->fuid), sizeof t->fuser);        }    }    /* some number->text resolving which is time consuming */    if (flags & PROC_FILLGRP){        memcpy(t->egroup, group_from_gid(t->egid), sizeof t->egroup);        if(flags & PROC_FILLSTATUS) {            memcpy(t->rgroup, group_from_gid(t->rgid), sizeof t->rgroup);            memcpy(t->sgroup, group_from_gid(t->sgid), sizeof t->sgroup);            memcpy(t->fgroup, group_from_gid(t->fgid), sizeof t->fgroup);        }    }#if 0    if ((flags & PROC_FILLCOM) || (flags & PROC_FILLARG))	/* read+parse /proc/#/cmdline */	t->cmdline = file2strvec(path, "cmdline");    else        t->cmdline = NULL;    if (unlikely(flags & PROC_FILLENV))			/* read+parse /proc/#/environ */	t->environ = file2strvec(path, "environ");    else        t->environ = NULL;#else    t->cmdline = p->cmdline;  // better not free these until done with all threads!    t->environ = p->environ;#endif    t->ppid = p->ppid;  // ought to put the per-task ppid somewhere    return t;next_task:    return NULL;}//////////////////////////////////////////////////////////////////////////////////// This finds processes in /proc in the traditional way.// Return non-zero on success.static int simple_nextpid(PROCTAB *restrict const PT, proc_t *restrict const p) {  static struct direct *ent;		/* dirent handle */  char *restrict const path = PT->path;  for (;;) {    ent = readdir(PT->procfs);

⌨️ 快捷键说明

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