Empêcher MSYS “bash” de tuer des processus qui piègent ^ C

J’ai une application Windows en mode console (scope depuis Unix) conçue à l’origine pour effectuer une sortie nette lorsqu’elle a reçu ^ C (Unix SIGINT ). Une sortie propre dans ce cas implique d’attendre, peut-être assez longtemps, la fermeture des connexions réseau distantes. (Je sais que ce n’est pas le comportement normal de ^ C mais je ne suis pas en mesure de le changer.) Le programme est à thread unique.

Je peux piéger ^ C avec un signal(SIGINT) (comme sous Unix) ou avec SetConsoleCtrlHandler . L’un ou l’autre fonctionne correctement lorsque le programme est exécuté sous CMD.EXE. Toutefois, si j’utilise le shell “bash” fourni avec MSYS (j’utilise l’environnement MinGW pour créer le programme, car cela me permet de réutiliser les fichiers de création Unix), le programme est forcé de se terminer de manière aléatoire (moins de 100 millisecondes) après le ^ C. C’est inacceptable, car comme je l’ai mentionné, le programme doit attendre que les connexions réseau distantes se ferment.

Il est très probable que les gens voudront exécuter ce programme sous MSYS bash. En outre, cet effet rompt la suite de tests. Je n’ai pas été en mesure de trouver un moyen de contourner le problème, que ce soit à l’intérieur du programme (idéal) ou par les parameters du shell (acceptable). Quelqu’un peut-il recommander quelque chose?

J’ai eu exactement le même problème – j’avais écrit un programme avec un gestionnaire SIGINT / SIGTERM. Ce manieur effectuait des travaux de nettoyage qui prenaient parfois un certain temps. Lorsque j’ai exécuté le programme depuis msys bash, ctrl-c provoquait le déclenchement de mon gestionnaire SIGINT, mais il ne se terminait pas – le programme était terminé (“de l’extérieur”, pour ainsi dire) avant de pouvoir terminer son nettoyage travail.

S’appuyant sur la réponse de phs, et cette réponse à une question similaire: https://stackoverflow.com/a/23678996/2494650 , je suis arrivé à la solution suivante. C’est incroyablement simple, et cela pourrait avoir des effets secondaires que je n’ai pas encore découvert, mais cela a résolu le problème pour moi.

Créez un fichier ~ / .bashrc avec la ligne suivante:

 trap '' SIGINT 

C’est tout. Cela intercepte le signal sigint et empêche msys bash de terminer votre programme “de l’extérieur”. Cependant, le signal SIGINT parvient toujours à passer dans votre programme, ce qui lui permet de faire son propre nettoyage / arrêt. Je ne peux pas vous dire exactement pourquoi cela fonctionne de cette façon, mais c’est le cas – du moins pour moi.

Bonne chance!

Arg – 5 minutes éditer sur le commentaire. Voici ce que je voulais écrire:

En guise de solution de contournement, au lieu d’essayer de piéger l’événement CTRL-C qui est également propagé au shell, je proposerais de désactiver ENABLED_PROCESSED_INPUT sur stdin pour que CTRL-C soit signalé comme une entrée de clavier plutôt que comme un signal:

 DWORD mode; HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hstdin, &mode); SetConsoleMode(hstdin, mode & ~ENABLE_PROCESSED_INPUT); /* disable CTRL-C processing as a signal */ 

Vous pouvez ensuite traiter l’entrée du clavier dans votre thread principal pendant que le rest du programme fait son travail dans un thread séparé et définissez un événement à nettoyer lors de la réception de CTRL-C.

Lorsque vous exécutez votre programme avec MSYS bash, exécutez-vous directement l’exécutable, ou existe-t-il un script shell enveloppant (bash)?

Si c’est le cas, il peut enregistrer un gestionnaire Ctrl-C personnalisé avec la commande trap (qui fait un sumil suivi d’un kill). Si une telle chose existe, modifiez-la ou supprimez-la.

Si aucune trap n’est enregistrée ou qu’il n’ya pas de script d’encapsulation, envisagez de créer un tel script et d’append votre propre interruption pour remplacer le comportement par défaut. Vous pouvez voir un exemple d’utilisation ici ou sur la page de manuel de bash (dans la section SHELL BUILTINS).

Ctrl-C est SIGINT? Je pensais que Ctrl-Z était SIGINT, mais Ctrl-C est SIGTERM. Regarde ça.

Avez-vous un paramètre d’environnement CYGWIN (dans les variables du panneau de commande / de l’environnement)? Essayez de définir CYGWIN = notty et redémarrez un nouveau shell MSYS MSM – le problème persiste-t-il?