I want to run specific code before quitting when the user hits CTRL-C. The code is in Go and I want to run it on Windows using Git Bash / MINGW64. Using Go, I do
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
// some goroutines get started here
// ...
for {
select {
case <-interrupt:
// code which shall be run on CTRL-C
}
}
On Windows, this works when I use a Windows command line, but I want it to work on MINGW64/Git Bash as well.
I found on https://stackoverflow.com/a/31974985/1370397 that adding
trap '' SIGINT
to ~/.bashrc traps the SIGINT signal and prevents bash from terminating my program.
This works for me on MINGW32 with bash version
$ bash --version
GNU bash, version 3.1.20(4)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.
but it fails to work on MINGW64, bash version
$ bash --version
GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
[...]
What's different on MINGW64 or on that new (git) bash version?
For easier testing, here is a minimal example to see the behaviour differences:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func cleanup(){
for i:=0; i<3; i++ {
fmt.Println("Cleaning up...")
time.Sleep(500*time.Millisecond)
}
}
func work() {
for {
fmt.Println("Working...")
time.Sleep(300*time.Millisecond)
}
}
func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
go work()
for {
select {
case <-interrupt:
fmt.Println("Interrupt received - calling cleanup()...")
cleanup()
fmt.Println("Quitting...")
return
}
fmt.Println("Waiting...")
}
}
Output from MINGW32 (with trap '' SIGINT in ~/.bashrc):
$ ./sigint.exe
Working...
Working...
Working...
Interrupt received - calling cleanup()...
Cleaning up...
Working...
Working...
Cleaning up...
Working...
Cleaning up...
Working...
Working...
Quitting...
The cleanup() code gets executed.
Output from MINGW64 (also with trap '' SIGINT in ~/.bashrc):
$ ./sigint.exe
Working...
Working...
Working...
Working...
cleanup() does not get executed. :-(
Use winpty
to catch signals correctly in Git Bash for Windows. It comes bundled with the installation, so all you need to do is:
$ winpty ./my-program.exe
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With