[SIGAR-76] Implement sigar_proc_port_get for Solaris
This commit is contained in:
		
							parent
							
								
									4b712b5da0
								
							
						
					
					
						commit
						4a61c20405
					
				@ -198,6 +198,10 @@ typedef struct ps_prochandle * (*proc_grab_func_t)(pid_t, int, int *);
 | 
			
		||||
 | 
			
		||||
typedef void (*proc_free_func_t)(struct ps_prochandle *);
 | 
			
		||||
 | 
			
		||||
typedef int (*proc_create_agent_func_t)(struct ps_prochandle *);
 | 
			
		||||
 | 
			
		||||
typedef void (*proc_destroy_agent_func_t)(struct ps_prochandle *);
 | 
			
		||||
 | 
			
		||||
typedef void (*proc_objname_func_t)(struct ps_prochandle *,
 | 
			
		||||
                                    uintptr_t, const char *, size_t);
 | 
			
		||||
 | 
			
		||||
@ -205,6 +209,14 @@ typedef char * (*proc_dirname_func_t)(const char *, char *, size_t);
 | 
			
		||||
 | 
			
		||||
typedef char * (*proc_exename_func_t)(struct ps_prochandle *, char *, size_t);
 | 
			
		||||
 | 
			
		||||
typedef int (*proc_fstat64_func_t)(struct ps_prochandle *, int, void *);
 | 
			
		||||
 | 
			
		||||
typedef int (*proc_getsockopt_func_t)(struct ps_prochandle *,
 | 
			
		||||
                                     int, int, int, void *, int *);
 | 
			
		||||
 | 
			
		||||
typedef int (*proc_getsockname_func_t)(struct ps_prochandle *,
 | 
			
		||||
                                      int, struct sockaddr *, socklen_t *);
 | 
			
		||||
 | 
			
		||||
struct sigar_t {
 | 
			
		||||
    SIGAR_T_BASE;
 | 
			
		||||
 | 
			
