after

Echo a string after process dies
git clone _git@git.zakaria.org/after.git
Log | Files | Refs | README | LICENSE

commit 0826f50ee3dd6c34a41ed0e9c9733e8808997ea7
parent 3fa56c31f1a0df03a5175ce577e6f8725150a3f4
Author: zakaria <e-zk@users.noreply.github.com>
Date:   Wed, 15 Sep 2021 20:50:59 +1000

Fix memory leaks

kinfo was never free()d and the kernel virtual memory descriptor was
never closed with kvm_close. These have been fixed.

Valgrind still reports that there is one less free() than there are
alloc()s. However I have yet to figure out why, but I do know Valgrind
has a hard time with reallocarray() so that is likely why.

get_proc_list() has been changed to update_proc_list() and it takes a
pointer to kinfo as the first argument, to make the call to
reallocarray() more sensible.

Diffstat:
Mafter.c | 42++++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/after.c b/after.c @@ -49,28 +49,25 @@ pname_is_in(char *pname, struct kinfo_proc **kinfo, int entries) return 0; } -struct kinfo_proc ** -get_proc_list(kvm_t *kd, int *entries) +void +update_proc_list(struct kinfo_proc ***kinfo, kvm_t *kd, int *entries) { int i; - struct kinfo_proc *kp, **kinfo; + struct kinfo_proc *kp; - // get proc list kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(*kp), entries); if (kp == NULL) errx(1, "%s", kvm_geterr(kd)); - // this may not be necessary since we are not sorting our array at any point - if ((kinfo = reallocarray(NULL, *entries, sizeof(*kinfo))) == NULL) + if (((*kinfo) = reallocarray((*kinfo), *entries, sizeof(*(*kinfo)))) == NULL) err(1, "failed to allocate memory for proc pointers"); - for (i = 0; i < *entries; i++) - kinfo[i] = &kp[i]; - return kinfo; + for (i = 0; i < *entries; i++) + (*kinfo)[i] = &kp[i]; } int -main(int argc, char *argv[]) +main(int argc, char **argv) { int i, ch, entries; int pid = 0; @@ -79,7 +76,7 @@ main(int argc, char *argv[]) char errbuf[_POSIX2_LINE_MAX]; kvm_t *kd; - struct kinfo_proc **kinfo; + struct kinfo_proc **kinfo = NULL; verbose = 0; @@ -127,20 +124,28 @@ main(int argc, char *argv[]) errx(1, "%s", errbuf); // get initial process list - kinfo = get_proc_list(kd, &entries); + update_proc_list(&kinfo, kd, &entries); // if a process name is given use that function, otherwise use pid function while ( - (pname != NULL) ? - pname_is_in(pname, kinfo, entries) : - pid_is_in(pid, kinfo, entries) + (pname != NULL) + ? pname_is_in(pname, kinfo, entries) + : pid_is_in(pid, kinfo, entries) ) { - found = 1; - kinfo = get_proc_list(kd, &entries); + found = 1; // mark the process as existing + update_proc_list(&kinfo, kd, &entries); debug_print("waiting..."); sleep(1); } + // free kinfo and close off access to kernel vmem + free(kinfo); + int kd_error; + if ((kd_error = kvm_close(kd)) < 0) { + errx(1, "failed to close kernel memory descriptor (%d)", kd_error); + } + + // if the process existed at some stage if (found) { debug_print("process died."); printf("%s\n", string); @@ -149,4 +154,4 @@ main(int argc, char *argv[]) } return 0; -} +} +\ No newline at end of file