On a raspberry pi (a recent raspian) I wrote an application that, on demand via network request, spawns an application, and on demand via different network request, kills it. The spawning mechanism is just fork/exec. Killing is done with kill(childPid, SIGQUIT). It's as a simple a piece of C++ as you'd think and it works fine.
That is, it works fine, unless I start it from /etc/rc.local. The command to start it from there is just an appropriate cd and then
and it starts up fine, receives requests fine, spawns fine (it spans an aplay, so it's trivial to tell when it works) but completely fails to kill the aplay subprocess on request. It calls kill() as normal and kill() returns 0. But aplay plays on.
I assume this is some weirdness having to do with the fact that spawning it from /etc/rc.local gives it some special behavior in fork or kill, but I don't understand what. What am I missing?
Edit: adding answers to questions. Run from /etc/rc.local with logging turned on, the application reports:
23:10:06 10-11-2019 (effectPlayer) 7: P1 64 elvenHall #command to start playing 23:10:06 10-11-2019 (sound) launched 1083: /usr/bin/aplay -q -... #what it forks/execs 23:10:10 10-11-2019 (effectPlayer) 7: X1000 #command to stop playing 23:10:10 10-11-2019 (sound) sending 3 to 1083, result 0 0 #what kill() is asked to do
Translation, it's asked to play a particular effect and spawns an aplay to handle it. It works (I hear the audio) and then I send a command to stop all playing. It successfully calls kill() on the right PID with the right signal, and kill() returns 0 with errno=0. Except aplay is still running.
When I do the same sequence from the command line, it all acts the same, except aplay actually dies.
When I swap SIGQUIT for SIGKILL, it works as expected: aplay dies regardless of how effectsPlayer is started.
I'm going to put this down to some weirdness in aplay for now. I don't like using SIGKILL - there might be important clean up being skipped. But it works...