add function get_processes for Linux

pull/5/head
yuqing 2016-01-14 12:29:14 +08:00
parent 6af9b0d52d
commit 0fc9297155
4 changed files with 291 additions and 1 deletions

View File

@ -1,11 +1,12 @@
Version 1.24 2016-01-12
Version 1.24 2016-01-14
* php extension compiled on PHP 7
* add skiplist which support stable sort
* make.sh: use sed to replace perl
* support get local mac addresses
* add system_info.h and system_info.c
* add function get_mounted_filesystems
* add function get_processes for Linux
Version 1.23 2015-11-16
* sched_thread.c: task can execute in a new thread

View File

@ -19,7 +19,9 @@
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include "logger.h"
#include "shared_func.h"
#include "system_info.h"
#ifdef OS_LINUX
@ -245,3 +247,220 @@ int get_mounted_filesystems(struct fast_statfs *stats, const int size, int *coun
#endif
}
#ifdef OS_LINUX
typedef struct fast_process_array {
struct fast_process_info *procs;
int alloc_size;
int count;
} FastProcessArray;
static int check_process_capacity(FastProcessArray *proc_array)
{
struct fast_process_info *procs;
int alloc_size;
int bytes;
if (proc_array->alloc_size > proc_array->count)
{
return 0;
}
alloc_size = proc_array->alloc_size > 0 ?
proc_array->alloc_size * 2 : 128;
bytes = sizeof(struct fast_process_info) * alloc_size;
procs = (struct fast_process_info *)malloc(bytes);
if (procs == NULL)
{
logError("file: "__FILE__", line: %d, "
"malloc %d bytes fail", __LINE__, bytes);
return ENOMEM;
}
memset(procs, 0, bytes);
if (proc_array->count > 0)
{
memcpy(procs, proc_array->procs, sizeof(struct fast_process_info) *
proc_array->count);
free(proc_array->procs);
}
proc_array->alloc_size = alloc_size;
proc_array->procs = procs;
return 0;
}
static void parse_proc_stat(char *buff, const int len, struct fast_process_info *process)
{
char *p;
char *end;
char *start;
int cmd_len;
if (len == 0)
{
process->field_count = 0;
return;
}
end = buff + len;
process->pid = strtol(buff, &p, 10);
p++; //skip space
start = p;
while (p < end)
{
if (*p == ' ' || *p == '\t')
{
if (*start == '(')
{
if (*(p - 1) == ')')
{
break;
}
}
else
{
break;
}
}
p++;
}
if (p == end)
{
process->field_count = 1;
return;
}
if (*start == '(')
{
start++;
cmd_len = p - start - 1;
}
else
{
cmd_len = p - start;
}
if (cmd_len >= sizeof(process->comm))
{
cmd_len = sizeof(process->comm) - 1;
}
memcpy(process->comm, start, cmd_len);
p++; //skip space
process->field_count = 2 +
sscanf(p, "%c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld "
"%ld %ld %llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu "
"%lu %lu %d %d %u %u %llu %lu %ld",
&process->state,
&process->ppid,
&process->pgrp,
&process->session,
&process->tty_nr,
&process->tpgid,
&process->flags,
&process->minflt,
&process->cminflt,
&process->majflt,
&process->cmajflt,
&process->utime,
&process->stime,
&process->cutime,
&process->cstime,
&process->priority,
&process->nice,
&process->num_threads,
&process->itrealvalue,
&process->starttime,
&process->vsize,
&process->rss,
&process->rsslim,
&process->startcode,
&process->endcode,
&process->startstack,
&process->kstkesp,
&process->kstkeip,
&process->signal,
&process->blocked,
&process->sigignore,
&process->sigcatch,
&process->wchan,
&process->nswap,
&process->cnswap,
&process->exit_signal,
&process->processor,
&process->rt_priority,
&process->policy,
&process->delayacct_blkio_ticks,
&process->guest_time,
&process->cguest_time);
}
int get_processes(struct fast_process_info **processes, int *count)
{
const char *dirname = "/proc";
char filename[128];
char buff[4096];
DIR *dir;
struct dirent *ent;
FastProcessArray proc_array;
int64_t bytes;
int result;
int len;
int i;
dir = opendir(dirname);
if (dir == NULL)
{
*count = 0;
*processes = NULL;
logError("file: "__FILE__", line: %d, "
"call opendir %s fail, "
"errno: %d, error info: %s",
__LINE__, dirname, errno, STRERROR(errno));
return errno != 0 ? errno : EPERM;
}
result = 0;
proc_array.procs = NULL;
proc_array.alloc_size = 0;
proc_array.count = 0;
while ((ent=readdir(dir)) != NULL)
{
len = strlen(ent->d_name);
for (i=0; i<len; i++)
{
if (!(ent->d_name[i] >= '0' && ent->d_name[i] <= '9'))
{
break;
}
}
if (i < len)
{
continue;
}
sprintf(filename, "%s/%s/stat", dirname, ent->d_name);
bytes = sizeof(buff);
if (getFileContentEx(filename, buff, 0, &bytes) != 0)
{
continue;
}
if ((result=check_process_capacity(&proc_array)) != 0)
{
break;
}
parse_proc_stat(buff, bytes, proc_array.procs + proc_array.count);
proc_array.count++;
}
closedir(dir);
*count = proc_array.count;
*processes = proc_array.procs;
return result;
}
#endif

View File

@ -46,6 +46,56 @@ extern "C" {
char f_mntonname[MNAMELEN]; /* directory on which mounted */
} FastStatFS;
#ifdef OS_LINUX
typedef struct fast_process_info {
int field_count;
int pid;
char comm[128];
char state;
int ppid;
int pgrp;
int session;
int tty_nr;
int tpgid;
unsigned int flags;
unsigned long minflt;
unsigned long cminflt;
unsigned long majflt;
unsigned long cmajflt;
unsigned long utime;
unsigned long stime;
long cutime;
long cstime;
long priority;
long nice;
long num_threads;
long itrealvalue;
unsigned long long starttime;
unsigned long vsize;
long rss;
unsigned long rsslim;
unsigned long startcode;
unsigned long endcode;
unsigned long startstack;
unsigned long kstkesp;
unsigned long kstkeip;
unsigned long signal;
unsigned long blocked;
unsigned long sigignore;
unsigned long sigcatch;
unsigned long wchan;
unsigned long nswap;
unsigned long cnswap;
int exit_signal;
int processor;
unsigned int rt_priority;
unsigned int policy;
unsigned long long delayacct_blkio_ticks;
unsigned long guest_time;
long cguest_time;
} FastProcessInfo;
#endif
/** get system total memory size
* parameters:
* mem_size: return the total memory size
@ -76,6 +126,16 @@ int get_uptime(time_t *uptime);
*/
int get_mounted_filesystems(struct fast_statfs *stats, const int size, int *count);
#ifdef OS_LINUX
/** get processes
* parameters:
* processes: return the processes
* count: return the count of the processes
* return: error no , 0 success, != 0 fail
*/
int get_processes(struct fast_process_info **processes, int *count);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -85,6 +85,16 @@ int main(int argc, char *argv[])
stats[i].f_ffree);
}
{
FastProcessInfo *processes;
get_processes(&processes, &count);
printf("count: %d\n", count);
for (i=0; i<count; i++)
{
printf("%d %d %c %s\n", processes[i].field_count, processes[i].pid, processes[i].state, processes[i].comm);
}
}
//iniPrintItems(&iniContext);
iniFreeContext(&iniContext);