static struct kinfo_proc * kinfo_resize_proc(kvm_t *kd, struct kinfo_proc *bp) { if (bp < kd->procend) return bp; size_t pos = bp - kd->procend; size_t size = kd->procend - kd->procbase; if (size == 0) size = 8; else size *= 2; kd->procbase = _kvm_realloc(kd, kd->procbase, sizeof(*bp) * size); if (kd->procbase == NULL) return NULL; kd->procend = kd->procbase + size; bp = kd->procbase + pos; return bp; }
char * kvm_getfiles(kvm_t *kd, int op, int arg, int *cnt) { int mib[2], st, n, nfiles, nprocs; size_t size; _kvm_syserr(kd, kd->program, "kvm_getfiles has been broken for years"); return (0); if (ISALIVE(kd)) { size = 0; mib[0] = CTL_KERN; mib[1] = KERN_FILE; st = sysctl(mib, 2, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getfiles"); return (0); } if (kd->argspc == 0) kd->argspc = (char *)_kvm_malloc(kd, size); else if (kd->arglen < (int)size) kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); if (kd->argspc == 0) return (0); kd->arglen = size; st = sysctl(mib, 2, kd->argspc, &size, NULL, 0); if (st != 0) { _kvm_syserr(kd, kd->program, "kvm_getfiles"); return (0); } nfiles = size / sizeof(struct xfile); } else { struct nlist nl[4], *p; nl[0].n_name = "_allproc"; nl[1].n_name = "_nprocs"; nl[2].n_name = "_nfiles"; nl[3].n_name = 0; if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) ; _kvm_err(kd, kd->program, "%s: no such symbol", p->n_name); return (0); } if (KREAD(kd, nl[1].n_value, &nprocs)) { _kvm_err(kd, kd->program, "can't read nprocs"); return (0); } if (KREAD(kd, nl[2].n_value, &nfiles)) { _kvm_err(kd, kd->program, "can't read nfiles"); return (0); } size = sizeof(void *) + (nfiles + 10) * sizeof(struct file); if (kd->argspc == 0) kd->argspc = (char *)_kvm_malloc(kd, size); else if (kd->arglen < (int)size) kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); if (kd->argspc == 0) return (0); kd->arglen = size; n = kvm_deadfiles(kd, op, arg, nl[0].n_value, nprocs); if (n != nfiles) { _kvm_err(kd, kd->program, "inconsistant nfiles"); return (0); } nfiles = n; } *cnt = nfiles; return (kd->argspc); }
char * kvm_getfiles(kvm_t *kd, int op, int arg, int *cnt) { int mib[2], st, nfiles; size_t size; struct file *fp, *fplim; struct filelist filehead; if (kvm_ishost(kd)) { size = 0; mib[0] = CTL_KERN; mib[1] = KERN_FILE; st = sysctl(mib, 2, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getfiles"); return (0); } if (kd->argspc == 0) kd->argspc = (char *)_kvm_malloc(kd, size); else if (kd->arglen < size) kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); if (kd->argspc == 0) return (0); kd->arglen = size; st = sysctl(mib, 2, kd->argspc, &size, NULL, 0); if (st == -1 || size < sizeof(filehead)) { _kvm_syserr(kd, kd->program, "kvm_getfiles"); return (0); } filehead = *(struct filelist *)kd->argspc; fp = (struct file *)(kd->argspc + sizeof (filehead)); fplim = (struct file *)(kd->argspc + size); for (nfiles = 0; filehead.lh_first && (fp < fplim); nfiles++, fp++) filehead.lh_first = fp->f_list.le_next; } else { struct nlist nl[3], *p; nl[0].n_name = "_filehead"; nl[1].n_name = "_nfiles"; nl[2].n_name = 0; if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) ; _kvm_err(kd, kd->program, "%s: no such symbol", p->n_name); return (0); } if (KREAD(kd, nl[0].n_value, &nfiles)) { _kvm_err(kd, kd->program, "can't read nfiles"); return (0); } size = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); if (kd->argspc == 0) kd->argspc = (char *)_kvm_malloc(kd, size); else if (kd->arglen < size) kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); if (kd->argspc == 0) return (0); kd->arglen = size; nfiles = kvm_deadfiles(kd, op, arg, nl[1].n_value, nfiles); if (nfiles == 0) return (0); } *cnt = nfiles; return (kd->argspc); }
struct kinfo_proc * kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) { int mib[4], st, nprocs; int miblen = ((op & ~KERN_PROC_FLAGMASK) == KERN_PROC_ALL) ? 3 : 4; size_t size; if (kd->procbase != 0) { free((void *)kd->procbase); /* * Clear this pointer in case this call fails. Otherwise, * kvm_close() will free it again. */ kd->procbase = 0; } if (kvm_ishost(kd)) { size = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = op; mib[3] = arg; st = sysctl(mib, miblen, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } do { size += size / 10; kd->procbase = (struct kinfo_proc *) _kvm_realloc(kd, kd->procbase, size); if (kd->procbase == 0) return (0); st = sysctl(mib, miblen, kd->procbase, &size, NULL, 0); } while (st == -1 && errno == ENOMEM); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } if (size % sizeof(struct kinfo_proc) != 0) { _kvm_err(kd, kd->program, "proc size mismatch (%zd total, %zd chunks)", size, sizeof(struct kinfo_proc)); return (0); } nprocs = size / sizeof(struct kinfo_proc); } else { struct nlist nl[4], *p; nl[0].n_name = "_nprocs"; nl[1].n_name = "_allproc"; nl[2].n_name = "_zombproc"; nl[3].n_name = 0; if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) ; _kvm_err(kd, kd->program, "%s: no such symbol", p->n_name); return (0); } if (KREAD(kd, nl[0].n_value, &nprocs)) { _kvm_err(kd, kd->program, "can't read nprocs"); return (0); } nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, nl[2].n_value); #ifdef notdef size = nprocs * sizeof(struct kinfo_proc); (void)realloc(kd->procbase, size); #endif } *cnt = nprocs; return (kd->procbase); }
struct kinfo_proc * kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) { int mib[4], st, nprocs; size_t size, osize; int temp_op; if (kd->procbase != 0) { free((void *)kd->procbase); /* * Clear this pointer in case this call fails. Otherwise, * kvm_close() will free it again. */ kd->procbase = 0; } if (ISALIVE(kd)) { size = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = op; mib[3] = arg; temp_op = op & ~KERN_PROC_INC_THREAD; st = sysctl(mib, temp_op == KERN_PROC_ALL || temp_op == KERN_PROC_PROC ? 3 : 4, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } /* * We can't continue with a size of 0 because we pass * it to realloc() (via _kvm_realloc()), and passing 0 * to realloc() results in undefined behavior. */ if (size == 0) { /* * XXX: We should probably return an invalid, * but non-NULL, pointer here so any client * program trying to dereference it will * crash. However, _kvm_freeprocs() calls * free() on kd->procbase if it isn't NULL, * and free()'ing a junk pointer isn't good. * Then again, _kvm_freeprocs() isn't used * anywhere . . . */ kd->procbase = _kvm_malloc(kd, 1); goto liveout; } do { size += size / 10; kd->procbase = (struct kinfo_proc *) _kvm_realloc(kd, kd->procbase, size); if (kd->procbase == NULL) return (0); osize = size; st = sysctl(mib, temp_op == KERN_PROC_ALL || temp_op == KERN_PROC_PROC ? 3 : 4, kd->procbase, &size, NULL, 0); } while (st == -1 && errno == ENOMEM && size == osize); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } /* * We have to check the size again because sysctl() * may "round up" oldlenp if oldp is NULL; hence it * might've told us that there was data to get when * there really isn't any. */ if (size > 0 && kd->procbase->ki_structsize != sizeof(struct kinfo_proc)) { _kvm_err(kd, kd->program, "kinfo_proc size mismatch (expected %zu, got %d)", sizeof(struct kinfo_proc), kd->procbase->ki_structsize); return (0); } liveout: nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize; } else { struct nlist nl[7], *p; nl[0].n_name = "_nprocs"; nl[1].n_name = "_allproc"; nl[2].n_name = "_zombproc"; nl[3].n_name = "_ticks"; nl[4].n_name = "_hz"; nl[5].n_name = "_cpu_tick_frequency"; nl[6].n_name = 0; if (!kd->arch->ka_native(kd)) { _kvm_err(kd, kd->program, "cannot read procs from non-native core"); return (0); } if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) ; _kvm_err(kd, kd->program, "%s: no such symbol", p->n_name); return (0); } if (KREAD(kd, nl[0].n_value, &nprocs)) { _kvm_err(kd, kd->program, "can't read nprocs"); return (0); } if (KREAD(kd, nl[3].n_value, &ticks)) { _kvm_err(kd, kd->program, "can't read ticks"); return (0); } if (KREAD(kd, nl[4].n_value, &hz)) { _kvm_err(kd, kd->program, "can't read hz"); return (0); } if (KREAD(kd, nl[5].n_value, &cpu_tick_frequency)) { _kvm_err(kd, kd->program, "can't read cpu_tick_frequency"); return (0); } size = nprocs * sizeof(struct kinfo_proc); kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); if (kd->procbase == NULL) return (0); nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, nl[2].n_value, nprocs); if (nprocs <= 0) { _kvm_freeprocs(kd); nprocs = 0; } #ifdef notdef else { size = nprocs * sizeof(struct kinfo_proc); kd->procbase = realloc(kd->procbase, size); } #endif } *cnt = nprocs; return (kd->procbase); }