Windows - Forebyggelse af MSYS 'bash' fra at dræbe processer, der falder ^ C

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et Windows-program med konsolmodus (portet fra Unix), der oprindeligt var designet til at gøre en ren exit, da den modtog ^ C (Unix SIGINT). En ren udgang i dette tilfælde indebærer at vente, muligvis ganske lang tid, for at fjerne netværkstilslutninger til at lukke ned. (Jeg ved, at dette ikke er den normale opførsel af ^ C , men jeg er ikke i stand til at ændre den.) Programmet er enkeltgearet.


Jeg kan fælde ^ C med enten signal(SIGINT) (som under Unix) eller med SetConsoleCtrlHandler. Enten fungerer korrekt, når programmet køres under CMD.EXE. Men hvis jeg bruger 'bash' -skallen, der følger med MSYS (jeg bruger MinGW-miljøet til at opbygge programmet, da det tillader mig at genbruge Unix makefiles), afbrydes programmet med en vis tilfældig, kort tid (mindre end 100 millisekunder) efter ^ C . Dette er uacceptabelt, da programmet som nævnt skal vente på fjernnetværksforbindelser til at lukke. [8]


Det er meget sandsynligt, at folk vil køre dette program under MSYS bash. Denne effekt bryder også testpakken. Jeg har ikke kunnet finde nogen måde at løse problemet på, enten inden for programmet (ideelt) eller ved indstillinger på skallen (acceptabel). Kan nogen anbefale noget?

Bedste reference


Jeg havde det samme problem - jeg havde skrevet et program med en SIGINT/SIGTERM handler. Den håndterer gjorde oprydning, som nogle gange tog et stykke tid. Da jeg kørte programmet fra msys bash, ville ctrl-c få min SIGINT-håndterer til at slukke, men det ville ikke afslutte - programmet blev opsagt ('udefra' som det var), før det kunne fuldføre dets oprydning arbejde.


På baggrund af phs 'svar, og dette svar på et lignende spørgsmål: https://stackoverflow.com/a/23678996/2494650, kom jeg op på følgende løsning. Det er sindssygt simpelt, og det kan have nogle side- effekter, som jeg endnu har opdaget, men det løste problemet for mig.


Opret en ~/.bashrc fil med følgende linje:


trap '' SIGINT


Det er det. Dette fælder signaltignalet og forhindrer msys bash i at afslutte dit program 'udefra.' Det gør det på en eller anden måde stadig muligt at sende SIGINT-signalet til dit program, så det kan gøre sin yndefulde oprydning/nedlukning. 'Jeg fortæller dig præcis, hvorfor det virker på denne måde, men det gør - i hvert fald for mig.


Held og lykke!

Andre referencer 1


Arg - 5 minutters redigering på kommentar. Her er hvad jeg ønskede at skrive:


Som en løsning, foreslår jeg i stedet for at forsøge at fælde CTRL-C-hændelsen, som også propageres til skallen, at slukke ENABLED\_PROCESSED\_INPUT på stdin, så CTRL-C rapporteres som tastaturindgang i stedet for som et 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 */


Du kan så behandle tastaturindgang i din hovedtråd, mens resten af ​​programmet gør dens ting i en separat tråd og indstille en begivenhed til oprydning, når CTRL-C modtages.

Andre referencer 2


Når du kører dit program med MSYS bash, kører du den eksekverbare direkte, eller er der et indpakning (bash) shell script?


Hvis det er tilfældet, kan det være at registrere en brugerdefineret Ctrl-C-handler med kommandoen trap (det gør en søvn efterfulgt af en kill.) Hvis en sådan ting eksisterer, skal du ændre eller fjerne den.


Hvis der ikke er registreret trap, eller der ikke er noget indpakningsskript, skal du overveje at lave et sådant script og tilføje din egen fælde for at tilsidesætte standardadfærden. Du kan se et eksempel på hvordan du bruger det her eller på bashs man side (i SHELL BUILTINS sektionen). [10] [11]

Andre referencer 3


Ctrl-C er SIGINT? Jeg troede Ctrl-Z var SIGINT, men Ctrl-C er SIGTERM. Kontroller det.

Andre referencer 4


Har du en CYGWIN-miljøindstilling (i kontrolpanel/miljøvariabler)? Prøv at indstille CYGWIN=notty og genstart åbne en ny MSYS bash shell - opretholder problemet?