aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbhackerozzo <bhackerozzo@3b445381-d045-0410-9223-e17ecdb95f4b>2008-09-07 13:42:29 +0000
committerbhackerozzo <bhackerozzo@3b445381-d045-0410-9223-e17ecdb95f4b>2008-09-07 13:42:29 +0000
commite25774f1e25d66143811e5414bea4557f0a67f00 (patch)
treeddf4ceed0ea4e8b3888ce65df92dde5bda9f4783
parent873ae317d65e72a0dcd09cff74b8668e4a298e96 (diff)
downloadcpulimit-e25774f1e25d66143811e5414bea4557f0a67f00.tar.gz
using kvm_* for macosx, compatible with *bsd
-rw-r--r--process.c35
-rw-r--r--process.h11
-rw-r--r--procutils.c207
-rw-r--r--procutils.h8
4 files changed, 160 insertions, 101 deletions
diff --git a/process.c b/process.c
index ddce042..315ed38 100644
--- a/process.c
+++ b/process.c
@@ -23,8 +23,11 @@
#include "process.h"
+#include <fcntl.h>
+
#ifdef __APPLE__
-#include <Carbon/Carbon.h>
+#include <kvm.h>
+#include <sys/sysctl.h>
#endif
// returns the start time of a process (used with pid to identify a process)
@@ -47,13 +50,15 @@ static int get_starttime(pid_t pid)
int time = atoi(p+1);
return time;
#elif defined __APPLE__
- ProcessSerialNumber psn;
- ProcessInfoRec info;
- memset(&info, 0, sizeof(ProcessInfoRec));
- info.processInfoLength = sizeof(ProcessInfoRec);
- if (GetProcessForPID(pid, &psn)) return -1;
- if (GetProcessInformation(&psn, &info)) return -1;
- return info.processLaunchDate;
+ int count;
+ kvm_t *kp = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
+ if (kp) return -1;
+ struct kinfo_proc *proc = kvm_getprocs(kp, KERN_PROC_PID, pid, &count);
+ if (!proc) return -2;
+ //return only seconds
+ int ret = proc->kp_proc.p_starttime.tv_sec;
+ kvm_close(kp);
+ return ret;
#endif
}
@@ -75,11 +80,15 @@ static int get_jiffies(struct process *proc) {
int ktime = atoi(p+1);
return utime+ktime;
#elif defined __APPLE__
- ProcessSerialNumber psn;
- ProcessInfoRec info;
- if (GetProcessForPID(proc->pid, &psn)) return -1;
- if (GetProcessInformation(&psn, &info)) return -1;
- return info.processActiveTime;
+ int count;
+ kvm_t *kp = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
+ if (kp) return -1;
+ struct kinfo_proc *kproc = kvm_getprocs(kp, KERN_PROC_PID, proc->pid, &count);
+ if (!kproc) return -2;
+ //return only seconds
+ int ret = kproc->kp_proc.p_starttime.tv_sec;
+ kvm_close(kp);
+ return ret;
#endif
}
diff --git a/process.h b/process.h
index 5b3a305..3ae33cd 100644
--- a/process.h
+++ b/process.h
@@ -31,11 +31,10 @@
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
+#include <sys/utsname.h>
+#include <limits.h>
-//kernel time resolution timer interrupt frequency in Hertz
-//#define HZ sysconf(_SC_CLK_TCK)
-
-//HZ detection, from openssl code
+//USER_HZ detection, from openssl code
#ifndef HZ
# if defined(_SC_CLK_TCK) \
&& (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000)
@@ -57,6 +56,8 @@
struct process {
//pid of the process
pid_t pid;
+ //pid of the process
+ pid_t ppid;
//start time
int starttime;
//is member of the family?
@@ -69,6 +70,8 @@ struct process {
double cpu_usage;
//1 if the process is zombie
int is_zombie;
+ //absolute path of the executable file
+ char command[PATH_MAX+1];
//system-dependent members
//TODO: delete these members for the sake of portability?
diff --git a/procutils.c b/procutils.c
index 3c3221e..601a03d 100644
--- a/procutils.c
+++ b/procutils.c
@@ -19,11 +19,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <fcntl.h>
#include <sys/utsname.h>
#include "procutils.h"
+#include "sys/types.h"
+#include "sys/stat.h"
+
+#ifdef __APPLE__
+#include <kvm.h>
+#include <sys/sysctl.h>
+#endif
/* PROCESS STATISTICS FUNCTIONS */
+//deprecated
// returns pid of the parent process
static pid_t getppid_of(pid_t pid)
{
@@ -44,22 +53,21 @@ static pid_t getppid_of(pid_t pid)
pid_t ppid = atoi(p+1);
return ppid;
#elif defined __APPLE__
- ProcessSerialNumber psn_child;
- ProcessInfoRec info_child;
- pid_t ppid;
- memset(&info_child, 0, sizeof(ProcessInfoRec));
- info_child.processInfoLength = sizeof(ProcessInfoRec);
- if (GetProcessForPID(pid, &psn_child)) return -1;
- if (GetProcessInformation(&psn_child, &info_child)) return -1;
- if (GetProcessPID (&(info_child.processLauncher), &ppid)) return -1;
+ int count;
+ kvm_t *kp = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
+ if (kp) return -1;
+ struct kinfo_proc *proc = kvm_getprocs(kp, KERN_PROC_PID, pid, &count);
+ if (!proc) return -2;
+ int ppid = proc->kp_eproc.e_ppid;
+ kvm_close(kp);
return ppid;
#endif
}
+#ifdef __linux__
// detects whether a process is a kernel thread or not
static int is_kernel_thread(pid_t pid)
{
-#ifdef __linux__
static char statfile[20];
static char buffer[64];
int ret;
@@ -70,29 +78,55 @@ static int is_kernel_thread(pid_t pid)
ret = strncmp(buffer,"0 0 0",3)==0;
fclose(fd);
return ret;
-#elif defined __APPLE__
- return 0;
-#endif
}
+#endif
+//deprecated
// returns 1 if pid is a user process, 0 otherwise
static int process_exists(pid_t pid) {
#ifdef __linux__
+ static char procdir[20];
+ struct stat procstat;
+ sprintf(procdir, "/proc/%d", pid);
+ return stat(procdir, &procstat)==0;
+#elif defined __APPLE__
+ int count;
+ kvm_t *kp = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
+ if (kp) return -1;
+ struct kinfo_proc *proc = kvm_getprocs(kp, KERN_PROC_PID, pid, &count);
+ if (!proc) return -2;
+ kvm_close(kp);
+ return count;
+#endif
+}
+
+#ifdef __linuxblabla__
+int get_proc_stat(struct process *p, pid_t pid) {
static char statfile[20];
static char buffer[64];
int ret;
- sprintf(statfile, "/proc/%d/statm", pid);
+ sprintf(statfile, "/proc/%d/stat", pid);
FILE *fd = fopen(statfile, "r");
- if (fd==NULL) return 0;
+ if (fd==NULL) return -1;
fgets(buffer, sizeof(buffer), fd);
- ret = strncmp(buffer,"0 0 0",3)!=0;
fclose(fd);
- return ret;
-#elif defined __APPLE__
- ProcessSerialNumber psn;
- return !GetProcessForPID(pid, &psn);
-#endif
+
+ char state;
+
+ int n = sscanf(buffer, "%d %s %c %d %d %d %d %d "
+ "%lu %lu %lu %lu %lu %lu %lu "
+ "%ld %ld %ld %ld %ld %ld "
+ "%lu ",
+ &p->pid,
+ &p->command,
+ &state,
+ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+ &utime,&stime,&cutime,&cstime,
+ NULL,NULL,NULL,NULL,
+ &starttime,
+ );
}
+#endif
/* PID HASH FUNCTIONS */
@@ -149,7 +183,7 @@ static struct process *seek_process(struct process_family *f, pid_t pid)
/* PROCESS ITERATOR STUFF */
// creates an object that browse all running processes
-static int init_process_iterator(struct process_iterator *i) {
+int init_process_iterator(struct process_iterator *i) {
#ifdef __linux__
//open a directory stream to /proc directory
if ((i->dip = opendir("/proc")) == NULL) {
@@ -157,21 +191,26 @@ static int init_process_iterator(struct process_iterator *i) {
return -1;
}
#elif defined __APPLE__
- i->psn.highLongOfPSN = kNoProcess;
- i->psn.lowLongOfPSN = kNoProcess;
+ i->kp = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
+ if (!i->kp) return -1;
+ i->proc = kvm_getprocs(i->kp, KERN_PROC_ALL, 0, &i->count);
+ if (!i->proc) return -2;
+ i->c = 0;
#endif
+ i->current = malloc(sizeof(struct process));
+ memset(i->current, 0, sizeof(struct process));
return 0;
}
// reads the next user process from /process
// automatic closing if the end of the list is reached
-static pid_t read_next_process(struct process_iterator *i) {
- pid_t pid = 0;
+int read_next_process(struct process_iterator *i) {
#ifdef __linux__
+ pid_t pid = 0;
//TODO read this to port to other systems: http://www.steve.org.uk/Reference/Unix/faq_8.html#SEC85
//read in from /proc and seek for process dirs
while ((i->dit = readdir(i->dip)) != NULL) {
- if( strtok(i->dit->d_name, "0123456789") != NULL )
+ if(strtok(i->dit->d_name, "0123456789") != NULL)
continue;
pid = atoi(i->dit->d_name);
if (is_kernel_thread(pid))
@@ -180,17 +219,40 @@ static pid_t read_next_process(struct process_iterator *i) {
break;
}
if (pid == 0) {
- //no more processes, release resources
+ //no more processes
closedir(i->dip);
+ free(i->current);
+ i->current = NULL;
+ return -1;
}
+ //read the executable link
+ char statfile[20];
+ sprintf(statfile,"/proc/%d/cmdline",pid);
+ FILE *fd = fopen(statfile, "r");
+ char buffer[1024];
+ fgets(buffer, sizeof(buffer), fd);
+ fclose(fd);
+ sscanf(buffer, "%s", (char*)&i->current->command);
+ i->current->pid = pid;
+
#elif defined __APPLE__
- ProcessInfoRec info;
- memset(&info, 0, sizeof(ProcessInfoRec));
- info.processInfoLength = sizeof(ProcessInfoRec);
- if (GetNextProcess(&i->psn)) return 0;
- GetProcessPID(&(i->psn), &pid);
+printf("%d di %d\n", i->c, i->count);
+ if (!i->kp || !i->proc) return 0;
+ if (i->c >= i->count) {
+ //no more processes
+ kvm_close(i->kp);
+ i->kp = NULL;
+ i->proc = NULL;
+ free(i->current);
+ i->current = NULL;
+ return -1;
+ }
+ i->current->pid = i->proc[i->c].kp_proc.p_pid;
+ strncpy(i->current->command, i->proc[i->c].kp_proc.p_comm, MAXCOMLEN);
+printf("%d %d %s\n", i->c, i->current->pid, i->proc[i->c].kp_proc.p_comm);
+ i->c++;
#endif
- return pid;
+ return 0;
}
/* PUBLIC FUNCTIONS */
@@ -209,7 +271,8 @@ int create_process_family(struct process_family *f, pid_t father)
struct process_iterator iter;
init_process_iterator(&iter);
int pid = 0;
- while ((pid = read_next_process(&iter))) {
+ while (read_next_process(&iter)==0) {
+ pid = iter.current->pid;
//check if process belongs to the family
int ppid = pid;
//TODO: optimize adding also these parents, and continue if process is already present
@@ -245,7 +308,8 @@ int update_process_family(struct process_family *f)
struct process_iterator iter;
init_process_iterator(&iter);
int pid = 0;
- while ((pid = read_next_process(&iter))) {
+ while (read_next_process(&iter)==0) {
+ pid = iter.current->pid;
struct process *newp = seek_process(f, pid);
if (newp != NULL) continue; //already known //TODO: what if newp is a new process with the same PID??
//the process is new, check if it belongs to the family
@@ -337,10 +401,6 @@ int look_for_process_by_pid(pid_t pid)
// negative pid, if it is found but it's not possible to control it
int look_for_process_by_name(const char *process_name)
{
- //the name of /proc/pid/exe symbolic link pointing to the executable file
- char exelink[20];
- //the name of the executable file
- char exepath[PATH_MAX+1];
//whether the variable process_name is the absolute path or not
int is_absolute_path = process_name[0] == '/';
//flag indicating if the a process with given name was found
@@ -350,55 +410,37 @@ int look_for_process_by_name(const char *process_name)
struct process_iterator iter;
init_process_iterator(&iter);
pid_t pid = 0;
-#ifdef __APPLE__
- ProcessSerialNumber psn;
- ProcessInfoRec info;
- memset(&info, 0, sizeof(ProcessInfoRec));
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = (char*)malloc(64*sizeof(char));
-#endif
- while ((pid = read_next_process(&iter))) {
- int size = 0;
-#ifdef __linux__
- //read the executable link
- sprintf(exelink,"/proc/%d/exe",pid);
- size = readlink(exelink, exepath, sizeof(exepath));
- exepath[size] = '\0';
-#elif defined __APPLE__
- //get the executable file name
- if (GetProcessForPID(pid, &psn)) return -1;
- if (GetProcessInformation(&psn, &info)) return -1;
- size = strlen(info.processName);
- strcpy(exepath, info.processName);
-#endif
- if (size>0) {
- found = 0;
- if (is_absolute_path && strncmp(exepath, process_name, size)==0 && size==strlen(process_name)) {
- //process found
+
+printf("name\n");
+
+ while (read_next_process(&iter)==0) {
+ pid = iter.current->pid;
+
+ int size = strlen(iter.current->command);
+
+ found = 0;
+ if (is_absolute_path && strncmp(iter.current->command, process_name, size)==0 && size==strlen(process_name)) {
+ //process found
+ found = 1;
+ }
+ else {
+ //process found
+ if (strncmp(iter.current->command + size - strlen(process_name), process_name, strlen(process_name))==0) {
found = 1;
}
- else {
- //process found
- if (strncmp(exepath + size - strlen(process_name), process_name, strlen(process_name))==0) {
- found = 1;
- }
+ }
+ if (found==1) {
+ if (kill(pid,SIGCONT)==0) {
+ //process is ok!
+ break;
}
- if (found==1) {
- if (kill(pid,SIGCONT)==0) {
- //process is ok!
- break;
- }
- else {
- //we don't have permission to send signal to that process
- //so, don't exit from the loop and look for another one with the same name
- found = -1;
- }
+ else {
+ //we don't have permission to send signal to that process
+ //so, don't exit from the loop and look for another one with the same name
+ found = -1;
}
}
}
-#ifdef __APPLE__
- free(info.processName);
-#endif
if (found == 1) {
//ok, the process was found
return pid;
@@ -414,3 +456,4 @@ int look_for_process_by_name(const char *process_name)
//this MUST NOT happen
return 0;
}
+
diff --git a/procutils.h b/procutils.h
index 720b09b..de77d05 100644
--- a/procutils.h
+++ b/procutils.h
@@ -36,7 +36,7 @@
#include "process.h"
#ifdef __APPLE__
-#include <Carbon/Carbon.h>
+#include <kvm.h>
#endif
#define PIDHASH_SZ 1024
@@ -69,8 +69,12 @@ struct process_iterator {
DIR *dip;
struct dirent *dit;
#elif defined __APPLE__
- ProcessSerialNumber psn;
+ kvm_t *kp;
+ struct kinfo_proc *proc;
+ int count;
+ int c;
#endif
+ struct process *current;
};
// searches for all the processes derived from father and stores them
Un proyecto texto-plano.xyz