Changeset View
Changeset View
Standalone View
Standalone View
lib/libprocstat/libprocstat.c
Show First 20 Lines • Show All 2,638 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
procstat_freekstack(struct procstat *procstat __unused, | procstat_freekstack(struct procstat *procstat __unused, | ||||
struct kinfo_kstack *kkstp) | struct kinfo_kstack *kkstp) | ||||
{ | { | ||||
free(kkstp); | free(kkstp); | ||||
} | } | ||||
static struct advlock_list * | |||||
procstat_getadvlock_sysctl(struct procstat *procstat __unused) | |||||
{ | |||||
struct advlock_list *res; | |||||
struct advlock *a; | |||||
void *buf; | |||||
char *c; | |||||
struct kinfo_lockf *kl; | |||||
size_t buf_len; | |||||
int error; | |||||
static const int kl_name[] = { CTL_KERN, KERN_LOCKF }; | |||||
res = malloc(sizeof(*res)); | |||||
if (res == NULL) | |||||
return (NULL); | |||||
STAILQ_INIT(res); | |||||
buf = NULL; | |||||
buf_len = 0; | |||||
error = sysctl(kl_name, nitems(kl_name), NULL, &buf_len, NULL, 0); | |||||
if (error != 0) { | |||||
warn("sysctl KERN_LOCKF size"); | |||||
goto fail; | |||||
} | |||||
buf_len *= 2; | |||||
buf = malloc(buf_len); | |||||
if (buf == NULL) { | |||||
warn("malloc"); | |||||
goto fail; | |||||
} | |||||
error = sysctl(kl_name, nitems(kl_name), buf, &buf_len, NULL, 0); | |||||
if (error != 0) { | |||||
warn("sysctl KERN_LOCKF data"); | |||||
goto fail; | |||||
} | |||||
for (c = buf; (char *)c < (char *)buf + buf_len; | |||||
c += kl->kl_structsize) { | |||||
kl = (struct kinfo_lockf *)(void *)c; | |||||
if (sizeof(*kl) < (size_t)kl->kl_structsize) { | |||||
warn("ABI broken"); | |||||
goto fail; | |||||
} | |||||
a = malloc(sizeof(*a)); | |||||
if (a == NULL) { | |||||
warn("malloc advlock"); | |||||
goto fail; | |||||
} | |||||
switch (kl->kl_rw) { | |||||
case KLOCK_RW_READ: | |||||
a->rw = PS_ADVLOCK_RO; | |||||
break; | |||||
case KLOCK_RW_WRITE: | |||||
a->rw = PS_ADVLOCK_RW; | |||||
break; | |||||
default: | |||||
warn("ABI broken"); | |||||
free(a); | |||||
goto fail; | |||||
} | |||||
switch (kl->kl_type) { | |||||
case KLOCK_TYPE_FLOCK: | |||||
a->type = PS_ADVLOCK_TYPE_FLOCK; | |||||
break; | |||||
case KLOCK_TYPE_PID: | |||||
a->type = PS_ADVLOCK_TYPE_PID; | |||||
break; | |||||
case KLOCK_TYPE_REMOTE: | |||||
a->type = PS_ADVLOCK_TYPE_REMOTE; | |||||
break; | |||||
default: | |||||
warn("ABI broken"); | |||||
free(a); | |||||
goto fail; | |||||
} | |||||
a->pid = kl->kl_pid; | |||||
a->sysid = kl->kl_sysid; | |||||
a->file_fsid = kl->kl_file_fsid; | |||||
a->file_rdev = kl->kl_file_rdev; | |||||
a->file_fileid = kl->kl_file_fileid; | |||||
a->start = kl->kl_start; | |||||
a->len = kl->kl_len; | |||||
if (kl->kl_path[0] != '\0') { | |||||
a->path = strdup(kl->kl_path); | |||||
if (a->path == NULL) { | |||||
warn("malloc"); | |||||
free(a); | |||||
goto fail; | |||||
} | |||||
} else | |||||
a->path = NULL; | |||||
STAILQ_INSERT_TAIL(res, a, next); | |||||
} | |||||
free(buf); | |||||
return (res); | |||||
fail: | |||||
free(buf); | |||||
procstat_freeadvlock(procstat, res); | |||||
return (NULL); | |||||
} | |||||
struct advlock_list * | |||||
procstat_getadvlock(struct procstat *procstat) | |||||
{ | |||||
switch(procstat->type) { | |||||
case PROCSTAT_KVM: | |||||
warnx("kvm method is not supported"); | |||||
return (NULL); | |||||
case PROCSTAT_SYSCTL: | |||||
return (procstat_getadvlock_sysctl(procstat)); | |||||
case PROCSTAT_CORE: | |||||
warnx("core method is not supported"); | |||||
return (NULL); | |||||
default: | |||||
warnx("unknown access method: %d", procstat->type); | |||||
return (NULL); | |||||
} | |||||
} | |||||
void | |||||
procstat_freeadvlock(struct procstat *procstat __unused, | |||||
struct advlock_list *lst) | |||||
{ | |||||
struct advlock *a, *a1; | |||||
STAILQ_FOREACH_SAFE(a, lst, next, a1) { | |||||
free(__DECONST(char *, a->path)); | |||||
free(a); | |||||
} | |||||
free(lst); | |||||
} | |||||