How can I tell in Linux which process sent my process a signal
Two Linux-specific methods are SA_SIGINFO
and signalfd()
, which allows programs to receive very detailed information about signals sent, including the sender's PID.
Call
sigaction()
and pass to it astruct sigaction
which has the desired signal handler insa_sigaction
and theSA_SIGINFO
flag insa_flags
set. With this flag, your signal handler will receive three arguments, one of which is asiginfo_t
structure containing the sender's PID and UID.Call
signalfd()
and readsignalfd_siginfo
structures from it (usually in some kind of a select/poll loop). The contents will be similar tosiginfo_t
.
Which one to use depends on how your application is written; they probably won't work well outside plain C, and I wouldn't have any hope of getting them work in Java. They are also unportable outside Linux. They also likely are the Very Wrong Way of doing what you are trying to achieve.
Finding the process which sent signal in c
You set up your signal handler with sigaction
using the SA_SIGINFO
flag. Your handler will accept a parameter of siginfo_t
. Within the siginfo_t struct is the field si_pid
. This is the process id of the sending process. Match that against the child's ppid().
What order are signals sent to a process group in Linux?
I've been browsing the Linux kernel source and I think I have the answer. When sending a signal via kill, Linux iterates over the linked list held in the pid structure, which contains all the tasks that use that PID. I believe that this means it iterates over processes in a group in the reverse order they were forked() as the PID is added to the linked list with hlist_add_head_rcu, which inserts it at the head. I don't think this behavior should be relied on though, as they could change it in several ways.
Linux C: upon receiving a signal, is it possible to know the PID of the sender?
Yes, if you use the sigaction()
call to set up your signal handler instead of signal
. Doing so will let you set up a signal handler that takes three parameters:
- An
int
, for the signal number (just likesignal
) - A
siginfo_t *
, which is a structure containing all sorts of information about the source of the signal, including the pid of the sender if applicable. (It also includes some information about the cause of the signal for automatic signals likeSIGSEGV
.) - A
ucontext_t *
, which has to do with which thread got the signal. Mostly ignorable.
When several signals arrive at a process, what is the order between the process handling the signals?
SIGCONT has special semantics.
Regardless of whether SIGCONT is caught, is ignored, or has default disposition, its generation will clear all pending stop signals and resume execution of a stopped process. [IEEE Std 1003.1-2017] Again, this resumption happens before any other signals are delivered, and even before SIGCONT's handler (if any) is invoked.
(This special “dispositionless” semantic makes sense. In order for a process to execute a signal handler, the process must itself be executing.)
POSIX is clearer than APUE here, saying that "[t]he default action for SIGCONT is to resume execution at the point where the process was stopped, after first handling any pending unblocked signals."
As others have mentioned, the actual order in which pending signals are delivered is implementation-specific. Linux, at least, delivers basic UNIX signals in ascending numeric order.
To demonstrate all this, consider the following code. It STOPs a process, then sends it several signals, then CONTinues it, having installed handlers for all catchable signals so we can see what is handled when:
#define _POSIX_SOURCE
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static int signals[] = { SIGSTOP, SIGURG, SIGUSR1, SIGHUP, SIGCONT, 0 };
static void
handler(int signo) {
// XXX not async-signal-safe
printf("<signal %d>\n", signo);
}
int
main(int argc, char **argv) {
int *sig = signals;
struct sigaction sa = { .sa_flags = 0, .sa_handler = handler };
sigfillset(&sa.sa_mask);
sig++; // can't catch SIGSTOP
while (*sig) {
sigaction(*sig, &sa, NULL); // XXX error check
sig++;
}
if (fork() == 0) { // XXX error check
sleep(2); // faux synchronization - let parent pause()
sig = signals;
while (*sig) {
printf("sending signal %d\n", *sig);
kill(getppid(), *sig);
sig++;
}
exit(0);
}
pause();
return 0;
}
For me, this prints
sending signal 19
sending signal 23
sending signal 10
sending signal 1
sending signal 18
<signal 1>
<signal 10>
<signal 18>
<signal 23>
Related Topics
Why Child Process Still Alive After Parent Process Was Killed in Linux
How to Have a Tcp Connection Back to the Same Port
How to Grep for the Dollar Symbol ($)
Cannot Connect to X Server :0.0 with a Qt Application
How to Install Nuget from Command Line on Linux
Splitting a File in Linux Based on Content
How to Use Ioctl() to Manipulate My Kernel Module
/Usr/Bin/Ld: Cannot Find -Llapack
Gcloud Compute Copy-Files': Permission Denied When Copying Files
Replace the First Line in a Text File by a String
Parallel Download Using Curl Command Line Utility
Bash Script: Using "Script" Command from a Bash Script for Logging a Session
Crontab Run Every 15 Minutes Except at 3Am
How to Determine the Current CPU Utilization from the Shell
Is It Ok to Use the Same Input File as Output of a Piped Command
Openshift: "Failed to Execute Control Start" on Node Application