2

I have an executable loop.exe on my Windows machine that was compiled using MinGW's gcc.

The code for loop.c is behaviorally similar to:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

static int sigintReceived = 0;

void sigint_handler(int signum){
    sigintReceived = 1;
}

int main(){
    signal(SIGINT, sigint_handler);
    while(1){
        sleep(1);
        if(sigintReceived){
            printf("SIGINT received");
            exit(0);
        }
    }
}

If I open a Cygwin terminal using Cygwin.bat and run ./loop.exe and then press Ctrl+C I will see the output:

SIGINT received

However if I open two terminals using Cygwin.bat and run ./loop.exe in one and kill -2 <LOOP_EXE_PID> in the other, I do not see the output at all.

The code is acting as if no signal handler exists when I run kill -## <LOOP_EXE_PID> with any signal and handler (for example if I kill -10 I'll get a Bus error or if I kill -12 I'll get a Bad system call or if I kill -11 I'll get a Segmentation fault)

I have looked around and come across this answer which I believe might relate to what I'm encountering, however loop.exe is being terminated in each case. In this answer Bogdan mentions that Windows executables are not run directly by the Bash shell but rather through an intermediate Bash process, and I can see this process in my Windows Task Manager when I run ./loop.exe, but I cannot see this intermediate Bash process from inside Cygwin.

Any ideas as to how I can get kill -2 <LOOP_EXE_PID> to act the same as Ctrl+C? Or, any ideas how I can see this intermediate Bash process from inside Cygwin?

Note: I am running Cygwin using C:\cygwin\Cygwin.bat; I am not using mintty.

Den Dinh
  • 197
  • 1
  • 10
  • I think running two cygwins is not the same as running two terminals on the same linux system. I think it is like running two different systems. Not sure though. Can a PID from one of them be seen in the `ps` of the other one? – Eugene Sh. Jul 20 '17 at 17:29
  • @EugeneSh. Yes, PIDs are consistent between seperate Cygwin terminals. – Den Dinh Jul 20 '17 at 17:32
  • Using standard library functions from a signal handler invokes undefined behaviour. The standard library is not guaranteed to be thread-safe. – too honest for this site Jul 20 '17 at 17:40
  • 1
    @Olaf I understand but that is beside the point. Replace the `printf("SIGINT received\n");` with any statement you'd like, the statement still will not be invoked/executed. I used `printf` for understandability, though I understand it is bad practice. – Den Dinh Jul 20 '17 at 18:17
  • "Bad practice" is not the same as undefined behaviour! Get comforatble with the debugger. – too honest for this site Jul 20 '17 at 18:24
  • @Olaf Edited the code in attempts to make it "thread safe" please take a look at it now and see if the edit helps you to answer the question. – Den Dinh Jul 20 '17 at 18:51
  • `int` is not guaranteed atomic. You should read about concurrency/threads when doing such things. – too honest for this site Jul 20 '17 at 20:13

2 Answers2

2

The program is compiled with MinGW; therefore it is not a Cygwin program.

MinGW programs do not have real POSIX signal handling; only a minimal signal API from ISO C.

They cannot respond to external signals in the Cygwin environment. There is no relationship between the signal function in the Microsoft MSVCRT.DLL and Cygwin's signal handling.

Sending a signal from one process to another is not a concept in MS Windows. Cygwin brings that about in its own domain, the same way it brings about other POSIX things like fork and exec, termios over the console and whatever else.

Kaz
  • 55,781
  • 9
  • 100
  • 149
  • So you're saying if I compiled `loop.c` with Cygwin's gcc I would have a greater chance of success? – Den Dinh Jul 20 '17 at 19:02
  • @DenDinh Well, yes. Then `signal` is actually the implementation in `cygwin1.dll`, – Kaz Jul 20 '17 at 19:03
  • 1
    Okay, I understand. I will attempt to get `loop.c`'s dependencies working with Cygwin's gcc and I will report back when I have results... – Den Dinh Jul 20 '17 at 19:05
1

There is no such thing as signal handling in MinGW. Cygwin has its own signal handling behaviors that can not be handled from outside of Cygwin. Your best bet is to compile with Cygwin's GCC or take a look at Microsoft signals.