Craig Small: Sending data in a signal
The well-known kill system call has been around for decades and is used to send a signal to another process. The most common use is to terminate or kill another process by sending the KILL or TERM signal but it can be used for a form of IPC, usually around giving the other process a kick to do something.
One thing that isn t as well known is besides sending a signal to a process, you can send some data to it. This can either be an integer or a pointer and uses similar semantics to the known kill and signal handler. I came across this when there was a merge request for procps. The main changes are using sigqueue instead of kill in the sender and using a signal action not a signal handler in the receiver.
To illustrate this feature, I have a small set of programs called sender and receiver that will pass an integer between them.
The Sender
The sender program is extremely simple, use a random(ish) from time masked to two bytes, put it in the required union and send the lot to sendqueue.
# include <signal.h>
# include <stdlib.h>
# include <stdio.h>
# include <time.h>
int main(int argc, char **argv)
union sigval sigval;
pid_t pid;
if (argc < 2 (pid = atoi(argv[1])) < 0)
return EXIT_FAILURE;
sigval.sival_int = time(NULL) & 0xff;
printf("sender: sending %d to PID %d\n",
sigval.sival_int, pid);
sigqueue(pid, SIGUSR1, sigval);
return EXIT_SUCCESS;
The key lines are 13 and 16 where the random (ish) integer is stored in the sigval union and then sent to the other process with the sigqueue.
The receiver
The receiver just sets up the signal handler, sends its PID (so I know what to tell the sender) and sits in a sleeping loop.
# include <stdio.h>
# include <stdlib.h>
# include <sys/types.h>
# include <unistd.h>
# include <signal.h>
void signal_handler(int signum, siginfo_t *siginfo, void *ucontext)
if (signum != SIGUSR1) return;
if (siginfo->si_code != SI_QUEUE) return;
printf("receiver: Got value %d\n",
siginfo->si_int);
int main(int argc, char **argv)
pid_t pid = getpid();
struct sigaction signal_action;
printf("receiver: PID is %d\n", pid);
signal_action.sa_sigaction = signal_handler;
sigemptyset (&signal_action.sa_mask);
signal_action.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &signal_action, NULL);
while(1) sleep(100);
return EXIT_SUCCESS;
Lines 16-26 setup the signal handler. The main difference here is SA_SIGINFO used for the signal flags and sigaction references a sa_sigaction function rather than sa_handler.
We need to use a different function because the sigaction only is passed the signal number but we need more information, including the integer that the sender process stored in sigval.
Lines 7-14 are the signal handler function itself. It first checks that the receiver process got the correct signal (SIGUSR1 in this case) and that we got this signal from sigqueue because the type is SI_QUEUE. Checking the type of signal is important because different signals give you different data. For example, if you signalled this process with kill then si_int is undefined.
The result
As a proof of concept, the results are not terribly exciting. We see the sender say what it will be sending and the receiver saying it got it. It was useful to get some results, especially when things went wrong.
$ ./receiver & [1] 370216 receiver: PID is 370216 $ ./sender 370216 sender: sending 133 to (gdPID 370216 receiver: Got value 133Gotchas While testing the two process there was two gotchas I encountered. GDB and the siginfo structure The sigaction manual page shows a simple siginfo_t structure, however when looking at what is passed to the signal handler, it s much more complicated.
(gdb) p *siginfo
$2 = si_signo = 10, si_errno = 0, si_code = -1, __pad0 = 0, _sifields = _pad = 371539, 1000, 11, 32766, 0 <repeats 24 times> , _kill = si_pid = 371539, si_uid = 1000 , _timer = si_tid = 371539,
si_overrun = 1000, si_sigval = sival_int = 11, sival_ptr = 0x7ffe0000000b , _rt = si_pid = 371539, si_uid = 1000, si_sigval = sival_int = 11, sival_ptr = 0x7ffe0000000b , _sigchld =
si_pid = 371539, si_uid = 1000, si_status = 11, si_utime = 0, si_stime = 0 , _sigfault = si_addr = 0x3e80005ab53, si_addr_lsb = 11, _bounds = _addr_bnd = _lower = 0x0, _upper = 0x0 , _pkey = 0 ,
_sigpoll = si_band = 4294967667539, si_fd = 11 , _sigsys = _call_addr = 0x3e80005ab53, _syscall = 11, _arch = 32766
(gdb) p siginfo->_sifields._rt.si_sigval.sival_int
$3 = 11
So the integer is stored in a union in a structure in a structure. Much harder to find than just simply sival_int.
The pointer is just a pointer
So perhaps sending an integer is not enough. The sigval is a union with an integer and a pointer. Could a string be sent instead? I changed line 13 of the sender so it used a string instead of an integer.
sigval.sival_ptr = "Hello, World!"The receiver needed a minor adjustment to print out the string. I tried this and the receiver segmentation faulted. What was going on? The issue is the set of system calls does a simple passing of the values. So if the sender sends a pointer to a string located at 0x1234567 then the receiver will have a pointer to the same location. When the receiver tries to dereference the sival_ptr, it is pointing to memory that is not owned by it but by another process (the sender) so it segmentation faults. The solution would be to use shared memory between the processes. The signal queue would then use the pointer to the shared memory and, in theory, all would be well.
I never thought I could finish a game which is completely linear, has hardly any interaction necessary, hardly any riddles, no fighting.
A friend recently pointed me at a
The games plays completely in the now deserted house of the family Finch. The youngest member of the family returns with a key to the house and uncovers the stories of her family. This is about all that is happening in the game. And it is so well done that I couldn t stop playing (wouldn t it be for my daughter interrupting me), and leaves you with the feeling to replay as soon as possible. The graphics are very well done, beautiful scenery, lots of love to details. The story progresses by walking (completely linearly) through the house, and text fragments appearing around you, telling part of the story, small hints, little secrets, everything that makes up a tangible set of family memories.
Exploring the house filled with locked rooms sealed as shrines for the deceased members of the family, Edith uncovers one by one the final moments of her family members, a family seemingly cursed. In these stories the player dives into the world and playing the role of the family members, re-living events of the past.
As I wrote in the beginning don t expect fights, don t expect riddles, but be prepared for an emotional roller coaster, for a deep dive into a well written family history with lots of weird twists. An absolute great game with a playing time of around 2h.
Back in early 2018, the
Since the two early releases, I made a few changes to e.g. the analysis of package checks and their summaries (but never pushed these) as well as a few usability enhancements. This release regroups these.
The release is summarised in the NEWS entry:
The Debian Project Leader elections just finished and the winner is Jonathan Carter!
His term as project leader starts next Tuesday April 21st and expires on April 20th 2021.
Of a total of 1011 developers, 339 developers voted using the
I m working on trying to get a Qualcomm
If you never heard of the 10x engineer myth, it's a pretty great concept. It boils down to the idea where an engineer could be 10x more efficient than a random engineer. I find this fantastically twisted.Last week, I sat and chat with Alexis Monville in 
Today at the ACLU, we
Welcome to gambaru.de. Here is my monthly report (+ the first week in April) that covers what I have been doing for Debian. If you re interested in Java, Games and LTS topics, this might be interesting for you.
I am sure I am not the only one who will remember March 2020 in the future as a month nobody was really fond of. I was mostly occupied with non-Debian work and managed to get ill in the same week I wanted to celebrate my birthday but it didn t matter anyway because of ehm quarantine and social distancing. Maybe next year March will be great again.
TLDR: