Getting popen and SIGCHLD handler to work in parallel - c

In our code base we have a part of software that allows to run an arbitrary amount of external programs and monitor their exit codes via the use of fork() and the installation of a SIGCHLD handler. In the unit test cases this piece of software works fine.
However the process that is running this fork "server" is also running a bunch of software modules in several threads. Unfortunately one some parts of this (older) software are using popen() which seems to need to use its own SIGCHLD handler. The result we see is that the program will fail on the call to pclose() with the errno ECHILD.
Is there any way to use a SIGCHLD handler and a call to popen/pclose in parallel?

After fork(), signal handlers are inherited. So perhaps you should reset them to their defaults between fork() and exec(), by using signal() with SIG_DFL in the first child process, before you invoke the legacy software.

Related

Send signal to another process on Windows with C (alternative to kill of POSIX)

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)

who send sighup signal to childs when session leader exit, the c library or kernel?

As I know from man 3 exit :
If the exiting process is a session leader and its controlling
terminal is the controlling terminal of the session, then each process
in the foreground process group of this controlling terminal is sent a
SIGHUP signal
but who send the signal? it's c library or kernel ?
what clean work, c library do, and what clean work kernel do.
It's the kernel which sends the SIGHUP signal to the foreground process group when the controlling process (i.e. a session leader with a controlling terminal) exits -- see disassociate_ctty() which is called from do_exit().
I have no idea if job control could be implemented at all in userland, even theoretically -- FWIW it's in the kernel in all the implementations I know of.
However, notice that many shells (like bash) supplement the job control interface implemented by the operating system with their own non-standard quirks and features, making people wrongly assume that they're part of the same interface.

how to reset handlers registered by pthread_atfork

Some libraries might register some handlers with pthread_atfork(). I don't need them as I only use fork() together with exec(). Also, they can cause trouble in some cases. So, is there a way to reset the registered handler list?
Related: calling fork() without the atfork handlers, fork() async signal safety.
POSIX does not document any mechanism for fork handlers installed by pthread_atfork() to be removed, short of termination of the process or replacing the process image. If you don't want them, then don't install them. If they are installed by a third-party library, as you describe, then your options are to find a way to avoid that behavior of the library (possibly by avoiding the library altogether) or to live with it.

C program that can receive shutdown/terminate requests from linux/upstart/ubuntu

I have a coded a program in C for linux. At the moment I am using ubuntu upstart to run as a background service.
I want to be able to have the program gracefully shutdown when commanded instead of just being killed off. Can someone please point me to the functions used to receive such a command?
(edit: can't answer own post but it seems I am meant to use signal.h signal function to put callbacks on SIGTERM and SIGKILL).
You want to use sigaction(2) to define a handler to be run when SIGTERM is caught.

nptl SIGCONT and thread scheduling

I'm trying to port a code that relies on SIGCONT to stop certain threads of an application. With current linux nptl implementation seems one can't rely on that in 2.6.x kernels. I'm trying to devise a method to stop other threads. Currently I can only think on mutexes and condition variables. Any hints is appreciated.
If you are relying on stopping and resuming other threads, then your application will eventually fail.
That is because, you cannot guarantee that you're not going to stop a thread while it has a mutex taken which protects a shared resource. This would result in deadlock, as any other threads (possibly including the one which stopped the first thread) which then need to wait for the mutex, will wait forever.
I'm sure it is possible, but also, you're doing it wrong.
NB: such mutexes probably exist in parts of the C library, even if you have none in your own code. If you have none in your own code and it is nontrivial, I'd be surprised.
How are you sending the signals to the target thread? If you use pthread_kill() to send SIGSTOP / SIGCONT to a single thread, it should work.

Resources