diff options
author | kib <kib@FreeBSD.org> | 2016-09-30 09:20:44 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-09-30 09:20:44 +0000 |
commit | 69c812782221ac6a0da3d28581cb93af8f607776 (patch) | |
tree | 22ff906d8bd8b35d06c778a80639242aa3397c26 | |
parent | 1664922b18d47041e29a69593827af673336f53b (diff) | |
download | FreeBSD-src-69c812782221ac6a0da3d28581cb93af8f607776.zip FreeBSD-src-69c812782221ac6a0da3d28581cb93af8f607776.tar.gz |
MFC r306261:
Add proccontrol(1).
MFC r306281 (by bdrewery):
DIRDEPS_BUILD: Connect new directories.
-rw-r--r-- | targets/pseudo/userland/Makefile.depend | 1 | ||||
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/proccontrol/Makefile | 7 | ||||
-rw-r--r-- | usr.bin/proccontrol/Makefile.depend | 18 | ||||
-rw-r--r-- | usr.bin/proccontrol/proccontrol.c | 180 |
5 files changed, 207 insertions, 0 deletions
diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 2b1d3d3..f12f240 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -325,6 +325,7 @@ DIRDEPS+= \ usr.bin/pr \ usr.bin/printenv \ usr.bin/printf \ + usr.bin/proccontrol \ usr.bin/procstat \ usr.bin/protect \ usr.bin/quota \ diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 1f0c664..b87c26a 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -122,6 +122,7 @@ SUBDIR= alias \ pr \ printenv \ printf \ + proccontrol \ procstat \ protect \ rctl \ diff --git a/usr.bin/proccontrol/Makefile b/usr.bin/proccontrol/Makefile new file mode 100644 index 0000000..c11c412 --- /dev/null +++ b/usr.bin/proccontrol/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +PROG= proccontrol +WARNS?= 6 +MK_MAN=no + +.include <bsd.prog.mk> diff --git a/usr.bin/proccontrol/Makefile.depend b/usr.bin/proccontrol/Makefile.depend new file mode 100644 index 0000000..3646e2e --- /dev/null +++ b/usr.bin/proccontrol/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/proccontrol/proccontrol.c b/usr.bin/proccontrol/proccontrol.c new file mode 100644 index 0000000..4cb3701 --- /dev/null +++ b/usr.bin/proccontrol/proccontrol.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2016 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/procctl.h> +#include <err.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +enum { + MODE_INVALID, + MODE_TRACE, + MODE_TRAPCAP, +}; + +static pid_t +str2pid(const char *str) +{ + pid_t res; + char *tail; + + res = strtol(str, &tail, 0); + if (*tail != '\0') { + warnx("non-numeric pid"); + return (-1); + } + return (res); +} + +static void __dead2 +usage(void) +{ + + fprintf(stderr, "Usage: proccontrol -m (trace|trapcap) [-q] " + "[-s (enable|disable)] [-p pid | command]\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int arg, ch, error, mode; + pid_t pid; + bool enable, do_command, query; + + mode = MODE_INVALID; + enable = true; + pid = -1; + query = false; + while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) { + switch (ch) { + case 'm': + if (strcmp(optarg, "trace") == 0) + mode = MODE_TRACE; + else if (strcmp(optarg, "trapcap") == 0) + mode = MODE_TRAPCAP; + else + usage(); + break; + case 's': + if (strcmp(optarg, "enable") == 0) + enable = true; + else if (strcmp(optarg, "disable") == 0) + enable = false; + else + usage(); + break; + case 'p': + pid = str2pid(optarg); + break; + case 'q': + query = true; + break; + case '?': + default: + usage(); + break; + } + } + argc -= optind; + argv += optind; + do_command = argc != 0; + if (do_command) { + if (pid != -1 || query) + usage(); + pid = getpid(); + } else if (pid == -1) { + pid = getpid(); + } + + if (query) { + switch (mode) { + case MODE_TRACE: + error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg); + break; + case MODE_TRAPCAP: + error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg); + break; + default: + usage(); + break; + } + if (error != 0) + err(1, "procctl status"); + switch (mode) { + case MODE_TRACE: + if (arg == -1) + printf("disabled\n"); + else if (arg == 0) + printf("enabled, no debugger\n"); + else + printf("enabled, traced by %d\n", arg); + break; + case MODE_TRAPCAP: + switch (arg) { + case PROC_TRAPCAP_CTL_ENABLE: + printf("enabled\n"); + break; + case PROC_TRAPCAP_CTL_DISABLE: + printf("disabled\n"); + break; + } + break; + } + } else { + switch (mode) { + case MODE_TRACE: + arg = enable ? PROC_TRACE_CTL_ENABLE : + PROC_TRACE_CTL_DISABLE; + error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg); + break; + case MODE_TRAPCAP: + arg = enable ? PROC_TRAPCAP_CTL_ENABLE : + PROC_TRAPCAP_CTL_DISABLE; + error = procctl(P_PID, pid, PROC_TRAPCAP_CTL, &arg); + break; + default: + usage(); + break; + } + if (error != 0) + err(1, "procctl ctl"); + if (do_command) { + error = execvp(argv[0], argv); + err(1, "exec"); + } + } + exit(0); +} |