Cómo capturar la señal de Control + D?

Quiero capturar la señal Ctrl + D en mi progtwig y escribir un manejador de señal para ello. ¿Cómo puedo hacer eso? Estoy trabajando en C y usando un sistema Linux .

Como otros ya han dicho, para manejar Control + D , maneje el “final del archivo”.

Control + D es una comunicación entre el usuario y el pseudo archivo que ve como stdin. No significa específicamente “fin de archivo”, pero en general “vacía la entrada que escribí hasta ahora”. Enjuagar significa que cualquier llamada a read() en stdin en su progtwig regresa con la longitud de la entrada escrita desde la última descarga. Si la línea no está vacía, la entrada estará disponible para su progtwig aunque el usuario aún no haya escrito “return”. Si la línea está vacía, read() regresa con cero, y eso se interpreta como “fin del archivo”.

Entonces, cuando se usa Control + D para finalizar un progtwig, solo funciona al comienzo de una línea, o si se hace dos veces (la primera vez que se vacía, la segunda vez que read() devuelve cero).

Intentalo:

 $ cat foo (type Control-D once) foofoo (read has returned "foo") (type Control-D again) $ 

Ctrl + D no es una señal, es EOF (Fin-de-Archivo). Cierra la tubería stdin. Si read (STDIN) devuelve 0, significa stdin cerrado, lo que significa que se presionó Ctrl + D (suponiendo que haya un teclado en el otro extremo de la tubería).

Un ejemplo minimalista:

 #include  #include  #include  #include  void sig_hnd(int sig){ (void)sig; printf("(VINTR)"); } int main(){ setvbuf(stdout,NULL,_IONBF,0); struct termios old_termios, new_termios; tcgetattr(0,&old_termios); signal( SIGINT, sig_hnd ); new_termios = old_termios; new_termios.c_cc[VEOF] = 3; // ^C new_termios.c_cc[VINTR] = 4; // ^D tcsetattr(0,TCSANOW,&new_termios); char line[256]; int len; do{ len=read(0,line,256); line[len]='\0'; if( len <0 ) printf("(len: %i)",len); if( len==0 ) printf("(VEOF)"); if( len >0 ){ if( line[len-1] == 10 ) printf("(line:'%.*s')\n",len-1,line); if( line[len-1] != 10 ) printf("(partial line:'%s')",line); } }while( line[0] != 'q' ); tcsetattr(0,TCSANOW,&old_termios); } 

El progtwig cambia el carácter VEOF (de Ctrl-D) a Ctrl-C y el carácter VINTR (de Ctrl-C) a Ctrl-D. Si presiona Ctrl-D, el controlador del terminal enviará un SIGINT al manejador de señal del progtwig.

Nota: presionar VINTR borrará el buffer de entrada del terminal para que no pueda leer los caracteres escritos en la línea antes de presionar la tecla VINTR.

Por lo que sé Ctrl + D es traducido por el sistema al final de la entrada estándar para que su aplicación no reciba ninguna señal.

Creo que la única forma de interceptar Ctrl + D es trabajar directamente con la API del sistema (como acceder a tty)

No hay necesidad de procesar señales.

Debe asegurarse de que ISIG no esté configurado en los indicadores de la terminal, eso es todo.

Aquí hay un ejemplo completo que contiene el uso de select para evitar el locking en stdin:

 #include  #include  #include  #include  #include  

Salida:

 doug-2:rust-sys-sterm doug$ cc junk.c doug-2:rust-sys-sterm doug$ ./a.out Press Q to quit... Found: 4 Found: 3 Found: 27 Found: 26 Found: 113 Normal exit 

NÓTESE BIEN. 3 es control C y 4 es control D; 26 es control z. 113 es ‘q’. Consulte: http://en.wikipedia.org/wiki/ASCII#ASCII_control_characters para obtener una tabla completa.

Puede usar poll () y mirar para POLLHUP en fd # 1, porque la capa TTY traduce ^ D a EOF.

La señal solo puede capturarse para que pueda capturar ^ C pero no ^ D

Porque no es una señal …

Espero que esto ayude