C语言环境读取/proc目录的进程信息

2 篇文章 0 订阅
2 篇文章 0 订阅

通过/proc目录可以获取所有的进程信息。

需要注意的是 readlink系统调用不会追加0到字符串结尾,并且字符串的最大长度需要时读取长度+1,便于添加0结束字符串。

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>


typedef struct {
    int Pid;
    int Ppid;
    char Name[128];
    char Username[32];
    int Effecitveuid;
    char Exe[128];
    char Cmdline[1024];
    char Fd[1024];
}proc ;


proc g_proc;


static inline char* next_line( char *str ) {
    int i = 0;
    while( str[i] != '\n' ) {
        if( str[i] == 0 ) {
            return str+i;
        }
        i++;
    }
    i++; //skip the char '\n'
    return str+i;
}

proc* get_proc( int pid ) 
{
    char filename[128];
    char buff[1024];
    char key[16];
    char val0[16], val1[16], val2[16], val3[16]; 
    int str_len;
    FILE *fp;
    int i, count;
    int ret;
    proc* p = &g_proc;
    struct passwd *pws;

    sprintf(filename, "/proc/%d/status", pid);
    fp = fopen(filename, "r");
    if( fp != NULL ){
        str_len = fread(buff, 1, 1024, fp);
        if( str_len > 0) {
            char *next, *curr;
            curr = buff;
            next = next_line(curr);
            count = 0;
            while(next != curr) {
                *(next-1) = 0;
                ret = sscanf(curr, " %s %s %s %s %s ", key, val0, val1, val2, val3);
                if( strcmp(key, "Pid:") == 0 ) {
                    p->Pid = atoi(val0);
                    count++;
                }else if( strcmp(key, "Name:") == 0 ) {
                    strcpy(p->Name, val0);
                    count++;
                }else if( strcmp(key, "PPid:") == 0 ) {
                    p->Ppid = atoi(val0);
                    count++;
                }else if( strcmp(key, "Uid:") == 0 ) {
                    p->Effecitveuid= atoi(val1);
                    int uid = atoi(val0);
                    pws = getpwuid(uid);
                    strcpy(p->Username, pws->pw_name);
                    count++;
                }else if( count >= 3) {
                    break;
                }

                curr = next;
                next = next_line(curr);
            }
            fclose(fp);
        }
    }else{
        return NULL;
    }
    
    p->Cmdline[0] = 0;
    sprintf(filename, "/proc/%d/cmdline", pid);
    fp = fopen(filename, "r");
    if( fp != NULL ) {
        str_len = fread(p->Cmdline, 1, 1024, fp);
        i = 0;
        while(i < str_len-1) {
            if(p->Cmdline[i] == 0) {
                p->Cmdline[i] = ' ';
            }
            i++;
        }
        fclose(fp);
    }

    p->Exe[0] = 0;
    sprintf(filename, "/proc/%d/exe", pid);
    str_len = readlink(filename, p->Exe, 128);
    if( str_len > 0 ) {
        i = 0;
        while(i < str_len) {
            if(p->Exe[i] == 0) {
                p->Exe[i] = ' ';
            }
            i++;
        }
        p->Exe[str_len] = 0;
    }
    
    p->Fd[0] = 0;
    strcpy(p->Fd, "[");
    str_len = 1;
    i = 0;
    while( i < 3 ) {
        sprintf(filename, "/proc/%d/fd/%d", pid, i);
        ret = readlink(filename, buff, 128);
        if( ret > 0 ) {
            buff[ret] = 0;
            str_len += sprintf(p->Fd+str_len, "\"%s\",", buff);
        }
        i++;

    }
    if( p->Fd[str_len-1] == ',') {
        p->Fd[str_len-1] = ']';
    }else {
        strcat(p->Fd, "]");
    }
    return p;
}

int proc2json(proc *p, char *buff) 
{
   int len = 0;
   len += sprintf(buff, "{");
   len += sprintf(buff+len, "\"%s\":%d,", "Pid", p->Pid);
   len += sprintf(buff+len, "\"%s\":\"%s\",", "Name", p->Name);
   len += sprintf(buff+len, "\"%s\":%d,", "Ppid", p->Ppid);
   len += sprintf(buff+len, "\"%s\":\"%s\",", "Username", p->Username);
   len += sprintf(buff+len, "\"%s\":%d,", "Effecitveuid", p->Effecitveuid);
   len += sprintf(buff+len, "\"%s\":\"%s\",", "Exe", p->Exe);
   len += sprintf(buff+len, "\"%s\":\"%s\",", "Cmdline", p->Cmdline);
   len += sprintf(buff+len, "\"%s\":%s", "Fd", p->Fd);
   len += sprintf(buff+len, "}");
   return len;
}

void main() 
{
    int i = 0;
    int ret;
    proc *p;
    char buff[2048];
    while(i++ < 60000) {
        p = get_proc(i);
        if(p) {
            ret = proc2json(&g_proc, buff);
            printf("%s\n", buff);
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值