cache args when using ucb/ps
This commit is contained in:
		
							parent
							
								
									50f8e4e4b6
								
							
						
					
					
						commit
						9414b07011
					
				@ -225,6 +225,7 @@ struct sigar_t {
 | 
			
		||||
    proc_exename_func_t pexename;
 | 
			
		||||
 | 
			
		||||
    sigar_cache_t *fsdev;
 | 
			
		||||
    sigar_cache_t *pargs;
 | 
			
		||||
 | 
			
		||||
    solaris_mib2_t mib2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user