cache args when using ucb/ps

This commit is contained in:
Doug MacEachern 2005-12-10 02:33:49 +00:00
parent 50f8e4e4b6
commit 9414b07011
2 changed files with 78 additions and 25 deletions

View File

@ -225,6 +225,7 @@ struct sigar_t {
proc_exename_func_t pexename;
sigar_cache_t *fsdev;
sigar_cache_t *pargs;
solaris_mib2_t mib2;
};

View File

@ -100,6 +100,7 @@ int sigar_os_open(sigar_t **sig)
sigar->pobjname = NULL;
sigar->fsdev = NULL;
sigar->pargs = NULL;
SIGAR_ZERO(&sigar->mib2);
sigar->mib2.sd = -1;
@ -142,6 +143,9 @@ int sigar_os_close(sigar_t *sigar)
if (sigar->fsdev) {
sigar_cache_destroy(sigar->fsdev);
}
if (sigar->pargs) {
sigar_cache_destroy(sigar->pargs);
}
free(sigar);
return SIGAR_OK;
}
@ -676,12 +680,56 @@ static char *sigar_getword(char **line, char stop)
return res;
}
static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_args_t *procargs)
{
char buffer[9086], *args;
FILE *fp;
typedef struct {
int timestamp;
char *args;
} pargs_t;
static void pargs_free(void *value)
{
pargs_t *pargs = (pargs_t *)value;
if (pargs->args != NULL) {
free(pargs->args);
}
free(pargs);
}
static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_args_t *procargs,
int timestamp)
{
char buffer[9086], *args, *arg;
sigar_cache_entry_t *ent;
FILE *fp;
pargs_t *pargs;
if (!sigar->pargs) {
sigar->pargs = sigar_cache_new(15);
sigar->pargs->free_value = pargs_free;
}
ent = sigar_cache_get(sigar->pargs, pid);
if (ent->value) {
pargs = (pargs_t *)ent->value;
if (pargs->timestamp != timestamp) {
if (pargs->args) {
free(pargs->args);
pargs->args = NULL;
}
}
}
else {
pargs = malloc(sizeof(*pargs));
pargs->args = NULL;
ent->value = pargs;
}
pargs->timestamp = timestamp;
if (pargs->args) {
args = pargs->args;
}
else {
sprintf(buffer, "/usr/ucb/ps -ww %ld", pid);
if (!(fp = popen(buffer, "r"))) {
@ -691,7 +739,6 @@ static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
(void)fgets(buffer, sizeof(buffer), fp);
if ((args = fgets(buffer, sizeof(buffer), fp))) {
int len;
char *arg;
/* skip PID,TT,S,TIME */
args = sigar_skip_multiple_token(args, 4);
@ -699,15 +746,19 @@ static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
len = strlen(args);
args[len-1] = '\0'; /* chop \n */
pargs->args = malloc(len+1);
memcpy(pargs->args, args, len);
}
pclose(fp);
}
sigar_proc_args_create(procargs);
while (*args && (arg = sigar_getword(&args, ' '))) {
SIGAR_PROC_ARGS_GROW(procargs);
procargs->data[procargs->number++] = arg;
}
}
pclose(fp);
return SIGAR_OK;
}
@ -748,7 +799,8 @@ int sigar_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
if ((fd = open(buffer, O_RDONLY)) < 0) {
if ((errno == EACCES) && sigar->use_ucb_ps) {
return ucb_ps_args_get(sigar, pid, procargs);
return ucb_ps_args_get(sigar, pid, procargs,
pinfo->pr_start.tv_sec);
}
else {
return PROC_ERRNO;