[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 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 *,
 | 
					typedef void (*proc_objname_func_t)(struct ps_prochandle *,
 | 
				
			||||||
                                    uintptr_t, const char *, size_t);
 | 
					                                    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 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 {
 | 
					struct sigar_t {
 | 
				
			||||||
    SIGAR_T_BASE;
 | 
					    SIGAR_T_BASE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -251,9 +263,14 @@ struct sigar_t {
 | 
				
			|||||||
    void *plib;
 | 
					    void *plib;
 | 
				
			||||||
    proc_grab_func_t pgrab;
 | 
					    proc_grab_func_t pgrab;
 | 
				
			||||||
    proc_free_func_t pfree;
 | 
					    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_objname_func_t pobjname;
 | 
				
			||||||
    proc_dirname_func_t pdirname;
 | 
					    proc_dirname_func_t pdirname;
 | 
				
			||||||
    proc_exename_func_t pexename;
 | 
					    proc_exename_func_t pexename;
 | 
				
			||||||
 | 
					    proc_fstat64_func_t pfstat64;
 | 
				
			||||||
 | 
					    proc_getsockopt_func_t pgetsockopt;
 | 
				
			||||||
 | 
					    proc_getsockname_func_t pgetsockname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sigar_cache_t *pargs;
 | 
					    sigar_cache_t *pargs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@
 | 
				
			|||||||
#include <sys/systeminfo.h>
 | 
					#include <sys/systeminfo.h>
 | 
				
			||||||
#include <sys/utsname.h>
 | 
					#include <sys/utsname.h>
 | 
				
			||||||
#include <dlfcn.h>
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PROC_ERRNO ((errno == ENOENT) ? ESRCH : errno)
 | 
					#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->pgrab    = (proc_grab_func_t)dlsym(sigar->plib, "Pgrab");
 | 
				
			||||||
    sigar->pfree    = (proc_free_func_t)dlsym(sigar->plib, "Pfree");
 | 
					    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->pobjname = (proc_objname_func_t)dlsym(sigar->plib, "Pobjname");
 | 
				
			||||||
    sigar->pexename = (proc_exename_func_t)dlsym(sigar->plib, "Pexecname");
 | 
					    sigar->pexename = (proc_exename_func_t)dlsym(sigar->plib, "Pexecname");
 | 
				
			||||||
    sigar->pdirname = (proc_dirname_func_t)dlsym(sigar->plib, "proc_dirname");
 | 
					    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(pgrab);
 | 
				
			||||||
    CHECK_PSYM(pfree);
 | 
					    CHECK_PSYM(pfree);
 | 
				
			||||||
@ -2606,10 +2612,120 @@ int sigar_nfs_server_v3_get(sigar_t *sigar,
 | 
				
			|||||||
    return sigar_nfs_get(sigar, "rfsproccnt_v3", nfs_v3_names, (char *)nfs);
 | 
					    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,
 | 
					int sigar_proc_port_get(sigar_t *sigar, int protocol,
 | 
				
			||||||
                        unsigned long port, sigar_pid_t *pid)
 | 
					                        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;
 | 
					        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,
 | 
					int sigar_os_sys_info_get(sigar_t *sigar,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user