De read(2)
:
EINTR The call was interrupted by a signal before any data
was read; see signal(7).
Si usted enmienda el código para parecerse más a:
cont = 1;
while (1 && cont) {
ret = read(sockfd, buf, sizeof(buf));
if (ret < 0 && errno == EINTR)
cont = arbitrary_function();
}
Esto permite arbitrary_function()
decidir si el read(2)
debe juzgado de nuevo o no.
actualización
Es necesario para manejar la señal con el fin de obtener el comportamiento de EINTR
read(2)
:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<errno.h>
int interrupted;
void handle_int(num) {
interrupted = 1;
}
int main(void){
char buf[9001];
struct sigaction int_handler = {.sa_handler=handle_int};
sigaction(SIGINT,&int_handler,0);
while(!interrupted){
printf("interrupted: %d\n", interrupted);
if(read(0,buf,sizeof(buf))<0){
if(errno==EINTR){
puts("eintr");
}else{
printf("%d\n",errno);
}
puts(".");
}
}
puts("end");
return 0;
}
Da salida:
$ ./foo
interrupted: 0
hello
interrupted: 0
^Ceintr
.
end
Con lo que nos ha facilitado, El envío de SIGINT (a través de Ctrl + C) solo termina el programa. – kaykun
@kaykun, solo si esa es la última línea del programa. Puede agregar más líneas después del bloque 'while' que reinicia la transmisión, puede soltar ese cliente específico y continuar con el enlace principal de su programa, puede iniciar un shell interactivo con el usuario para preguntar qué acciones tomar a continuación ... nada dice que esto deba terminar el programa. – sarnold
@sarnold Incorrecto, al menos para mí el programa termina cuando se envía SIGINT sin importar lo que agregue después del ciclo while, que es el mismo para casi todos los demás programas de línea de comandos. – kaykun