From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- shell_cmds/killall/killall.1 | 159 +++++++++++++ shell_cmds/killall/killall.c | 549 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 708 insertions(+) create mode 100644 shell_cmds/killall/killall.1 create mode 100644 shell_cmds/killall/killall.c (limited to 'shell_cmds/killall') diff --git a/shell_cmds/killall/killall.1 b/shell_cmds/killall/killall.1 new file mode 100644 index 0000000..7c7b59d --- /dev/null +++ b/shell_cmds/killall/killall.1 @@ -0,0 +1,159 @@ +.\" Copyright (C) 1995 by Joerg Wunsch, Dresden +.\" 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(S) ``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(S) 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. +.\" +.\" $FreeBSD: src/usr.bin/killall/killall.1,v 1.34 2005/01/17 07:44:20 ru Exp $ +.\" +.Dd January 26, 2004 +.Os +.Dt KILLALL 1 +.Sh NAME +.Nm killall +.Nd kill processes by name +.Sh SYNOPSIS +.Nm +.Op Fl delmsvz +.Op Fl help +.Op Fl u Ar user +.Op Fl t Ar tty +.Op Fl c Ar procname +.Op Fl SIGNAL +.Op Ar procname ... +.Sh DESCRIPTION +The +.Nm +utility kills processes selected by name, as opposed to the selection by pid +as done by +.Xr kill 1 . +By default, it will send a +.Dv TERM +signal to all processes with a real UID identical to the +caller of +.Nm +that match the name +.Ar procname . +The super-user is allowed to kill any process. +.Pp +The options are as follows: +.Bl -tag -width 10n -offset indent +.It Fl v +Be more verbose about what will be done. +.It Fl e +Use the effective user ID instead of the (default) real user ID for matching +processes specified with the +.Fl u +option. +.It Fl help +Give a help on the command usage and exit. +.It Fl l +List the names of the available signals and exit, like in +.Xr kill 1 . +.It Fl m +Match the argument +.Ar procname +as a (case sensitive) regular expression against the names +of processes found. +CAUTION! +This is dangerous, a single dot will match any process +running under the real UID of the caller. +.It Fl s +Show only what would be done, but do not send any signal. +.It Fl d +Print detailed information about the processes matched, +but do not send any signal. +.It Fl SIGNAL +Send a different signal instead of the default +.Dv TERM . +The signal may be specified either as a name +(with or without a leading +.Dv SIG ) , +or numerically. +.It Fl u Ar user +Limit potentially matching processes to those belonging to +the specified +.Ar user . +.It Fl t Ar tty +Limit potentially matching processes to those running on +the specified +.Ar tty . +.It Fl c Ar procname +When used with the +.Fl u +or +.Fl t +flags, limit potentially matching processes to those matching +the specified +.Ar procname . +.It Fl z +Do not skip zombies. +This should not have any effect except to print a few error messages +if there are zombie processes that match the specified pattern. +.El +.Sh ALL PROCESSES +Sending a signal to all processes with uid +.Em XYZ +is already supported by +.Xr kill 1 . +So use +.Xr kill 1 +for this job (e.g.\& $ kill -TERM -1 or +as root $ echo kill -TERM -1 | su -m ) +.Sh EXIT STATUS +The +.Nm +command will respond with a short usage message and exit with a status +of 2 in case of a command error. +A status of 1 will be returned if +either no matching process has been found or not all processes have +been signalled successfully. +Otherwise, a status of 0 will be +returned. +.Sh DIAGNOSTICS +Diagnostic messages will only be printed if requested by +.Fl d +options. +.Sh SEE ALSO +.Xr kill 1 , +.Xr sysctl 3 +.Sh HISTORY +The +.Nm +command appeared in +.Fx 2.1 . +It has been modeled after the +.Nm +command as available on other platforms. +.Sh AUTHORS +.An -nosplit +The +.Nm +program was originally written in Perl and was contributed by +.An Wolfram Schneider , +this manual page has been written by +.An J\(:org Wunsch . +The current version of +.Nm +was rewritten in C by +.An Peter Wemm +using +.Xr sysctl 3 . diff --git a/shell_cmds/killall/killall.c b/shell_cmds/killall/killall.c new file mode 100644 index 0000000..4ef96a9 --- /dev/null +++ b/shell_cmds/killall/killall.c @@ -0,0 +1,549 @@ +/*- + * Copyright (c) 2000 Peter Wemm + * Copyright (c) 2000 Paul Saab + * 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 +__FBSDID("$FreeBSD: src/usr.bin/killall/killall.c,v 1.31 2004/07/29 18:36:35 maxim Exp $"); + +#include +#ifndef __APPLE__ +#include +#endif /* !__APPLE__ */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#define OPTIONS ("c:dej:lmst:u:vz") + +#ifdef __APPLE__ +#include +#endif + +static void __dead2 +usage(void) +{ + +#ifdef __APPLE__ + fprintf(stderr, "usage: killall [-delmsvz] [-help]\n"); +#else /* !__APPLE__ */ + fprintf(stderr, "usage: killall [-delmsvz] [-help] [-j jid]\n"); +#endif /* __APPLE__ */ + fprintf(stderr, + " [-u user] [-t tty] [-c cmd] [-SIGNAL] [cmd]...\n"); + fprintf(stderr, "At least one option or argument to specify processes must be given.\n"); + exit(1); +} + +static char * +upper(const char *str) +{ + static char buf[80]; + char *s; + + strncpy(buf, str, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + for (s = buf; *s; s++) + *s = toupper((unsigned char)*s); + return buf; +} + + +static void +printsig(FILE *fp) +{ + const char *const * p; + int cnt; + int offset = 0; + + for (cnt = NSIG, p = sys_signame + 1; --cnt; ++p) { + offset += fprintf(fp, "%s ", upper(*p)); + if (offset >= 75 && cnt > 1) { + offset = 0; + fprintf(fp, "\n"); + } + } + fprintf(fp, "\n"); +} + +static void +nosig(char *name) +{ + + warnx("unknown signal %s; valid signals:", name); + printsig(stderr); + exit(1); +} + +/* + * kludge_signal_args - remove any signal option (-SIGXXX, -##) from the argv array. + */ +void +kludge_signal_args(int *argc, char **argv, int *sig) +{ + int i; + int shift = 0; + int kludge = 1; + char *ptr; + const char *const *p; + char *ep; + + /* i = 1, skip program name */ + for (i = 1; i < *argc; i++) { + /* Stop kludging if we encounter -- */ + if (strcmp(argv[i], "--") == 0) + kludge = 0; + ptr = argv[i] + 1; + /* Only process arguments that start with - and do not look like an existing option. */ + if (kludge && *argv[i] == '-' && *ptr && strchr(OPTIONS, *ptr) == NULL) { + if (isalpha(*ptr)) { + if (strcmp(ptr, "help") == 0) + usage(); + if (strncasecmp(ptr, "sig", 3) == 0) + ptr += 3; + for (*sig = NSIG, p = sys_signame + 1; --*sig; ++p) + if (strcasecmp(*p, ptr) == 0) { + *sig = p - sys_signame; + break; + } + if (!*sig) + nosig(ptr); + } else if (isdigit(*ptr)) { + *sig = strtol(ptr, &ep, 10); + if (*ep) + errx(1, "illegal signal number: %s", ptr); + if (*sig < 0 || *sig >= NSIG) + nosig(ptr); + } else + nosig(ptr); + + shift++; + continue; + } + + argv[i - shift] = argv[i]; + } + + for (i = *argc - shift; i < *argc; i++) { + argv[i] = NULL; + } + + *argc -= shift; +} + +int +main(int ac, char **av) +{ + struct kinfo_proc *procs = NULL, *newprocs; + struct stat sb; + struct passwd *pw; + regex_t rgx; + regmatch_t pmatch; + int i, j; + char buf[256]; + char *user = NULL; + char *tty = NULL; + char *cmd = NULL; + int vflag = 0; + int sflag = 0; + int dflag = 0; + int eflag = 0; +#ifndef __APPLE__ + int jflag = 0; +#endif /* !__APPLE__*/ + int mflag = 0; + int zflag = 0; + uid_t uid = 0; + dev_t tdev = 0; + pid_t mypid; +#ifdef __APPLE__ + char *thiscmd; +#else /* !__APPLE__ */ + char thiscmd[MAXCOMLEN + 1]; +#endif /* __APPLE__ */ + pid_t thispid; +#ifndef __APPLE__ + uid_t thisuid; +#endif /* !__APPLE__ */ + dev_t thistdev; + int sig = SIGTERM; + char *ep; + int errors = 0; +#ifndef __APPLE__ + int jid; +#endif /* !__APPLE__ */ + int mib[4]; + size_t miblen; + int st, nprocs; + size_t size; + int matched; + int killed = 0; + int ch; + + setlocale(LC_ALL, ""); + + kludge_signal_args(&ac, av, &sig); + + while ((ch = getopt(ac, av, OPTIONS)) != -1) { + switch (ch) { + case 'c': + cmd = optarg; + break; + case 'd': + dflag++; + break; + case 'e': + eflag++; + break; +#ifndef __APPLE__ + case 'j': + jflag++; + jid = strtol(optarg, &ep, 10); + if (*ep) + errx(1, "illegal jid: %s", optarg); + if (jail_attach(jid) == -1) + err(1, "jail_attach(): %d", jid); + break; +#endif /* __APPLE__ */ + case 'l': + printsig(stdout); + exit(0); + case 'm': + mflag++; + break; + case 's': + sflag++; + break; + case 't': + tty = optarg; + break; + case 'u': + user = optarg; + break; + case 'v': + vflag++; + break; + case 'z': + zflag++; + break; + default: + usage(); + } + } + + ac -= optind; + av += optind; + +#ifdef __APPLE__ + if (user == NULL && tty == NULL && cmd == NULL && ac == 0) +#else /* !__APPLE__*/ + if (user == NULL && tty == NULL && cmd == NULL && !jflag && ac == 0) +#endif /* __APPLE__ */ + usage(); + + if (tty) { + if (strncmp(tty, "/dev/", 5) == 0) + snprintf(buf, sizeof(buf), "%s", tty); + else if (strncmp(tty, "tty", 3) == 0) + snprintf(buf, sizeof(buf), "/dev/%s", tty); + else + snprintf(buf, sizeof(buf), "/dev/tty%s", tty); + if (stat(buf, &sb) < 0) + err(1, "stat(%s)", buf); + if (!S_ISCHR(sb.st_mode)) + errx(1, "%s: not a character device", buf); + tdev = sb.st_rdev; + if (dflag) + printf("ttydev:0x%x\n", tdev); + } + if (user) { + uid = strtol(user, &ep, 10); + if (*user == '\0' || *ep != '\0') { /* was it a number? */ + pw = getpwnam(user); + if (pw == NULL) + errx(1, "user %s does not exist", user); + uid = pw->pw_uid; + if (dflag) + printf("uid:%d\n", uid); + } + } else { + uid = getuid(); + if (uid != 0) { + pw = getpwuid(uid); + if (pw) + user = pw->pw_name; + if (dflag) + printf("uid:%d\n", uid); + } + } + size = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; +#ifdef __APPLE__ + mib[2] = KERN_PROC_ALL; +#else /* !__APPLE__ */ + mib[2] = KERN_PROC_PROC; +#endif /* __APPLE__ */ + mib[3] = 0; + miblen = 3; + + if (user) { + mib[2] = eflag ? KERN_PROC_UID : KERN_PROC_RUID; + mib[3] = uid; + miblen = 4; + } else if (tty) { + mib[2] = KERN_PROC_TTY; + mib[3] = tdev; + miblen = 4; + } + + do { + st = sysctl(mib, miblen, NULL, &size, NULL, 0); + if (st == -1) + err(1, "could not sysctl(KERN_PROC)"); + if (!size) + errx(1, "could not get size from sysctl(KERN_PROC)"); + size += size / 10; + newprocs = realloc(procs, size); + if (newprocs == 0) { + if (procs) + free(procs); + errx(1, "could not reallocate memory"); + } + procs = newprocs; + st = sysctl(mib, miblen, procs, &size, NULL, 0); + } while (st == -1 && errno == ENOMEM); + if (st == -1) + err(1, "could not sysctl(KERN_PROC)"); + if (size % sizeof(struct kinfo_proc) != 0) { + fprintf(stderr, "proc size mismatch (%zu total, %zu chunks)\n", + size, sizeof(struct kinfo_proc)); + fprintf(stderr, "userland out of sync with kernel, recompile libkvm etc\n"); + exit(1); + } + nprocs = size / sizeof(struct kinfo_proc); + if (dflag) + printf("nprocs %d\n", nprocs); + mypid = getpid(); + + for (i = 0; i < nprocs; i++) { +#ifdef __APPLE__ + if (procs[i].kp_proc.p_stat == SZOMB && !zflag) + continue; + thispid = procs[i].kp_proc.p_pid; + + int mib[3], argmax; + size_t syssize; + char *procargs, *cp; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARGMAX; + + syssize = sizeof(argmax); + if (sysctl(mib, 2, &argmax, &syssize, NULL, 0) == -1) + continue; + + procargs = malloc(argmax); + if (procargs == NULL) + continue; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROCARGS2; + mib[2] = thispid; + + syssize = (size_t)argmax; + if (sysctl(mib, 3, procargs, &syssize, NULL, 0) == -1) { + free(procargs); + continue; + } + + for (cp = procargs; cp < &procargs[syssize]; cp++) { + if (*cp == '\0') { + break; + } + } + + if (cp == &procargs[syssize]) { + free(procargs); + continue; + } + + for (; cp < &procargs[syssize]; cp++) { + if (*cp != '\0') { + break; + } + } + + if (cp == &procargs[syssize]) { + free(procargs); + continue; + } + + /* Strip off any path that was specified */ + for (thiscmd = cp; (cp < &procargs[syssize]) && (*cp != '\0'); cp++) { + if (*cp == '/') { + thiscmd = cp + 1; + } + } + + thistdev = procs[i].kp_eproc.e_tdev; +#else /* !__APPLE__ */ + if (procs[i].ki_stat == SZOMB && !zflag) + continue; + thispid = procs[i].ki_pid; + strncpy(thiscmd, procs[i].ki_comm, MAXCOMLEN); + thiscmd[MAXCOMLEN] = '\0'; + thistdev = procs[i].ki_tdev; +#endif /* __APPLE__ */ +#ifndef __APPLE__ + if (eflag) + thisuid = procs[i].ki_uid; /* effective uid */ + else + thisuid = procs[i].ki_ruid; /* real uid */ +#endif /* !__APPLE__ */ + + if (thispid == mypid) { +#ifdef __APPLE__ + free(procargs); +#endif /* __APPLE__ */ + continue; + } + matched = 1; +#ifndef __APPLE__ + if (user) { + if (thisuid != uid) + matched = 0; + } +#endif /* !__APPLE__ */ + if (tty) { + if (thistdev != tdev) + matched = 0; + } + if (cmd) { + if (mflag) { + if (regcomp(&rgx, cmd, + REG_EXTENDED|REG_NOSUB) != 0) { + mflag = 0; + warnx("%s: illegal regexp", cmd); + } + } + if (mflag) { + pmatch.rm_so = 0; + pmatch.rm_eo = strlen(thiscmd); + if (regexec(&rgx, thiscmd, 0, &pmatch, + REG_STARTEND) != 0) + matched = 0; + regfree(&rgx); + } else { + if (strncmp(thiscmd, cmd, MAXCOMLEN) != 0) + matched = 0; + } + } +#ifndef __APPLE__ + if (jflag && thispid == getpid()) + matched = 0; +#endif /* !__APPLE__ */ + if (matched == 0) { +#ifdef __APPLE__ + free(procargs); +#endif /* !__APPLE__ */ + continue; + } + if (ac > 0) + matched = 0; + for (j = 0; j < ac; j++) { + if (mflag) { + if (regcomp(&rgx, av[j], + REG_EXTENDED|REG_NOSUB) != 0) { + mflag = 0; + warnx("%s: illegal regexp", av[j]); + } + } + if (mflag) { + pmatch.rm_so = 0; + pmatch.rm_eo = strlen(thiscmd); + if (regexec(&rgx, thiscmd, 0, &pmatch, + REG_STARTEND) == 0) + matched = 1; + regfree(&rgx); + } else { + if (strcmp(thiscmd, av[j]) == 0) + matched = 1; + } + if (matched) + break; + } + if (matched == 0) { +#ifdef __APPLE__ + free(procargs); +#endif /* __APPLE__ */ + continue; + } + if (dflag) +#ifdef __APPLE__ + printf("sig:%d, cmd:%s, pid:%d, dev:0x%x\n", sig, + thiscmd, thispid, thistdev); +#else /* !__APPLE__ */ + printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig, + thiscmd, thispid, thistdev, thisuid); +#endif /* __APPLE__ */ + + if (vflag || sflag) + printf("kill -%s %d\n", upper(sys_signame[sig]), + thispid); + + killed++; + if (!dflag && !sflag) { + if (kill(thispid, sig) < 0 /* && errno != ESRCH */ ) { + warn("warning: kill -%s %d", + upper(sys_signame[sig]), thispid); + errors = 1; + } + } +#ifdef __APPLE__ + free(procargs); +#endif /* __APPLE__ */ + } + if (killed == 0) { + fprintf(stderr, "No matching processes %swere found\n", + getuid() != 0 ? "belonging to you " : ""); + errors = 1; + } + exit(errors); +} -- cgit v1.2.3-56-ge451