ejecutar - console emulator windows
Evitando que MSYS ''bash'' mate procesos que atrapan ^ C (5)
¿Tiene una configuración de entorno CYGWIN (en el panel de control / variables de entorno)? Pruebe a configurar CYGWIN = notty y reinicie la apertura de un nuevo shell MSYS bash - ¿el problema persiste?
Tengo una aplicación de Windows en modo consola (portada desde Unix) que fue diseñada originalmente para hacer una salida limpia cuando recibió ^ C ( SIGINT
Unix). Una salida limpia en este caso implica esperar, potencialmente bastante tiempo, para que se cierren las conexiones de red remotas. (Sé que este no es el comportamiento normal de ^ C, pero no estoy en posición de cambiarlo). El programa es de un solo subproceso.
Puedo capturar ^ C con cualquier signal(SIGINT)
(como en Unix) o con SetConsoleCtrlHandler
. Cualquiera de los dos funciona correctamente cuando el programa se ejecuta bajo CMD.EXE. Sin embargo, si utilizo el shell "bash" que viene con MSYS (estoy usando el entorno MinGW para construir el programa, ya que esto me permite reutilizar los archivos make de Unix), entonces el programa se termina a la fuerza de forma aleatoria, a corto plazo (menos de 100 milisegundos) después de ^ C. Esto es inaceptable, ya que como mencioné, el programa necesita esperar a que se cierren las conexiones de red remotas.
Es muy probable que la gente quiera ejecutar este programa bajo MSYS bash. Además, este efecto rompe el conjunto de pruebas. No he podido encontrar ninguna forma de solucionar el problema, ya sea desde dentro del programa (ideal) o mediante la configuración en el shell (aceptable). ¿Alguien puede recomendar algo?
Arg - 5 minutos de edición en el comentario. Esto es lo que quería escribir:
Como solución alternativa, en lugar de intentar atrapar el evento CTRL-C que también se está propagando al shell, propondría que se desactive ENABLED_PROCESSED_INPUT en stdin para que CTRL-C se notifique como una entrada de teclado en lugar de como una señal:
DWORD mode;
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hstdin, &mode);
SetConsoleMode(hstdin, mode & ~ENABLE_PROCESSED_INPUT); /* disable CTRL-C processing as a signal */
Luego puede procesar la entrada del teclado en su hilo principal mientras el resto del programa hace su trabajo en un hilo separado y establecer un evento para la limpieza cuando se recibe CTRL-C.
Ctrl-C es SIGINT? Pensé que Ctrl-Z era SIGINT, pero Ctrl-C es SIGTERM. Mira esto.
Cuando ejecuta su programa con MSYS bash, ¿ejecuta el ejecutable directamente, o hay un script de shell wrapping (bash)?
Si es así, puede estar registrando un controlador Ctrl-C personalizado con el comando trap
(que hace un sleep seguido de un kill). Si tal cosa existe, modifíquela o elimínela.
Si no hay una trap
registrada, o no hay una secuencia de comandos de ajuste, considere crear dicha secuencia de comandos y agregar su propia trampa para anular el comportamiento predeterminado. Puede ver un ejemplo de cómo usarlo here o en la página man de bash (en la sección SHELL BUILTINS).
Tenía exactamente el mismo problema: había escrito un programa con un controlador SIGINT / SIGTERM. Ese controlador hizo el trabajo de limpieza, que a veces tomó un tiempo. Cuando ejecutaba el programa desde dentro de msys bash, ctrl-c hacía que mi manejador SIGINT disparara, pero no terminaba: el programa finalizaba ("desde afuera", por así decirlo) antes de que pudiera completar su limpieza trabajo.
Sobre la base de la respuesta de phs, y esta respuesta a una pregunta similar: https://.com/a/23678996/2494650 , se me ocurrió la siguiente solución. Es increíblemente simple, y podría tener algunos efectos secundarios que aún no he descubierto, pero me solucionó el problema.
Crea un archivo ~ / .bashrc con la siguiente línea:
trap '''' SIGINT
Eso es. Esto atrapa la señal sigint y evita que msys bash termine su programa "desde afuera". Sin embargo, de alguna manera todavía permite la señal SIGINT a través de su programa, lo que le permite hacer su elegante limpieza / apagado. No puedo decirle exactamente por qué funciona de esta manera, pero lo hace, al menos para mí.
¡Buena suerte!