Sending a signal/message to a TProcess? lazarus / 34-Windows ---------------------------------------------------------------------- role_33 · 2024-11-04 02:43 Hello all, I'm trying to rewrite a front end for a console application that was originally written in C under Linux. Unfortunately, developing this front-end in Linux is not an option due to company restrictions. This (Linux) console application does some cleanup when it receives the SIGTERM or SIGQUIT signals (via Ctrl+C or Ctrl+\). I recompiled this console application under Windows (using Cygwin), and is responding correctly to both key combinations when I run it from Powershell/Command prompt, so I know the "signals" are being processed correctly under Windows. Here's my problem (or one of them): I'm running this consola applications from the front-end program I'm writing by using TProcess on a 2nd thread (essentially following the "executing external programs" wiki examples). However, TProcess.Terminate just kills the process (skipping any processing). Looking for information on how to send the signals before the thread is terminated -unsurprisingly- returns mostly Linux discussions (using fpKill). There is also discussion of using another console program (I don't recall the name right now) to send the signal to the 1st process, but that program needs Visual Studio to be compiled, and the link to the binaries doesn't work anymore. So, my question is: is there a way to send signals (specifically SIGQUIT or SIGTERM) to a console app (running as a TProcess) from within Free Pascal? Thanks! J ---------------------------------------------------------------------- Roland57 · 2024-11-04 07:37 Hello. Not sure that it help, but here someone suggests to use GenerateConsoleCtrlEvent. There is a Delphi example here. ---------------------------------------------------------------------- MarkMLl · 2024-11-04 08:26 Quote from: role_33 on November 04, 2024, 03:43:37 amLooking for information on how to send the signals before the thread is terminated -unsurprisingly- returns mostly Linux discussions (using fpKill). There is also discussion of using another console program (I don't recall the name right now) to send the signal to the 1st process, but that program needs Visual Studio to be compiled, and the link to the binaries doesn't work anymore. From your POV, what makes fpKill wrong? QuoteSo, my question is: is there a way to send signals (specifically SIGQUIT or SIGTERM) to a console app (running as a TProcess) from within Free Pascal? You use fpKill. There's a couple of caveats: first you'll need to find the PID of the process and second it can be a bit of a blunt instrument if the target program has internal threads. MarkMLl ---------------------------------------------------------------------- role_33 · 2024-11-04 18:34 Thank you people, @Roland57 I'll take a look. @MarkMLI: the main problem with fpKill() is that -as far as I know- it works only under Linux. Is this incorrect? Thx! J ---------------------------------------------------------------------- MarkMLl · 2024-11-04 18:58 Quote from: role_33 on November 04, 2024, 07:34:04 pm@MarkMLI: the main problem with fpKill() is that -as far as I know- it works only under Linux. Is this incorrect? Ah, I see what you mean. So it's working fine on Linux, but you want to convert it to Windows possibly via Cygwin... OK, it's 20 years since I touched that but does Cygwin provide a kill program (i.e. I mean a separate program, like I think it provides ls, rm and so on) and what does that map to on Windows? There's obviously lots of ways to do IPC, but it would even more obviously be worth trying to get the existing handler working rather than rearranging things to suit the OS change. Apart from that- and noting which topic you've posted under- trust anything anybody else says before me: my Windows experience is /way/ out of date. MarkMLl ---------------------------------------------------------------------- role_33 · 2024-11-04 19:46 LOL... I was hoping I was wrong and fpKill worked under Windows Apparently Cygwin takes care of the conversion of messages/interrupts (Windows) and signals (Linux). All I know is that the console program works fine under Linux AND under Windows (after compiling it using Cygwin). I can close the app using Ctrl+C or Ctrl+\ and the correct code is executed. So, that part is sorted out - thankfully. I tried modifying the code to respond to standard input (TProcess allows to send keystrokes through STDIN), but it didn't work. Now I'm on plan B (or is it  C?), which is sending the signals before I terminate the process (from inside my GUI frontend), so it has time to clean up the handlers/whatnot before closing. I'll check to see if there's another console program to do the sending of the signals, but I agree -  the correct way of doing this is from within FPC. J ---------------------------------------------------------------------- MarkMLl · 2024-11-04 20:00 A unix shell (strictly, the terminal handler) will normally intercept ^C and convert it into (I think) a signal, unless set to raw mode. That's probably why trying to do anything with ^C directly doesn't work. Apart from that I agree: send the signal which by default will be a SIGTERM which the target can intercept, and then if it continues to run send a SIGKILL or interact with the TProcess directly. MarkMLl ---------------------------------------------------------------------- role_33 · 2024-11-04 20:13 Alas... If I just knew how to send those signals! Thx! ---------------------------------------------------------------------- marcov · 2024-11-04 20:15 Freepascal might have some rudimentary signals support for windows in unit signals. But that was meant to deal with the GDB debugger when linked into the IDE, the FPC own app is still a fully native windows application, and doesn't know about mingw/cygwin Unix emulation modes. For windows apps it probably means installing a message handler and monitoring WM_QUIT. But I'm not sure if that is called if you kill a process by hard means. ---------------------------------------------------------------------- MarkMLl · 2024-11-04 20:42 Quote from: role_33 on November 04, 2024, 09:13:32 pmAlas... If I just knew how to send those signals! Terminology alert :-) kill (from a shell) or fpKill (from an FPC program) sends a unix-style signal, there isn't a separate "signal" program or API. A program (i.e. a process running a binary loaded from a file) has certain default responses to signals, but at least some of these may be overridden using a custom handler (SIGKILL implies extreme prejudice). MarkMLl ---------------------------------------------------------------------- Roland57 · 2024-11-05 07:20 Quote from: role_33 on November 04, 2024, 03:43:37 amThere is also discussion of using another console program (I don't recall the name right now) to send the signal to the 1st process, but that program needs Visual Studio to be compiled, and the link to the binaries doesn't work anymore. It is certainly possible to find such a program, or to write it yourself in C. Here is what I found: http://web.archive.org/web/20170909040729/http://www.latenighthacking. com/projects/2003/sendSignal/https://github.com/ElyDotDev/windows- killhttps://github.com/jredfox/WINSIG ---------------------------------------------------------------------- Thaddy · 2024-11-05 10:42 Quote from: Roland57 on November 05, 2024, 08:20:56 amIt is certainly possible to find such a program, or to write it yourself in C. You can simply write it in Pascal.... Don't need to mention C. In this case a named event is enough, but otherwise you can use a semaphore. See the syncobjs unit. That is, if both programs know about the sync object. C as a language does not help you any further than Pascal can. BTW the "easy" way out is use the process handles. ---------------------------------------------------------------------- role_33 · 2024-11-06 17:21 Hello all, Thank you for keeping the discussion alive. Just to be on the same page: I only have control over my end of the deal (sending the signals) - and that only after I figure out how to send them :/ I can compile the console app and I can do some basic modifications to it (in C), but anything bigger than that would require more time that I can reasonably invest. The console app (btw, it's Covesa's DLT-Receive) has code to respond specifically to SIGTERM and SIGQUIT, and I know for a fact it's working correctly under Windows. The links Roland posted look promising (after some digging). SendSignal doesn't work with x64, and Windows-Kill is the app I mentioned whose binaries are no longer available, and needs Visual Studio to compile. BUT WinSig and SendSignal Advanced may work. I need to do the testing. @Thaddy: can you offer pointers on how to implement this in Pascal? My problem is not with the multithreading (not at this point, at least), and from what I can see the C app I'm trying to interface with appears to be relatively safe. The issue is sending the darn signal. J ---------------------------------------------------------------------- Thaddy · 2024-11-06 18:28 Do you happen to know if the external program can handle stdin? That would greatly simplify my example. ---------------------------------------------------------------------- role_33 · 2024-11-06 20:01 Hello Thaddy, I don't think it handles STDIN, unfortunately. I tried modifying it to add a keyboard input handler (put some handling code on what I thought was the main loop), but I failed miserably :/ The console app can be found on Github (that much I can share!): https://github.com/COVESA/dlt-daemon/blob/master/src/console/dlt- receive.c The only change I've made was to modify the signal handling code (starting at line 97) to explicitly handle every signal, and put something on STDOUT to confirm it handled it. J