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; proc_exename_func_t pexename;
sigar_cache_t *fsdev; sigar_cache_t *fsdev;
sigar_cache_t *pargs;
solaris_mib2_t mib2; solaris_mib2_t mib2;
}; };

View File

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