1

I am working to port a C/Fortran package that was written for POSIX systems to Windows. Most of the Fortran part of the software runs mathematical calculations. The C codes act as interfaces between Fortran and the system. The code is fully console-based and does not have a GUI.

The software is parallelised with MPI, i.e. after launch it runs multiple processes - one master process and several child processes.

Now, one of the hurdles I have faced with porting is the C code that deals with signal. The master process and child processes each have their signal handlers. The way the signal handling is implemented is that, when the master process receives the SIGTERM or SIGSEGV, it sends those to the child processes. In POSIX, that is implemented by kill(pid, SIGTERM). The signal handler of the child processes then interact with the Fortran part to gracefully bring the program to an exit.

What would be the best strategy to port this behaviour to Windows? I am not much familiar with Fortran so I would leave the fortran part untouched if I can. The only thing I have to ensure is that somehow the master process communicates with child processes via their PID, then I have enough to start writing code.

I have asked questions about an alternative to kill() on Windows, and it seems like there is no easy alternative. Please add an answer even if it means I have to modify a lot of code. The C signal code can be seen in another question I asked about this here.

(Please don't mention cygwin or WSL. Cygwin fails to compile it, and I need to run it from Windows, WSL binaries don't work outside of it)

S R Maiti
  • 237
  • 3
  • 13
  • It's probably easiest to just run the posix version in a WSL2 environment or VM instead of trying to port to Win32. – Shawn Apr 14 '21 at 22:12
  • I recommend not mixing C and C++ (they are distinct languages). For example, C++ allows function overloading and many compilers use non-standard "name mangling" techniques to make unique names for them. The C language does not support function overloading. This may affect linking with libraries. Please update your language tags accordingly. And then there is the issue about passing by reference... – Thomas Matthews Apr 14 '21 at 22:18
  • 1
    See: https://stackoverflow.com/questions/1216788/win32-api-analog-of-sending-catching-sigterm This is one link I got from an AND web search on: `signal equivalent in windows` As Shawn mentioned, you could run under a WSL2 VM and be done with it. Or, maybe `cygwin`. Don't know about its impl of POSIX signal handling, but it has _elaborate_ code for its impl of `fork`. So, at a minimum, it might be a good guide because I suspect it [already] implements what you want. – Craig Estey Apr 14 '21 at 22:35
  • 1
    One way for a parent process to communicate with its children is to write to (or close) a pipe connected to the child processes’ stdin. Of course the child processes need to contain code to monitor/read from stdin in order for that to work. – Jeremy Friesner Apr 15 '21 at 03:03
  • AFAIK MinGW provides this kind of signal handling. Not all POSIX signals are working, but SIGTERM among others does. – the busybee Apr 15 '21 at 07:16
  • @JeremyFriesner Thanks! Can you point me to an example of such type of code? I am not an experienced C coder. – S R Maiti Apr 15 '21 at 09:17
  • @thebusybee No, MinGW does not provide the function kill() or any other way to *send* signals to another process. It provides signal() for signal handling, but that's not what my question is about. – S R Maiti Apr 15 '21 at 09:19
  • @CraigEstey Thanks for the link, that's quite helpful. I have already tried cygwin, but the gfortran compiler runs into multiple errors while compiling the source code. So, I can't use cygwin. (Intel Fortran does compile everything successfully, so my best bet is to port the very small amount of C code that's present to windows) – S R Maiti Apr 15 '21 at 09:25
  • 1
    Oh, OK. I never tried to `kill()` another process, just my own. ;-) A short web search revealed [this project](https://github.com/walware/statet/tree/master/de.walware.statet.r.console.core/cppSendSignal) that might help. It seems to "inject" a thread in the target process and let it do the dirty job. – the busybee Apr 15 '21 at 09:32
  • @thebusybee Thanks! Yeah I have seen several such projects. They usually use GenerateConsolCtrlEvent() but the problem is, it can only generate SIGINT and SIGBREAK, not SIGSEGV or SIGTERM. Another problem is that generating the ctrl event affects all the child processes too, so if I call it from the master processes it just shuts down everything. – S R Maiti Apr 15 '21 at 09:40
  • 1
    @ShoubhikRMaiti an example of a parent process interacting with its child processes via their stdin/stdout can be found in the `test/daemonsitter.cpp` program included with this library: https://github.com/jfriesne/muscle.git (note that the library is written in C++, so in order to get it to work in a C-only program you'd need to rip out the appropriate Win32-API-calling sections of `ChildProcessDataIO.cpp` and/or `StdinDataIO.cpp`) – Jeremy Friesner Apr 17 '21 at 01:53

0 Answers0