Am 07.06.2016 um 13:21 schrieb Brendon Costa:
I am vaguely following this thread as I don't have lots of time but am interested in the process library.
I have also written a C++ process (and signals) library supporting windows/OSX/Linux/Android (for an employer though so I can't propose it for boost). It actually suprised me how many platform differences existed that needed to be worked around in writing this library compared to others I have written.
I also did something similar to Klemens if what I undertood is correct, I did a fallback scenario of send TERM if not closed within time period send a KILL. I didn't really like it though and wonder if the std::thread destructor behavior is better to std::terminate if the child is still running but not detached and treat it more like a bug to destroy an active process instance than something to rely on to close it.
Well, I don't give a timeout, it just terminates. That is, you have to explicitly call wait or join, or wait_for/wait_until if you want a timeout.
Not having a SIGTERM equivilant for windows processes bothered me as SIGKILL is just too nasty as a default as mentioned. So I looked into this quite thoroughly. For GUI processes you can easily send WM_CLOSE message to it to simulate something akin to a SIGTERM. I think I used a WM_CLOSE from memory. I know there was a choice between QUIT and CLOSE, I think CLOSE was more suitable but I cant recall the exact reason now and may be wrong.
For console processes I only found bad options. I found something that worked quite well but ended up dropping it in the end as it was not required and was super hacky IMO. I only ever wanted to SIGTERM my own processes in the end so just used a non generic solution of a named pipe to listen for signals and raise() to local process.
The GenerateConsoleCtrlEvent() comes close to doing what we want but its got the worst behaviour in how to choose who gets the signal delivered and is not sufficient (even when creating processes to detach/attach to other consoles to generate the events). In the end I followed the basic idea proposed at:
http://www.latenighthacking.com/projects/2003/sendSignal/
With extra ideas proposed in comment (20110401) and a few extra changes of my own. I got this working well in all scenarios I could think of to test on win32 and 64 up to Win7 (I think I went down to XP but cant recall for sure).
The idea is basically to use the mechanism that GenerateConsoleCtrlEvent() uses to deliver the signal, but you choose the process where to deliver it yourself instead of using the stupid rules that GenerateConsoleCtrlEvent() follows. Well, I could put each process in it's own group and just try to signal arbitrary values. But that would break the console and might not even work.
The idea is to create a new "helper" process, have it register a signal handler, raise a signal to itself and in the handler walk back the stack to find the entry point where the signal was generated. It turns out that the function where the signal was generated (I think it was kernel32!CtrlRoutine) this function has the correct prototype for CeateRemoteThread and is in the kernel32.dll so is in the same location in all processes on the system and is how GenerateConsoleCtrlEvent() is implemented.
So you basically then find the process you care about, create a remote thread in it to call the specified function and presto you end up with a SIGTERM that can be handled by a normal signal() handler in a console process.
I hope my research was useful, but this approach was not really acceptable to me and I dont think would be to the boost community. Maybe another idea might arise from it though, in which case I would love to hear about it.
It's definitely intertesting, thank you. Though you're unfortunately right, that's a bit too much hacking for a stable library.