		||||
@ -251,9 +263,14 @@ struct sigar_t {
 | 
			
		||||
    void *plib;
 | 
			
		||||
    proc_grab_func_t pgrab;
 | 
			
		||||
    proc_free_func_t pfree;
 | 
			
		||||
    proc_create_agent_func_t pcreate_agent;
 | 
			
		||||
    proc_destroy_agent_func_t pdestroy_agent;
 | 
			
		||||
    proc_objname_func_t pobjname;
 | 
			
		||||
    proc_dirname_func_t pdirname;
 | 
			
		||||
    proc_exename_func_t pexename;
 | 
			
		||||
    proc_fstat64_func_t pfstat64;
 | 
			
		||||
    proc_getsockopt_func_t pgetsockopt;
 | 
			
		||||
    proc_getsockname_func_t pgetsockname;
 | 
			
		||||
 | 
			
		||||
    sigar_cache_t *pargs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@
 | 
			
		||||
#include <sys/systeminfo.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
 | 
			
		||||
#define PROC_ERRNO ((errno == ENOENT) ? ESRCH : errno)
 | 
			
		||||
 | 
			
		||||
@ -568,9 +569,14 @@ static int sigar_init_libproc(sigar_t *sigar)
 | 
			
		||||
 | 
			
		||||
    sigar->pgrab    = (proc_grab_func_t)dlsym(sigar->plib, "Pgrab");
 | 
			
		||||
    sigar->pfree    = (proc_free_func_t)dlsym(sigar->plib, "Pfree");
 | 
			
		||||
    sigar->pcreate_agent = (proc_create_agent_func_t)dlsym(sigar->plib, "Pcreate_agent");
 | 
			
		||||
    sigar->pdestroy_agent = (proc_destroy_agent_func_t)dlsym(sigar->plib, "Pdestroy_agent");
 | 
			
		||||
    sigar->pobjname = (proc_objname_func_t)dlsym(sigar->plib, "Pobjname");
 | 
			
		||||
    sigar->pexename = (proc_exename_func_t)dlsym(sigar->plib, "Pexecname");
 | 
			
		||||
    sigar->pdirname = (proc_dirname_func_t)dlsym(sigar->plib, "proc_dirname");
 | 
			
		||||
    sigar->pfstat64 = (proc_fstat64_func_t)dlsym(sigar->plib, "pr_fstat64");
 | 
			
		||||
    sigar->pgetsockopt = (proc_getsockopt_func_t)dlsym(sigar->plib, "pr_getsockopt");
 | 
			
		||||
    sigar->pgetsockname = (proc_getsockname_func_t)dlsym(sigar->plib, "pr_getsockname");
 | 
			
		||||
 | 
			
		||||
    CHECK_PSYM(pgrab);
 | 
			
		||||
    CHECK_PSYM(pfree);
 | 
			
		||||
@ -2606,11 +2612,121 @@ int sigar_nfs_server_v3_get(sigar_t *sigar,
 | 
			
		||||
    return sigar_nfs_get(sigar, "rfsproccnt_v3", nfs_v3_names, (char *)nfs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int find_port(sigar_t *sigar, struct ps_prochandle *phandle,
 | 
			
		||||
                     sigar_pid_t pid, unsigned long port)
 | 
			
		||||
{
 | 
			
		||||
    DIR *dirp;
 | 
			
		||||
    struct dirent *ent;
 | 
			
		||||
    char pname[PATH_MAX];
 | 
			
		||||
    struct stat64 statb;
 | 
			
		||||
    int found=0;
 | 
			
		||||
 | 
			
		||||
    sprintf(pname, "/proc/%d/fd", (int)pid);
 | 
			
		||||
 | 
			
		||||
    if (!(dirp = opendir(pname))) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while ((ent = readdir(dirp))) {
 | 
			
		||||
        int fd;
 | 
			
		||||
 | 
			
		||||
        if (!isdigit(ent->d_name[0])) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        fd = atoi(ent->d_name);
 | 
			
		||||
 | 
			
		||||
        if (sigar->pfstat64(phandle, fd, &statb) == -1) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((statb.st_mode & S_IFMT) == S_IFSOCK) {
 | 
			
		||||
            struct sockaddr_in sin;
 | 
			
		||||
            struct sockaddr *sa = (struct sockaddr *)&sin;
 | 
			
		||||
            socklen_t len = sizeof(sin);
 | 
			
		||||
            int opt, optsz, rc;
 | 
			
		||||
 | 
			
		||||
            optsz = sizeof(opt);
 | 
			
		||||
            rc = sigar->pgetsockopt(phandle, fd, SOL_SOCKET, SO_TYPE, &opt, &optsz);
 | 
			
		||||
            if (rc != 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt != SOCK_STREAM) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            optsz = sizeof(opt);
 | 
			
		||||
            rc = sigar->pgetsockopt(phandle, fd, SOL_SOCKET, SO_ACCEPTCONN, &opt, &optsz);
 | 
			
		||||
            if (rc != 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt != SO_ACCEPTCONN) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            rc = sigar->pgetsockname(phandle, fd, sa, &len);
 | 
			
		||||
            if (rc != 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ((sa->sa_family == AF_INET) ||
 | 
			
		||||
                (sa->sa_family == AF_INET6))
 | 
			
		||||
            {
 | 
			
		||||
                if (ntohs(sin.sin_port) == port) {
 | 
			
		||||
                    found = 1;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    closedir(dirp);
 | 
			
		||||
 | 
			
		||||
    return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* derived from /usr/bin/pfiles.c */
 | 
			
		||||
int sigar_proc_port_get(sigar_t *sigar, int protocol,
 | 
			
		||||
                        unsigned long port, sigar_pid_t *pid)
 | 
			
		||||
{
 | 
			
		||||
    sigar_proc_list_t pids;
 | 
			
		||||
    int i, status, found=0;
 | 
			
		||||
 | 
			
		||||
    if ((status = sigar_init_libproc(sigar)) != SIGAR_OK) {
 | 
			
		||||
        return SIGAR_ENOTIMPL;
 | 
			
		||||
    }
 | 
			
		||||
    status = sigar_proc_list_get(sigar, &pids);
 | 
			
		||||
    if (status != SIGAR_OK) {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<pids.number; i++) {
 | 
			
		||||
        sigar_pid_t ps_id = pids.data[i];
 | 
			
		||||
        struct ps_prochandle *phandle;
 | 
			
		||||
 | 
			
		||||
        if (ps_id == sigar_pid_get(sigar)) {
 | 
			
		||||
            continue; /* XXX */
 | 
			
		||||
        }
 | 
			
		||||
        status = sigar_pgrab(sigar, ps_id, SIGAR_FUNC, &phandle);
 | 
			
		||||
 | 
			
		||||
        if (status != SIGAR_OK) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sigar->pcreate_agent(phandle) == 0) {
 | 
			
		||||
            found = find_port(sigar, phandle, ps_id, port);
 | 
			
		||||
            sigar->pdestroy_agent(phandle);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sigar->pfree(phandle);
 | 
			
		||||
        if (found) {
 | 
			
		||||
            *pid = ps_id;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sigar_proc_list_destroy(sigar, &pids);
 | 
			
		||||
 | 
			
		||||
    return found ? SIGAR_OK : ENOENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sigar_os_sys_info_get(sigar_t *sigar,
 | 
			
		||||
                          sigar_sys_info_t *sys_info)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user