diff --git a/HISTORY b/HISTORY index 6f59f2c..62d10b1 100644 --- a/HISTORY +++ b/HISTORY @@ -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 diff --git a/src/system_info.c b/src/system_info.c index 9cec453..97957f8 100644 --- a/src/system_info.c +++ b/src/system_info.c @@ -19,7 +19,9 @@ #include #include #include +#include #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; id_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 + diff --git a/src/system_info.h b/src/system_info.h index 22b8385..664639d 100644 --- a/src/system_info.h +++ b/src/system_info.h @@ -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 diff --git a/src/tests/test_mblock.c b/src/tests/test_mblock.c index 62aa77f..2b42db6 100644 --- a/src/tests/test_mblock.c +++ b/src/tests/test_mblock.c @@ -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