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;
 | 
					    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;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user