diff options
author | John Baldwin <jhb@FreeBSD.org> | 2013-05-03 21:11:57 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2013-05-03 21:11:57 +0000 |
commit | 958aa57537952c7e7018518bb9d643b81e85e827 (patch) | |
tree | 4b4ec8c6d14c8986e2139b96edf75a870d996980 /lib/libprocstat/libprocstat.c | |
parent | 14303aa88998c64be2962e89ea48306fb44b4037 (diff) | |
download | src-958aa57537952c7e7018518bb9d643b81e85e827.tar.gz src-958aa57537952c7e7018518bb9d643b81e85e827.zip |
Notes
Diffstat (limited to 'lib/libprocstat/libprocstat.c')
-rw-r--r-- | lib/libprocstat/libprocstat.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index dd16c80d1c79..78eae9f7e4ed 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #define _WANT_FILE #include <sys/file.h> #include <sys/conf.h> +#include <sys/ksem.h> #include <sys/mman.h> #define _KERNEL #include <sys/mount.h> @@ -129,6 +130,10 @@ static int procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, char *errbuf); static int procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, struct ptsstat *pts, char *errbuf); +static int procstat_get_sem_info_sysctl(struct filestat *fst, + struct semstat *sem, char *errbuf); +static int procstat_get_sem_info_kvm(kvm_t *kd, struct filestat *fst, + struct semstat *sem, char *errbuf); static int procstat_get_shm_info_sysctl(struct filestat *fst, struct shmstat *shm, char *errbuf); static int procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, @@ -556,6 +561,10 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap data = file.f_data; break; #endif + case DTYPE_SEM: + type = PS_FST_TYPE_SEM; + data = file.f_data; + break; case DTYPE_SHM: type = PS_FST_TYPE_SHM; data = file.f_data; @@ -1003,6 +1012,87 @@ procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, } int +procstat_get_sem_info(struct procstat *procstat, struct filestat *fst, + struct semstat *sem, char *errbuf) +{ + + assert(sem); + if (procstat->type == PROCSTAT_KVM) { + return (procstat_get_sem_info_kvm(procstat->kd, fst, sem, + errbuf)); + } else if (procstat->type == PROCSTAT_SYSCTL || + procstat->type == PROCSTAT_CORE) { + return (procstat_get_sem_info_sysctl(fst, sem, errbuf)); + } else { + warnx("unknown access method: %d", procstat->type); + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); + } +} + +static int +procstat_get_sem_info_kvm(kvm_t *kd, struct filestat *fst, + struct semstat *sem, char *errbuf) +{ + struct ksem ksem; + void *ksemp; + char *path; + int i; + + assert(kd); + assert(sem); + assert(fst); + bzero(sem, sizeof(*sem)); + ksemp = fst->fs_typedep; + if (ksemp == NULL) + goto fail; + if (!kvm_read_all(kd, (unsigned long)ksemp, &ksem, + sizeof(struct ksem))) { + warnx("can't read ksem at %p", (void *)ksemp); + goto fail; + } + sem->mode = S_IFREG | ksem.ks_mode; + sem->value = ksem.ks_value; + if (fst->fs_path == NULL && ksem.ks_path != NULL) { + path = malloc(MAXPATHLEN); + for (i = 0; i < MAXPATHLEN - 1; i++) { + if (!kvm_read_all(kd, (unsigned long)ksem.ks_path + i, + path + i, 1)) + break; + if (path[i] == '\0') + break; + } + path[i] = '\0'; + if (i == 0) + free(path); + else + fst->fs_path = path; + } + return (0); + +fail: + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); +} + +static int +procstat_get_sem_info_sysctl(struct filestat *fst, struct semstat *sem, + char *errbuf __unused) +{ + struct kinfo_file *kif; + + assert(sem); + assert(fst); + bzero(sem, sizeof(*sem)); + kif = fst->fs_typedep; + if (kif == NULL) + return (0); + sem->value = kif->kf_un.kf_sem.kf_sem_value; + sem->mode = kif->kf_un.kf_sem.kf_sem_mode; + return (0); +} + +int procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, struct shmstat *shm, char *errbuf) { |