diff --git a/lib/procinfo_unix.C b/lib/procinfo_unix.C new file mode 100644 index 0000000000..c33f1ef187 --- /dev/null +++ b/lib/procinfo_unix.C @@ -0,0 +1,228 @@ +#include "config.h" +#include + +#if HAVE_SYS_TYPES_H +#include +#endif + +#if HAVE_DIRENT_H +#include +#endif + +#include "procinfo.h" +#include "client_msgs.h" + +using std::vector; + + +// see: +// man 5 proc +// /usr/src/linux/fs/proc/array.C + +struct PROC_STAT { + int pid; + char comm[256]; + char state; + int ppid; + int pgrp; + int session; + int tty_nr; + int tpgid; + unsigned long flags; + unsigned long minflt; + unsigned long cminflt; + unsigned long majflt; + unsigned long cmajflt; + unsigned long utime; + unsigned long stime; + int cutime; + int cstime; + int priority; + int nice; + int zero; + int itrealvalue; + unsigned long starttime; + unsigned long vsize; + int rss; + unsigned long rlim; + 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; + + int parse(char*); +}; + +int PROC_STAT::parse(char* buf) { + int n = sscanf(buf, "%d %s %c %d %d %d %d %d " +"%lu %lu %lu %lu %lu %lu %lu " +"%ld %ld %ld %ld %ld %ld " +"%lu %lu " +"%ld " +"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu " +"%d %d", + &pid, + &comm, + &state, + &ppid, + &pgrp, + &session, + &tty_nr, + &tpgid, + &flags, + &minflt, + &cminflt, + &majflt, + &cmajflt, + &utime, + &stime, + &cutime, + &cstime, + &priority, + &nice, + &zero, + &itrealvalue, + &starttime, + &vsize, + &rss, + &rlim, + &startcode, + &endcode, + &startstack, + &kstkesp, + &kstkeip, + &signal, + &blocked, + &sigignore, + &sigcatch, + &wchan, + &nswap, + &cnswap, + &exit_signal, + &processor + ); + return 0; +} + +// build table of all processes in system +// +int procinfo_setup(vector& pi) { + +#if HAVE_DIRENT_H + DIR *dir; + dirent *piddir; + FILE* fd; + PROC_STAT ps; + PROCINFO p; + char pidpath[1024]; + char buf[1024]; + + dir = opendir("/proc"); + if (!dir) return 0; + + while (1) { + piddir = readdir(dir); + if (piddir) { + if (isdigit(piddir->d_name[0])) { + sprintf(pidpath, "/proc/%s/stat", piddir->d_name); + + fd = fopen(pidpath, "r"); + if (fd) { + fgets(buf, sizeof(buf), fd); + ps.parse(buf); + fclose(fd); + + p.id=ps.pid; + p.parentid=ps.ppid; + p.swap_size=ps.vsize; + // rss = pages, need bytes + // assumes page size = 4k + p.working_set_size = ps.rss * 4096.; + // times are in jiffies, need seconds + // assumes 100 jiffies per second + p.user_time = ps.utime / 100.; + p.kernel_time = ps.stime / 100.; + p.is_boinc_app = false; + pi.push_back(p); + } + } + } else { + return 0; + } + } + +#endif + return 0; + +} + +// Scan the process table adding in CPU time and mem usage. Loop +// thru entire table as the entries aren't in order. Recurse at +// most 4 times to get additional child processes +// +void add_child_totals(PROCINFO& pi, vector& piv, int pid, int rlvl) { + unsigned int i; + + if (rlvl > 3) { + return; + } + for (i=0; i& piv) { + unsigned int i; + + for (i=0; i& piv) { + unsigned int i; + + memset(&pi, 0, sizeof(pi)); + for (i=0; i