I've a client/server program, now I want to handle signals. When the client closes the connection (if for example I close the terminal), the server has to handle a SIGPIPE, am I right? I'd like to implement something like this. Is it possible?
server.c:
void function(){
printf("...");
read(socket,buff,size);
//IF THE CLIENT CLOSES, THE SERVER RECEIVES A SIGPIPE
...the resting part of the scheduled code should be ignored if sigpipe is received, and the program should begin from where I wrote on the handler of the sigpipe...
printf("not working"); //this should be ignored, but it's printed 2 times immediatly, and when I've finished the actions indicated in the function by the handler, it prints it another time, because the program counter restarts from here...
}
void sigpipehandler(){
close(socket);
main(); //I'd like that the program restarts from the main when I've received a SIGPIPE. It restarts from the main, but only after having printed "not working" two times...
}
int main(){
sigPipe.sa_sigaction = &sigpipehandler;
sigPipe.sa_flags = SA_SIGINFO;
sigaction(SIGPIPE, &sigpipehandler, NULL);
...code...
}
Converting comments into an answer.
Note that you only get SIGPIPE when you write to a pipe where there is no process with the read end of the pipe open. You get EOF (zero bytes read) when you read from a pipe that has no process with the write end of the pipe open.
So, if I change the
read()
with awrite()
in the example. How can I handle the SIGPIPE?
Simplest is to ignore SIGPIPE ( signal(SIGPIPE, SIG_IGN)
) and then monitor the return value from write()
. If it comes back with -1 and errno
set to EINTR
, you can assume you got interrupted by some signal, and most probably a SIGPIPE, especially if you don't have any other signal handling set. Of course, you should be looking at the return value from write()
— and read()
— anyway.
Alternatively, if you want an explicit SIGPIPE handler, then you definitely do not want to recursively call main()
from your signal handler. You can write a loop in main()
, and have the signal handler set a flag which you test in the loop. Per Standard C, about the only thing you can do in a signal handler is modify a variable or exit.
static volatile sigatomic_t sig_recvd = 0;
static int sock_fd = -1;
void sigpipehandler(int signum)
{
close(sock_fd);
sock_fd = -1;
sig_recvd = signum;
}
int main(void)
{
sigPipe.sa_sigaction = &sigpipehandler;
sigPipe.sa_flags = SA_SIGINFO;
sigemptyset(&sigPipe.sa_mask);
sigaction(SIGPIPE, &sigpipehandler, NULL);
int done = 0;
while (!done)
{
if (sock_fd == -1)
{
if (sig_recvd != 0)
{
...report signal received...
sig_recvd = 0;
}
...(re)open socket on sock_fd...
}
...code as before - sets done = 1 when loop should terminate...
}
return 0;
}
Note that naming a variable the same as a system call ( socket
in your code) is treading on thin ice; hence, I renamed it sock_fd
. A global variable called socket
would be a really bad idea.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.