kill 与killall
【查询命令所属软件包】
rpm -qf /usr/bin/killall
psmisc-22.20-15.el7.x86_64
rpm -qf /usr/bin/kill
util-linux-2.23.2-65.el7_9.1.x86_64
【命令参数】
killall | kill |
-e,--exact require exact match for very long names -I,--ignore-case case insensitive process name match -g,--process-group kill process group instead of process -y,--younger-than kill processes younger than TIME -o,--older-than kill processes older than TIME -i,--interactive ask for confirmation before killing -l,--list list all known signal names -q,--quiet don't print complaints -r,--regexp interpret NAME as an extended regular expression -s,--signal SIGNAL send this signal instead of SIGTERM -u,--user USER kill only process(es) running as USER -v,--verbose report if the signal was successfully sent -V,--version display version information -w,--wait wait for processes to die -Z,--context REGEXP kill only process(es) having context (must precede other arguments) | -- |
【源码】
kill GitHub - util-linux/util-linux at v2.23.2
killall https://gitlab.com/psmisc/psmisc/-/tree/v22.20
killall 代码实现关键点:kill 调用,正则表达式匹配、虚拟目录(/proc/)枚举进程
/** killall.c - kill processes by name or list PIDs** Copyright (C) 1993-2002 Werner Almesberger* Copyright (C) 2002-2012 Craig Small** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif#ifdef HAVE_CONFIG_H
#include <config.h>
#endif#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pwd.h>
#include <regex.h>
#include <ctype.h>
#include <assert.h>#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /*WITH_SELINUX*/#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif /* HAVE_LOCALE_H */#include "i18n.h"
#include "comm.h"
#include "signals.h"#define PROC_BASE "/proc"
#define MAX_NAMES (int)(sizeof(unsigned long)*8)#define TSECOND "s"
#define TMINUTE "m"
#define THOUR "h"
#define TDAY "d"
#define TWEEK "w"
#define TMONTH "M"
#define TYEAR "y"#define TMAX_SECOND 31536000
#define TMAX_MINUTE 525600
#define TMAX_HOUR 8760
#define TMAX_DAY 365
#define TMAX_WEEK 48
#define TMAX_MONTH 12
#define TMAX_YEAR 1 #define ER_REGFAIL -1
#define ER_NOMEM -2
#define ER_UNKWN -3
#define ER_OOFRA -4static int verbose = 0, exact = 0, interactive = 0, reg = 0,quiet = 0, wait_until_dead = 0, process_group = 0,ignore_case = 0;
static long younger_than = 0, older_than = 0;static int
ask (char *name, pid_t pid, const int signal)
{int res;size_t len;char *line;line = NULL;len = 0;do {if (signal == SIGTERM)printf (_("Kill %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",pid);elseprintf (_("Signal %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",pid);fflush (stdout);if (getline (&line, &len, stdin) < 0)return 0;/* Check for default */if (line[0] == '\n') {free(line);return 0;}res = rpmatch(line);if (res >= 0) {free(line);return res;}} while(1);/* Never should get here */
}static double
uptime()
{char * savelocale;char buf[2048];FILE* file;if (!(file=fopen( PROC_BASE "/uptime", "r"))) {fprintf(stderr, "killall: error opening uptime file\n"); exit(1);}savelocale = setlocale(LC_NUMERIC, NULL);setlocale(LC_NUMERIC,"C");if (fscanf(file, "%2047s", buf) == EOF) perror("uptime");fclose(file);setlocale(LC_NUMERIC,savelocale);return atof(buf);
}/* process age from jiffies to seconds via uptime */
static double process_age(const unsigned long long jf)
{double age;double sc_clk_tck = sysconf(_SC_CLK_TCK);assert(sc_clk_tck > 0);age = uptime() - jf / sc_clk_tck;if (age < 0L)return 0L;return age;
}/* returns requested time interval in seconds, negative indicates error has occurred*/
static long
parse_time_units(const char* age)
{char *unit;long num;num = strtol(age,&unit,10);if (age == unit) /* no digits found */return -1;if (unit[0] == '\0') /* no units found */return -1;switch(unit[0]) {case 's':return num;case 'm':return (num * 60);case 'h':return (num * 60 * 60);case 'd':return (num * 60 * 60 * 24);case 'w':return (num * 60 * 60 * 24 * 7);case 'M':return (num * 60 * 60 * 24 * 7 * 4);case 'y':return (num * 60 * 60 * 24 * 7 * 4 * 12);}return -1;
}static int
match_process_uid(pid_t pid, uid_t uid)
{char buf[128];uid_t puid;FILE *f;int re = -1;snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);if (!(f = fopen (buf, "r")))return 0;while (fgets(buf, sizeof buf, f)){if (sscanf (buf, "Uid:\t%d", &puid)){re = uid==puid;break;}}fclose(f);if (re==-1){fprintf(stderr, _("killall: Cannot get UID from process status\n"));exit(1);}return re;
}static regex_t *
build_regexp_list(int names, char **namelist)
{int i;regex_t *reglist;int flag = REG_EXTENDED|REG_NOSUB;if (!(reglist = malloc (sizeof (regex_t) * names))){perror ("malloc");exit (1);}if (ignore_case)flag |= REG_ICASE;for (i = 0; i < names; i++){if (regcomp(®list[i], namelist[i], flag) != 0) {fprintf(stderr, _("killall: Bad regular expression: %s\n"), namelist[i]);exit (1);}}return reglist;
}#ifdef WITH_SELINUX
static int
kill_all(int signal, int names, char **namelist, struct passwd *pwent, regex_t *scontext )
#else /*WITH_SELINUX*/
static int
kill_all (int signal, int names, char **namelist, struct passwd *pwent)
#endif /*WITH_SELINUX*/
{DIR *dir;struct dirent *de;FILE *file;struct stat st, sts[MAX_NAMES];int *name_len = NULL;char *path, comm[COMM_LEN];char *command_buf;char *command;pid_t *pid_table, pid, self, *pid_killed;pid_t *pgids;int i, j, okay, length, got_long, error;int pids, max_pids, pids_killed;unsigned long found;regex_t *reglist = NULL;;
#ifdef WITH_SELINUXsecurity_context_t lcontext=NULL;
#endif /*WITH_SELINUX*/if (names && reg) reglist = build_regexp_list(names, namelist);else if (names){if (!(name_len = malloc (sizeof (int) * names))){perror ("malloc");exit (1);}for (i = 0; i < names; i++) {if (!strchr (namelist[i], '/')){sts[i].st_dev = 0;name_len[i] = strlen (namelist[i]);}else if (stat (namelist[i], &sts[i]) < 0){perror (namelist[i]);exit (1);}}} self = getpid ();found = 0;if (!(dir = opendir (PROC_BASE))){perror (PROC_BASE);exit (1);}max_pids = 256;pid_table = malloc (max_pids * sizeof (pid_t));if (!pid_table){perror ("malloc");exit (1);}pids = 0;while ( (de = readdir (dir)) != NULL){if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)continue;if (pids == max_pids){if (!(pid_table = realloc (pid_table, 2 * pids * sizeof (pid_t)))){perror ("realloc");exit (1);}max_pids *= 2;}pid_table[pids++] = pid;}(void) closedir (dir);pids_killed = 0;pid_killed = malloc (max_pids * sizeof (pid_t));if (!pid_killed){perror ("malloc");exit (1);}if (!process_group)pgids = NULL; /* silence gcc */else{pgids = calloc (pids, sizeof (pid_t));if (!pgids){perror ("malloc");exit (1);}}for (i = 0; i < pids; i++){pid_t id;int found_name = -1;double process_age_sec = 0;/* match by UID */if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0)continue;
#ifdef WITH_SELINUX/* match by SELinux context */if (scontext) {if (getpidcon(pid_table[i], &lcontext) < 0)continue;if (regexec(scontext, lcontext, 0, NULL, 0) != 0) {freecon(lcontext);continue;}freecon(lcontext);}
#endif /*WITH_SELINUX*//* load process name */if (asprintf (&path, PROC_BASE "/%d/stat", pid_table[i]) < 0)continue;if (!(file = fopen (path, "r"))) {free (path);continue;}free (path);okay = fscanf (file, "%*d (%15[^)]", comm) == 1;if (!okay) {fclose(file);continue;}if ( younger_than || older_than ) {rewind(file);unsigned long long proc_stt_jf = 0;okay = fscanf(file, "%*d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", &proc_stt_jf) == 1;if (!okay) {fclose(file);continue;}process_age_sec = process_age(proc_stt_jf);}(void) fclose (file);got_long = 0;command = NULL; /* make gcc happy */length = strlen (comm);if (length == COMM_LEN - 1){if (asprintf (&path, PROC_BASE "/%d/cmdline", pid_table[i]) < 0)continue;if (!(file = fopen (path, "r"))) {free (path);continue;}free (path);while (1) {/* look for actual command so we skip over initial "sh" if any */char *p;int cmd_size = 128;command_buf = (char *)malloc (cmd_size);if (!command_buf)exit (1);/* 'cmdline' has arguments separated by nulls */for (p=command_buf; ; p++) {int c;if (p == (command_buf + cmd_size)) {int cur_size = cmd_size;cmd_size *= 2;command_buf = (char *)realloc(command_buf, cmd_size);if (!command_buf)exit (1);p = command_buf + cur_size;}c = fgetc(file);if (c == EOF || c == '\0') {*p = '\0';break;} else {*p = c;}}if (strlen(command_buf) == 0) {okay = 0;break;}p = strrchr(command_buf,'/');p = p ? p+1 : command_buf;if (strncmp(p, comm, COMM_LEN-1) == 0) {okay = 1;command = p;break;}}(void) fclose(file);if (exact && !okay){if (verbose)fprintf (stderr, _("killall: skipping partial match %s(%d)\n"),comm, pid_table[i]);continue;}got_long = okay;}/* mach by process name */for (j = 0; j < names; j++){if (reg){if (regexec (®list[j], got_long ? command : comm, 0, NULL, 0) != 0)continue;}else /* non-regex */{if ( younger_than && process_age_sec && (process_age_sec > younger_than ) )continue;if ( older_than && process_age_sec && (process_age_sec < older_than ) )continue;if (!sts[j].st_dev){if (length != COMM_LEN - 1 || name_len[j] < COMM_LEN - 1){if (ignore_case == 1){if (strcasecmp (namelist[j], comm))continue;}else{if (strcmp(namelist[j], comm))continue;}}else{if (ignore_case == 1){if (got_long ? strcasecmp (namelist[j], command) :strncasecmp (namelist[j], comm, COMM_LEN - 1))continue;}else{if (got_long ? strcmp (namelist[j], command) :strncmp (namelist[j], comm, COMM_LEN - 1))continue;}}}else{int ok = 1;if (asprintf (&path, PROC_BASE "/%d/exe", pid_table[i]) < 0)continue;if (stat (path, &st) < 0) ok = 0;else if (sts[j].st_dev != st.st_dev ||sts[j].st_ino != st.st_ino){/* maybe the binary has been modified and std[j].st_ino* is not reliable anymore. We need to compare paths.*/size_t len = strlen(namelist[j]);char *linkbuf = malloc(len + 1);if (!linkbuf ||readlink(path, linkbuf, len + 1) != len ||memcmp(namelist[j], linkbuf, len))ok = 0;free(linkbuf);}free(path);if (!ok)continue;}} /* non-regex */found_name = j;break;} if (names && found_name==-1)continue; /* match by process name faild *//* check for process group */if (!process_group)id = pid_table[i];else{int j;id = getpgid (pid_table[i]);pgids[i] = id;if (id < 0){fprintf (stderr, "killall: getpgid(%d): %s\n",pid_table[i], strerror (errno));}for (j = 0; j < i; j++)if (pgids[j] == id)break;if (j < i)continue;} if (interactive && !ask (comm, id, signal))continue;if (kill (process_group ? -id : id, signal) >= 0){if (verbose)fprintf (stderr, _("Killed %s(%s%d) with signal %d\n"), got_long ? command :comm, process_group ? "pgid " : "", id, signal);if (found_name >= 0)/* mark item of namelist */found |= 1 << found_name;pid_killed[pids_killed++] = id;}else if (errno != ESRCH || interactive)fprintf (stderr, "%s(%d): %s\n", got_long ? command :comm, id, strerror (errno));}if (!quiet)for (i = 0; i < names; i++)if (!(found & (1 << i)))fprintf (stderr, _("%s: no process found\n"), namelist[i]);if (names)/* killall returns a zero return code if at least one process has * been killed for each listed command. */error = found == ((1 << (names - 1)) | ((1 << (names - 1)) - 1)) ? 0 : 1;else/* in nameless mode killall returns a zero return code if at least * one process has killed */error = pids_killed ? 0 : 1;/** We scan all (supposedly) killed processes every second to detect dead* processes as soon as possible in order to limit problems of race with* PID re-use.*/while (pids_killed && wait_until_dead){for (i = 0; i < pids_killed;){if (kill (process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 &&errno == ESRCH){pid_killed[i] = pid_killed[--pids_killed];continue;}i++;}sleep (1); /* wait a bit longer */}return error;
}static void
usage (const char *msg)
{if (msg != NULL)fprintf(stderr, "%s\n", msg);
#ifdef WITH_SELINUXfprintf(stderr, _("Usage: killall [-Z CONTEXT] [-u USER] [ -eIgiqrvw ] [ -SIGNAL ] NAME...\n"));
#else /*WITH_SELINUX*/fprintf(stderr, _("Usage: killall [OPTION]... [--] NAME...\n"));
#endif /*WITH_SELINUX*/fprintf(stderr, _(" killall -l, --list\n"" killall -V, --version\n\n"" -e,--exact require exact match for very long names\n"" -I,--ignore-case case insensitive process name match\n"" -g,--process-group kill process group instead of process\n"" -y,--younger-than kill processes younger than TIME\n"" -o,--older-than kill processes older than TIME\n" " -i,--interactive ask for confirmation before killing\n"" -l,--list list all known signal names\n"" -q,--quiet don't print complaints\n"" -r,--regexp interpret NAME as an extended regular expression\n"" -s,--signal SIGNAL send this signal instead of SIGTERM\n"" -u,--user USER kill only process(es) running as USER\n"" -v,--verbose report if the signal was successfully sent\n"" -V,--version display version information\n"" -w,--wait wait for processes to die\n"));
#ifdef WITH_SELINUXfprintf(stderr, _(" -Z,--context REGEXP kill only process(es) having context\n"" (must precede other arguments)\n"));
#endif /*WITH_SELINUX*/fputc('\n', stderr);exit(1);
}void print_version()
{fprintf(stderr, "killall (PSmisc) %s\n", VERSION);fprintf(stderr, _("Copyright (C) 1993-2012 Werner Almesberger and Craig Small\n\n"));fprintf(stderr, _("PSmisc comes with ABSOLUTELY NO WARRANTY.\n""This is free software, and you are welcome to redistribute it under\n""the terms of the GNU General Public License.\n""For more information about these matters, see the files named COPYING.\n"));
}static int
have_proc_self_stat (void)
{char filename[128];struct stat isproc;pid_t pid = getpid();snprintf(filename, sizeof(filename), PROC_BASE"/%d/stat", (int) pid);return stat(filename, &isproc) == 0;
}int
main (int argc, char **argv)
{char *name;int sig_num;int optc;int myoptind;struct passwd *pwent = NULL;char yt[16];char ot[16];//int optsig = 0;struct option options[] = {{"exact", 0, NULL, 'e'},{"ignore-case", 0, NULL, 'I'},{"process-group", 0, NULL, 'g'},{"younger-than", 1, NULL, 'y'},{"older-than", 1, NULL, 'o'},{"interactive", 0, NULL, 'i'},{"list-signals", 0, NULL, 'l'},{"quiet", 0, NULL, 'q'},{"regexp", 0, NULL, 'r'},{"signal", 1, NULL, 's'},{"user", 1, NULL, 'u'},{"verbose", 0, NULL, 'v'},{"wait", 0, NULL, 'w'},
#ifdef WITH_SELINUX{"context", 1, NULL, 'Z'},
#endif /*WITH_SELINUX*/{"version", 0, NULL, 'V'},{0,0,0,0 }};/* Setup the i18n */
#ifdef ENABLE_NLSsetlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);
#endif
#ifdef WITH_SELINUXsecurity_context_t scontext = NULL;regex_t scontext_reg;if ( argc < 2 ) usage(NULL); /* do the obvious thing... */
#endif /*WITH_SELINUX*/name = strrchr (*argv, '/');if (name)name++;elsename = *argv;sig_num = SIGTERM;opterr = 0;
#ifdef WITH_SELINUXwhile ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VI",options,NULL)) != -1) {
#elsewhile ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVI",options,NULL)) != -1) {
#endifswitch (optc) {case 'e':exact = 1;break;case 'g':process_group = 1;break;case 'y':strncpy(yt, optarg, 16);yt[15] = '\0';if ( 0 >= (younger_than = parse_time_units(yt) ) )usage(_("Invalid time format"));break;case 'o':strncpy(ot, optarg, 16);ot[15] = '\0';if ( 0 >= (older_than = parse_time_units(ot) ) )usage(_("Invalid time format"));break;case 'i':interactive = 1;break;case 'l':list_signals();return 0;break;case 'q':quiet = 1;break;case 'r':reg = 1;break;case 's':sig_num = get_signal (optarg, "killall");break;case 'u':if (!(pwent = getpwnam(optarg))) {fprintf (stderr, _("Cannot find user %s\n"), optarg);exit (1);}break;case 'v':verbose = 1;break;case 'w':wait_until_dead = 1;break;case 'I':/* option check is optind-1 but sig name is optind */if (strcmp(argv[optind-1],"-I") == 0 || strncmp(argv[optind-1],"--",2) == 0) {ignore_case = 1;} else {sig_num = get_signal (argv[optind]+1, "killall");}break;case 'V':/* option check is optind-1 but sig name is optind */if (strcmp(argv[optind-1],"-V") == 0 || strncmp(argv[optind-1],"--",2) == 0) {print_version();return 0;}sig_num = get_signal (argv[optind]+1, "killall");break;
#ifdef WITH_SELINUXcase 'Z': if (is_selinux_enabled()>0) {scontext=optarg;if (regcomp(&scontext_reg, scontext, REG_EXTENDED|REG_NOSUB) != 0) {fprintf(stderr, _("Bad regular expression: %s\n"), scontext);exit (1);}} else fprintf(stderr, "Warning: -Z (--context) ignored. Requires an SELinux enabled kernel\n");break;
#endif /*WITH_SELINUX*/case '?':/* Signal names are in uppercase, so check to see if the argv* is upper case */if (argv[optind-1][1] >= 'A' && argv[optind-1][1] <= 'Z') {sig_num = get_signal (argv[optind-1]+1, "killall");} else {/* Might also be a -## signal too */if (argv[optind-1][1] >= '0' && argv[optind-1][1] <= '9') {sig_num = atoi(argv[optind-1]+1);} else {usage(NULL);}}break;}}myoptind = optind;
#ifdef WITH_SELINUXif ((argc - myoptind < 1) && pwent==NULL && scontext==NULL)
#elseif ((argc - myoptind < 1) && pwent==NULL)
#endifusage(NULL);if (argc - myoptind > MAX_NAMES) {fprintf (stderr, _("killall: Maximum number of names is %d\n"),MAX_NAMES);exit (1);}if (!have_proc_self_stat()) {fprintf (stderr, _("killall: %s lacks process entries (not mounted ?)\n"),PROC_BASE);exit (1);}argv = argv + myoptind;/*printf("sending signal %d to procs\n", sig_num);*/
#ifdef WITH_SELINUXreturn kill_all(sig_num,argc - myoptind, argv, pwent, scontext ? &scontext_reg : NULL);
#else /*WITH_SELINUX*/return kill_all(sig_num,argc - myoptind, argv, pwent);
#endif /*WITH_SELINUX*/
}
kill 代码关键点:kill 调用
/** Copyright (c) 1988, 1993, 1994* The Regents of the University of California. 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.* 3. All advertising materials mentioning features or use of this software* must display the following acknowledgement:* This product includes software developed by the University of* California, Berkeley and its contributors.* 4. Neither the name of the University nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.*/
/** oct 5 1994 -- almost entirely re-written to allow for process names.* modifications (c) salvatore valente <svalente@mit.edu>* may be used / modified / distributed under the same terms as the original.** 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>* - added Native Language Support** 1999-11-13 aeb Accept signal numers 128+s.**/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> /* for isdigit() */
#include <unistd.h>
#include <signal.h>#include "c.h"
#include "nls.h"
#include "closestream.h"
#include "procutils.h"
#include "strutils.h"
#include "ttyutils.h"
#include "xalloc.h"struct signv {const char *name;int val;
} sys_signame[] = {/* POSIX signals */{ "HUP", SIGHUP }, /* 1 */{ "INT", SIGINT }, /* 2 */{ "QUIT", SIGQUIT }, /* 3 */{ "ILL", SIGILL }, /* 4 */
#ifdef SIGTRAP{ "TRAP", SIGTRAP }, /* 5 */
#endif{ "ABRT", SIGABRT }, /* 6 */
#ifdef SIGIOT{ "IOT", SIGIOT }, /* 6, same as SIGABRT */
#endif
#ifdef SIGEMT{ "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */
#endif
#ifdef SIGBUS{ "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
#endif{ "FPE", SIGFPE }, /* 8 */{ "KILL", SIGKILL }, /* 9 */{ "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */{ "SEGV", SIGSEGV }, /* 11 */{ "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */{ "PIPE", SIGPIPE }, /* 13 */{ "ALRM", SIGALRM }, /* 14 */{ "TERM", SIGTERM }, /* 15 */
#ifdef SIGSTKFLT{ "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */
#endif{ "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
#ifdef SIGCLD{ "CLD", SIGCLD }, /* same as SIGCHLD (mips) */
#endif{ "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */{ "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */{ "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */{ "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */{ "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
#ifdef SIGURG{ "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
#endif
#ifdef SIGXCPU{ "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
#endif
#ifdef SIGXFSZ{ "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
#endif
#ifdef SIGVTALRM{ "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
#endif
#ifdef SIGPROF{ "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
#endif
#ifdef SIGWINCH{ "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
#endif
#ifdef SIGIO{ "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
#endif
#ifdef SIGPOLL{ "POLL", SIGPOLL }, /* same as SIGIO */
#endif
#ifdef SIGINFO{ "INFO", SIGINFO }, /* 29 (alpha) */
#endif
#ifdef SIGLOST{ "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */
#endif
#ifdef SIGPWR{ "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
#endif
#ifdef SIGUNUSED{ "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */
#endif
#ifdef SIGSYS{ "SYS", SIGSYS }, /* 31 (mips,alpha,sparc*) */
#endif
};static int arg_to_signum (char *arg, int mask);
static void nosig (char *name);
static void printsig (int sig);
static void printsignals (FILE *fp, int pretty);
static int usage (int status);
static int kill_verbose (char *procname, int pid, int sig);#ifdef HAVE_SIGQUEUE
static int use_sigval;
static union sigval sigdata;
#endifint main (int argc, char *argv[])
{int errors, numsig, pid;char *ep, *arg;int do_pid, do_kill, check_all;setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);atexit(close_stdout);numsig = SIGTERM;do_pid = (! strcmp (program_invocation_short_name, "pid")); /* Yecch */do_kill = 0;check_all = 0;/* loop through the arguments.actually, -a is the only option can be used with other options.`kill' is basically a one-option-at-most program. */for (argc--, argv++; argc > 0; argc--, argv++) {arg = *argv;if (*arg != '-') {break;}if (! strcmp (arg, "--")) {argc--, argv++;break;}if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||! strcmp (arg, "--version")) {printf(UTIL_LINUX_VERSION);return EXIT_SUCCESS;}if (! strcmp (arg, "-h") || ! strcmp (arg, "--help"))return usage(EXIT_FAILURE);if (! strcmp (arg, "-a") || ! strcmp (arg, "--all")) {check_all++;continue;}if (! strcmp (arg, "-l") || ! strcmp (arg, "--list")) {if (argc < 2) {printsignals (stdout, 0);return EXIT_SUCCESS;}if (argc > 2)return usage (EXIT_FAILURE);/* argc == 2, accept "kill -l $?" */arg = argv[1];if ((numsig = arg_to_signum (arg, 1)) < 0)errx(EXIT_FAILURE, _("unknown signal: %s"), arg);printsig (numsig);return EXIT_SUCCESS;}/* for compatibility with procps kill(1) */if (! strncmp (arg, "--list=", 7) || ! strncmp (arg, "-l=", 3)) {char *p = strchr(arg, '=') + 1;if ((numsig = arg_to_signum(p, 1)) < 0)errx(EXIT_FAILURE, _("unknown signal: %s"), p);printsig (numsig);return EXIT_SUCCESS;}if (! strcmp (arg, "-L") || ! strcmp (arg, "--table")) {printsignals (stdout, 1);return EXIT_SUCCESS;}if (! strcmp (arg, "-p") || ! strcmp (arg, "--pid")) {do_pid++;if (do_kill)return usage (EXIT_FAILURE);continue;}if (! strcmp (arg, "-s") || ! strcmp (arg, "--signal")) {if (argc < 2) {return usage (EXIT_FAILURE);}do_kill++;if (do_pid)return usage (EXIT_FAILURE);argc--, argv++;arg = *argv;if ((numsig = arg_to_signum (arg, 0)) < 0) {nosig (arg);return EXIT_FAILURE;}continue;}if (! strcmp (arg, "-q") || ! strcmp (arg, "--queue")) {if (argc < 2)return usage (EXIT_FAILURE);argc--, argv++;arg = *argv;
#ifdef HAVE_SIGQUEUEsigdata.sival_int = strtos32_or_err(arg, _("invalid sigval argument"));use_sigval = 1;
#endifcontinue;}/* `arg' begins with a dash but is not a known option.so it's probably something like -HUP, or -1/-ntry to deal with it.-n could be signal n, or pid -n (i.e. process group n).In case of doubt POSIX tells us to assume a signal.If a signal has been parsed, assume it's a pid, break */if (do_kill)break;arg++;if ((numsig = arg_to_signum (arg, 0)) < 0) {return usage (EXIT_FAILURE);}do_kill++;if (do_pid)return usage (EXIT_FAILURE);continue;}if (! *argv) {return usage (EXIT_FAILURE);}if (do_pid) {numsig = -1;}/* we're done with the options.the rest of the arguments should be process ids and names.kill them. */for (errors = 0; (arg = *argv) != NULL; argv++) {pid = strtol (arg, &ep, 10);if (! *ep)errors += kill_verbose (arg, pid, numsig);else {struct proc_processes *ps = proc_open_processes();int ct = 0;if (!ps)continue;if (!check_all)proc_processes_filter_by_uid(ps, getuid());proc_processes_filter_by_name(ps, arg);while (proc_next_pid(ps, &pid) == 0) {errors += kill_verbose(arg, pid, numsig);ct++;}if (!ct) {errors++;warnx (_("cannot find process \"%s\""), arg);}proc_close_processes(ps);}}if (errors != 0)errors = EXIT_FAILURE;return errors;
}#ifdef SIGRTMIN
static int rtsig_to_signum(char *sig)
{int num, maxi = 0;char *ep = NULL;if (strncasecmp(sig, "min+", 4) == 0)sig += 4;else if (strncasecmp(sig, "max-", 4) == 0) {sig += 4;maxi = 1;}if (!isdigit(*sig))return -1;errno = 0;num = strtol(sig, &ep, 10);if (!ep || sig == ep || errno || num < 0)return -1;num = maxi ? SIGRTMAX - num : SIGRTMIN + num;if (num < SIGRTMIN || num > SIGRTMAX)return -1;return num;
}
#endifstatic int signame_to_signum (char *sig)
{size_t n;if (! strncasecmp (sig, "sig", 3))sig += 3;#ifdef SIGRTMIN/* RT signals */if (!strncasecmp(sig, "rt", 2))return rtsig_to_signum(sig + 2);
#endif/* Normal sugnals */for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {if (! strcasecmp (sys_signame[n].name, sig))return sys_signame[n].val;}return (-1);
}static int arg_to_signum (char *arg, int maskbit)
{int numsig;char *ep;if (isdigit (*arg)) {numsig = strtol (arg, &ep, 10);if (numsig >= NSIG && maskbit && (numsig & 128) != 0)numsig -= 128;if (*ep != 0 || numsig < 0 || numsig >= NSIG)return (-1);return (numsig);}return signame_to_signum (arg);
}static void nosig (char *name)
{warnx (_("unknown signal %s; valid signals:"), name);printsignals (stderr, 1);
}static void printsig (int sig)
{size_t n;for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {if (sys_signame[n].val == sig) {printf ("%s\n", sys_signame[n].name);return;}}
#ifdef SIGRTMINif (sig >= SIGRTMIN && sig <= SIGRTMAX) {printf ("RT%d\n", sig - SIGRTMIN);return;}
#endifprintf("%d\n", sig);
}#define FIELD_WIDTH 11
static void pretty_print_signal(FILE *fp, size_t term_width, size_t *lpos,int signum, const char *name)
{if (term_width < (*lpos + FIELD_WIDTH)) {fputc ('\n', fp);*lpos = 0;}*lpos += FIELD_WIDTH;fprintf (fp, "%2d %-8s", signum, name);
}static void printsignals (FILE *fp, int pretty)
{size_t n, lth, lpos = 0, width;if (!pretty) {for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {lth = 1+strlen(sys_signame[n].name);if (lpos+lth > 72) {fputc ('\n', fp);lpos = 0;} else if (lpos)fputc (' ', fp);lpos += lth;fputs (sys_signame[n].name, fp);}
#ifdef SIGRTMINfputs (" RT<N> RTMIN+<N> RTMAX-<N>", fp);
#endiffputc ('\n', fp);return;}/* pretty print */width = get_terminal_width();if (width == 0)width = 72;elsewidth -= 1;for (n = 0; n < ARRAY_SIZE(sys_signame); n++)pretty_print_signal(fp, width, &lpos,sys_signame[n].val, sys_signame[n].name);#ifdef SIGRTMINpretty_print_signal(fp, width, &lpos, SIGRTMIN, "RTMIN");pretty_print_signal(fp, width, &lpos, SIGRTMAX, "RTMAX");
#endiffputc ('\n', fp);
}static int usage(int status)
{FILE *out = (status == 0 ? stdout : stderr);fputs(USAGE_HEADER, out);fprintf(out, _(" %s [options] <pid|name> [...]\n"), program_invocation_short_name);fputs(USAGE_OPTIONS, out);fputs(_(" -a, --all do not restrict the name-to-pid conversion to processes\n"" with the same uid as the present process\n"), out);fputs(_(" -s, --signal <sig> send specified signal\n"), out);fputs(_(" -q, --queue <sig> use sigqueue(2) rather than kill(2)\n"), out);fputs(_(" -p, --pid print pids without signaling them\n"), out);fputs(_(" -l, --list [=<signal>] list signal names, or convert one to a name\n"), out);fputs(_(" -L, --table list signal names and numbers\n"), out);fputs(USAGE_SEPARATOR, out);fputs(USAGE_HELP, out);fputs(USAGE_VERSION, out);fprintf(out, USAGE_MAN_TAIL("kill(1)"));return status;
}static int kill_verbose (char *procname, pid_t pid, int sig)
{int rc = 0;if (sig < 0) {printf ("%ld\n", (long)pid);return 0;}
#ifdef HAVE_SIGQUEUEif (use_sigval)rc = sigqueue(pid, sig, sigdata);else
#endifrc = kill (pid, sig);if (rc < 0) {warn(_("sending signal to %s failed"), procname);return 1;}return 0;
}
相关文章:
kill 与killall
【查询命令所属软件包】 rpm -qf /usr/bin/killall psmisc-22.20-15.el7.x86_64 rpm -qf /usr/bin/kill util-linux-2.23.2-65.el7_9.1.x86_64 【命令参数】 killallkill -e,--exact require exact match for very long names -I,--ignore-case case insensi…...
【加密】开发常见加密类型
相关加密方法具体使用,查阅工具官方; 对称加密(单密钥加密):常用于传输数据加密 信息的加密和解密使用相同密钥; 常见对称算法: DES(Data Encryption Standard)&#x…...

数据结构之基:从根儿上了解数据结构的特性
学好数据结构,就等于成功了一半。 程序是对现实的模拟,现实是由时间和空间组成的,高效的人都是用最少的时间、最少的空间来做最伟大的事,程序亦是如此。我们要选择最合理的算法和最合理的数据结构,来写最好的代码&…...
C++ 枚举详解
C 枚举详解 C 枚举类型详解 枚举类型的定义格式为: enum <类型名> {<枚举常量表>};关键字enum——指明其后的标识符是一个枚举类型的名字枚举常量表——由枚举常量构成。“枚举常量"或称"枚举成员”,是以标识符形式表示的整型量&…...

【vue3】ref , reactive ,toRef ,toRefs 使用和理解
这篇文章是基于理解写的,仅助于理解,如有任何错误之处,感谢指正! 文章目录一.ref的使用1. ref的功能主要有两个:2.使用ref注意事项二.reactive的使用三.使用ref 和 reactive 实现双向数据绑定四.toRef 和 toRefs 的使用…...

fastadmin:如何点击按钮弹出存在的指定页面的弹窗
样式:方法一:直接使用超链接进行操作{:url(popup/purchase/itemno)}:表示地址信息btn-dialog:表示弹窗<a href"{:url(popup/purchase/itemno)}" title"跳转第三方" class"btn btn-success btn-dialog…...

【storybook】你需要一款能在独立环境下开发组件并生成可视化控件文档的框架吗?(三)
storybook插件addons核心插件插件APIargTypes写文档组件注释法MDX生成在线可视化UI文档上一篇: https://blog.csdn.net/tuzi007a/article/details/129194267插件addons 插件用于增强storybook的UI功能。 核心插件 storybook/addon-essentials 它几乎控制了整个s…...

Android源码分析 —— Activity栈管理(基于Android8)
0. 写在前面 本文基于 Android8.0源码,和Android9.0大同小异,但和Android10.0差别非常大!新版改用ATM来管理Activity的启动,Activity的生命周期也通过XXXItem来管理。由于我分析的Activity启动流程就是基于Android8/9的ÿ…...

Python实现贝叶斯优化器(Bayes_opt)优化支持向量机分类模型(SVC算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景贝叶斯优化器(BayesianOptimization) 是一种黑盒子优化器,用来寻找最优参数。贝叶斯优化器是基…...

【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1)
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...

FFmpeg/OpenCV 实现全屏斜体水印
实现思路 🤔 基于ffmpeg,画布的方式,创建画布 -> 水印 -> 旋转 -> 抠图 -> 叠加到图像上基于ffmpeg,旋转图片的方式,填充 -> 水印 -> 顺时针旋转 -> 逆时针旋转 -> 截图基于opencvÿ…...

Calendar计算两个时间之间相差几个月
目录说明说明 计算两个时间之间相差几个月: public int getMonth(String startDt, String endDt) { int month 0;try {SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Calendar satrt Calendar.getInstance();Calendar end Cal…...

FPGA基础知识
FPGA是在PAL、PLA和CPLD等可编程器件的基础上进一步发展起来的一种更复杂的可编程逻辑器件。它是ASIC领域中的一种半定制电路,既解决了定制电路的不足,又克服了原有可编程器件门电路有限的缺点。 由于FPGA需要被反复烧写,它实现组合逻辑的基…...
C语言运算符逻辑运算符位运算符
逻辑运算符 下表显示了 C 语言支持的所有关系逻辑运算符。假设变量 A 的值为 1,变量 B 的值为 0,则: 运算符 描述 实例 && 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A && B) 为假。 || 称为逻辑…...

机器学习:基于主成分分析(PCA)对数据降维
机器学习:基于主成分分析(PCA)对数据降维 作者:AOAIYI 作者简介:Python领域新星作者、多项比赛获奖者:AOAIYI首页 😊😊😊如果觉得文章不错或能帮助到你学习,可…...

软件测试之测试模型
软件测试的发展 1960年代是调试时期(测试即调试) 1960年 - 1978年 论证时期(软件测试是验证软件是正确的)和 1979年 - 1982年 破坏性测试时期(为了发现错误而执行程序的过程) 1983年起,软件测…...

【项目精选】网络考试系统的设计与实现(源码+视频+论文)
点击下载源码 网络考试系统主要用于实现高校在线考试,基本功能包括:自动组卷、试卷发布、试卷批阅、试卷成绩统计等。本系统结构如下: (1)学生端: 登录模块:登录功能; 网络考试模块…...

Python近红外光谱分析与机器学习、深度学习方法融合实践技术
、 第一n入门基础【理论讲解与案 1、Python环境搭建( 下载、安装与版本选择)。 2、如何选择Python编辑器?(IDLE、Notepad、PyCharm、Jupyter…) 3、Python基础(数据类型和变量、字符串和编码、list和tu…...

实例7:树莓派呼吸灯
实例7:树莓派呼吸灯 实验目的 通过背景知识学习,了解digital与analog的区别。通过GPIO对外部LED灯进行呼吸控制,熟悉PWM技术。 实验要求 通过python编程,用GPIO控制LED灯,使之亮度逐渐增大,随后减小&am…...

java 接口 详解
目录 一、概述 1.介绍 : 2.定义 : 二、特点 1.接口成员变量的特点 : 2.接口成员方法的特点 : 3.接口构造方法的特点 : 4.接口创建对象的特点 : 5.接口继承关系的特点 : 三、应用 : 1.情景 : 2.多态 : ①多态的传递性 : ②关于接口的多态参数和多态…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...