I am writing a simple client/server communication with fifo but i am stuck at using a signal handler to process client request.
The server open a fifo in readonly and non blocking mode, read datas received and writes back some datas to the client fifo.
And this actually works fine when there is no signal handler on the server side. Here is the main code for both sides.
Server :
int main(int argc, char *argv[]) { // install handler struct sigaction action; action.sa_handler = requestHandler; sigemptyset(&(action.sa_mask)); action.sa_flags = SA_RESETHAND | SA_RESTART; sigaction(SIGIO, &action, NULL); if(!makeFifo(FIFO_READ, 0644)) exit(1); int rd_fifo = openFifo(FIFO_READ, O_RDONLY | O_NONBLOCK); // non blocking if(rd_fifo == -1) exit(1); // wait for request and answer while (1) { qWarning() << "waiting client..."; sleep(1); QString msg = readFifo(rd_fifo); qWarning() << "msg = " << msg; if(msg == "ReqMode") { int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); // blocking writeFifo(wr_fifo, QString("mode")); break; } else qWarning() << "unknow request .."; } close(rd_fifo); unlink(FIFO_READ); return 0; }
Client :
int main(int argc, char *argv[]) { int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); if(wr_fifo == -1) exit(1); // create a fifo to read server answer if(!makeFifo(FIFO_READ, 0644)) exit(1); // ask the server his mode writeFifo(wr_fifo, QString("ReqMode")); // read his answer and print it int rd_fifo = openFifo(FIFO_READ, O_RDONLY); // blocking qWarning() << "server is in mode : " << readFifo(rd_fifo); close(rd_fifo); unlink(FIFO_READ); return 0; }
Everything works as expected ( even if all errors are not properly handled, this is just a sample code to demonstrate that this is possible).
The problem is that the handler ( not shown here, but it only print a message on the terminal with the signal received ) is never called when the client write datas to the fifo. Beside, i have check that if i send a kill -SIGIO
to the server from a bash ( or from elsewhere ) the signal handler is executed.
Thanks for your help.
Advertisement
Answer
Actually, i missed the 3 following lines on the server side :
fcntl(rd_fifo, F_SETOWN, getpid()); // set PID of the receiving process fcntl(rd_fifo, F_SETFL, fcntl(rd_fifo, F_GETFL) | O_ASYNC); // enable asynchronous beahviour fcntl(rd_fifo, F_SETSIG, SIGIO); // set the signal that is sent when the kernel tell us that there is a read/write on the fifo.
The last point was important because the default signal sent was 0 in my case, so i had to set it explicity to SIGIO to make things works. Here is the output of the server side :
waiting client... nb_read = 0 msg = "" unknow request .. waiting client... signal 29 SIGPOLL nb_read = 7 msg = "ReqMode"
Now, i guess it’s possible to handle the request inside the handler by moving what is inside the while loop into the requestHandler function.