diff --git a/bsd/Makefile b/bsd/Makefile index dcdbf63..86de6c0 100644 --- a/bsd/Makefile +++ b/bsd/Makefile @@ -4,7 +4,7 @@ PROG= restartable WARNS= 3 CFLAGS+= -O2 LDFLAGS= -lutil -SRCS= restartable.c +SRCS= restartable.c kinfo_getargv.c .if ${OPSYS} == "NetBSD" SRCS+= kinfo_getallproc.c diff --git a/bsd/extern.h b/bsd/extern.h new file mode 100644 index 0000000..c742b53 --- /dev/null +++ b/bsd/extern.h @@ -0,0 +1,7 @@ + +void free_argv(char **); +char **kinfo_getargv(pid_t pid); + +#ifdef __NetBSD__ +struct kinfo_proc *kinfo_getallproc(int *); +#endif diff --git a/bsd/kinfo_getallproc.c b/bsd/kinfo_getallproc.c index 501ab0c..6fd621d 100644 --- a/bsd/kinfo_getallproc.c +++ b/bsd/kinfo_getallproc.c @@ -1,32 +1,3 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2007 Robert N. M. Watson - * Copyright (c) 2009 Ulf Lilleengen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - #include #include #include @@ -39,9 +10,7 @@ #define kinfo_proc kinfo_proc2 #endif -#define nitems(x) (sizeof((x)) / sizeof((x)[0])) - -struct kinfo_proc *kinfo_getallproc(int *); +#include "common.h" /* * Sort processes by pid @@ -76,7 +45,7 @@ kinfo_getallproc(int *cntp) mib[5] = 0; len = 0; - if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) < 0) + if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) return (NULL); mib[5] = (int) (len / sizeof(struct kinfo_proc2)); @@ -84,9 +53,7 @@ kinfo_getallproc(int *cntp) if (kipp == NULL) return (NULL); - if (sysctl(mib, nitems(mib), kipp, &len, NULL, 0) < 0) - goto bad; - if (len % sizeof(*kipp) != 0) + if (sysctl(mib, 6, kipp, &len, NULL, 0) < 0) goto bad; *cntp = len / sizeof(*kipp); kinfo_proc_sort(kipp, len / sizeof(*kipp)); diff --git a/bsd/kinfo_getargv.c b/bsd/kinfo_getargv.c new file mode 100644 index 0000000..4bce5c9 --- /dev/null +++ b/bsd/kinfo_getargv.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +static int +memnchr(const void *p, int c, size_t len) +{ + int n = 0; + + for (size_t i = 0; i < len; i++) + if (*((unsigned char *)p + i) == c) + n++; + + return n; +} + +void +free_argv(char **argv) +{ + char **argvp = argv; + + while (*argvp != NULL) { + free(*argvp); + argvp++; + } + + free(argv); +} + +char ** +kinfo_getargv(pid_t pid) +{ + char *buf = NULL; + char **argv; + int mib[4]; + int i, argc; + size_t off = 0, len = ARG_MAX; + + buf = malloc(len); + if (buf == NULL) + return (NULL); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_ARGS; + mib[3] = pid; + + if (sysctl(mib, 4, buf, &len, NULL, 0) < 0) + goto bad; + buf[len] = '\0'; + + argc = memnchr(buf, '\0', len); + argv = malloc((argc + 1) * sizeof(char *)); + if (argv == NULL) + goto bad; + + for (i = 0; i < argc; i++) { + argv[i] = strdup(buf + off); + if (argv[i] == NULL) { + free_argv(argv); + goto bad; + } + off += strlen(argv[i]) + 1; + } + argv[argc] = NULL; + + free(buf); + return (argv); + +bad: + free(buf); + return (NULL); +} diff --git a/bsd/restartable.c b/bsd/restartable.c index 99d8fba..862c44b 100644 --- a/bsd/restartable.c +++ b/bsd/restartable.c @@ -57,12 +57,12 @@ #define ki_pid p_pid #define ki_ppid p_ppid #define ki_ruid p_ruid -struct kinfo_proc * kinfo_getallproc(int *); #endif +#include "extern.h" + static int verbose = 0; -#if 0 /* Avoid ANSI terminal injection from processes that overwrite their argv */ static char * safe_arg(char *arg) { @@ -78,11 +78,11 @@ safe_arg(char *arg) { } static void -print_argv(kvm_t *kd, const struct kinfo_proc *kp) { - char **argv = kvm_getargv(kd, kp, 0); +print_argv(pid_t pid) { + char **argv = kinfo_getargv(pid); if (argv == NULL) { - warn("kvm_getargv(): %d: %s", kp->ki_pid, kvm_geterr(kd)); + warn("%d: kinfo_getargv", pid); return; } printf("\t"); @@ -90,8 +90,9 @@ print_argv(kvm_t *kd, const struct kinfo_proc *kp) { printf(" %s", safe_arg(*argv)); } while (*++argv); printf("\n"); + + free_argv(argv); } -#endif static void print_proc(const struct kinfo_proc *kp) { @@ -115,10 +116,8 @@ print_proc(const struct kinfo_proc *kp) { for (i = 0; i < count; i++) if (vmmap[i].kve_type == KVME_TYPE_VNODE && vmmap[i].kve_protection & KVME_PROT_EXEC && vmmap[i].kve_path[0] == '\0') { printf("%d\t%d\t%d\t%s\t%s\n", kp->ki_pid, kp->ki_ppid, kp->ki_ruid, kp->ki_login, kp->ki_comm); -#if 0 if (verbose) - print_argv(kd, kp); -#endif + print_argv(kp->ki_pid); break; }