pgrep: use sigqueue to pass value with the signal.

Based on the command line option, use 'sigqueue'
instead of 'kill' to pass the integer value with
the signal.

References:
 procps-ng/procps!32

Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
Arun Chandrasekaran 2020-04-25 13:15:06 +10:00 committed by Craig Small
parent 7f44382938
commit 89392e67a9
3 changed files with 35 additions and 5 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
procps-ng NEXT procps-ng NEXT
-------------- --------------
* kill: Pass int to signalled process merge #32 * kill: Pass int to signalled process merge #32
* pgrep: Pass int to signalled process merge #32
* pgrep: Check sanity of SG_ARG_MAX issue #152 * pgrep: Check sanity of SG_ARG_MAX issue #152
* pidof: show worker threads Redhat #1803640 * pidof: show worker threads Redhat #1803640
* ps.1: Mention stime alias issue #164 * ps.1: Mention stime alias issue #164

15
pgrep.1
View File

@ -7,7 +7,7 @@
.\" the Free Software Foundation; either version 2 of the License, or .\" the Free Software Foundation; either version 2 of the License, or
.\" (at your option) any later version. .\" (at your option) any later version.
.\" .\"
.TH PGREP "1" "2017-12-22" "procps-ng" "User Commands" .TH PGREP "1" "2020-04-24" "procps-ng" "User Commands"
.SH NAME .SH NAME
pgrep, pkill \- look up or signal processes based on name and other attributes pgrep, pkill \- look up or signal processes based on name and other attributes
.SH SYNOPSIS .SH SYNOPSIS
@ -166,6 +166,18 @@ which namespaces to match.
Match only the provided namespaces. Available namespaces: Match only the provided namespaces. Available namespaces:
ipc, mnt, net, pid, user,uts. ipc, mnt, net, pid, user,uts.
.TP .TP
\fB\-q\fR, \fB\-\-queue \fIvalue\fP
Use
.BR sigqueue(3)
rather than
.BR kill(2)
and the value argument is used to specify
an integer to be sent with the signal. If the receiving process has
installed a handler for this signal using the SA_SIGINFO flag to
.BR sigaction(2)
, then it can obtain this data via the si_value field of the
siginfo_t structure.
.TP
\fB\-V\fR, \fB\-\-version\fR \fB\-V\fR, \fB\-\-version\fR
Display version information and exit. Display version information and exit.
.TP .TP
@ -245,6 +257,7 @@ Defunct processes are reported.
.BR ps (1), .BR ps (1),
.BR regex (7), .BR regex (7),
.BR signal (7), .BR signal (7),
.BR sigqueue (3),
.BR killall (1), .BR killall (1),
.BR skill (1), .BR skill (1),
.BR kill (1), .BR kill (1),

20
pgrep.c
View File

@ -35,6 +35,7 @@
#include <regex.h> #include <regex.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
#include <stdbool.h>
/* EXIT_SUCCESS is 0 */ /* EXIT_SUCCESS is 0 */
/* EXIT_FAILURE is 1 */ /* EXIT_FAILURE is 1 */
@ -97,6 +98,8 @@ static int opt_case = 0;
static int opt_echo = 0; static int opt_echo = 0;
static int opt_threads = 0; static int opt_threads = 0;
static pid_t opt_ns_pid = 0; static pid_t opt_ns_pid = 0;
static bool use_sigqueue = false;
static union sigval sigval = {0};
static const char *opt_delim = "\n"; static const char *opt_delim = "\n";
static struct el *opt_pgrp = NULL; static struct el *opt_pgrp = NULL;
@ -132,6 +135,7 @@ static int __attribute__ ((__noreturn__)) usage(int opt)
} }
if (i_am_pkill == 1) { if (i_am_pkill == 1) {
fputs(_(" -<sig>, --signal <sig> signal to send (either number or name)\n"), fp); fputs(_(" -<sig>, --signal <sig> signal to send (either number or name)\n"), fp);
fputs(_(" -q, --queue <value> integer value to be sent with the signal\n"), fp);
fputs(_(" -e, --echo display what is killed\n"), fp); fputs(_(" -e, --echo display what is killed\n"), fp);
} }
fputs(_(" -c, --count count of matching processes\n"), fp); fputs(_(" -c, --count count of matching processes\n"), fp);
@ -695,6 +699,7 @@ static void parse_opts (int argc, char **argv)
{"echo", no_argument, NULL, 'e'}, {"echo", no_argument, NULL, 'e'},
{"ns", required_argument, NULL, NS_OPTION}, {"ns", required_argument, NULL, NS_OPTION},
{"nslist", required_argument, NULL, NSLIST_OPTION}, {"nslist", required_argument, NULL, NSLIST_OPTION},
{"queue", required_argument, NULL, 'q'},
{"runstates", required_argument, NULL, 'r'}, {"runstates", required_argument, NULL, 'r'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
@ -708,7 +713,7 @@ static void parse_opts (int argc, char **argv)
if (-1 < sig) if (-1 < sig)
opt_signal = sig; opt_signal = sig;
/* These options are for pkill only */ /* These options are for pkill only */
strcat (opts, "e"); strcat (opts, "eq:");
} else { } else {
/* These options are for pgrep only */ /* These options are for pgrep only */
strcat (opts, "lad:vw"); strcat (opts, "lad:vw");
@ -857,6 +862,10 @@ static void parse_opts (int argc, char **argv)
if (opt_nslist == NULL) if (opt_nslist == NULL)
usage ('?'); usage ('?');
break; break;
case 'q':
sigval.sival_int = atoi(optarg);
use_sigqueue = true;
break;
case 'h': case 'h':
case '?': case '?':
usage (opt); usage (opt);
@ -890,6 +899,13 @@ static void parse_opts (int argc, char **argv)
program_invocation_short_name); program_invocation_short_name);
} }
inline static int execute_kill(pid_t pid, int sig_num)
{
if (use_sigqueue)
return sigqueue(pid, sig_num, sigval);
else
return kill(pid, sig_num);
}
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
@ -911,7 +927,7 @@ int main (int argc, char **argv)
int i; int i;
int kill_count = 0; int kill_count = 0;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (kill (procs[i].num, opt_signal) != -1) { if (execute_kill (procs[i].num, opt_signal) != -1) {
if (opt_echo) if (opt_echo)
printf(_("%s killed (pid %lu)\n"), procs[i].str, procs[i].num); printf(_("%s killed (pid %lu)\n"), procs[i].str, procs[i].num);
kill_count++; kill_count++;