using select() with pipe – this is what I am doing and now I need to catch SIGTERM on that. how can I do it? Do I have to do it when select() returns error ( < 0 ) ?
using select() with pipe – this is what I am doing and now I
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
First,
SIGTERMwill kill your process if not caught, andselect()will not return. Thus, you must install a signal handler forSIGTERM. Do that usingsigaction().However, the
SIGTERMsignal can arrive at a moment where your thread is not blocked atselect(). It would be a rare condition, if your process is mostly sleeping on the file descriptors, but it can otherwise happen. This means that either your signal handler must do something to inform the main routine of the interruption, namely, setting some flag variable (of typesig_atomic_t), or you must guarantee thatSIGTERMis only delivered when the process is sleeping onselect().I’ll go with the latter approach, since it’s simpler, albeit less flexible (see end of the post).
So, you block
SIGTERMjust before callingselect(), and reblock it right away after the function returns, so that your process only receives the signal while sleeping insideselect(). But note that this actually creates a race condition. If the signal arrives just after the unblock, but just beforeselect()is called, the system call will not have been called yet and thus it will not return-1. If the signal arrives just afterselect()returns successfully, but just before the re-block, you have also lost the signal.Thus, you must use
pselect()for that. It does the blocking/unblocking aroundselect()atomically.First, block
SIGTERMusingsigprocmask()before entering thepselect()loop. After that, just callpselect()with the original mask returned bysigprocmask(). This way you guarantee your process will only be interrupted while sleeping onselect().In summary:
SIGTERM(that does nothing);pselect()loop, blockSIGTERMusingsigprocmask();pselect()with the old signal mask returned bysigprocmask();pselect()loop, now you can check safely whetherpselect()returned-1anderrnoisEINTR.Please note that if, after
pselect()returns successfully, you do a lot of work, you may experience bigger latency when responding toSIGTERM(since the process must do all processing and return topselect()before actually processing the signal). If this is a problem, you must use a flag variable inside the signal handler, so that you can check for this variable in a number of specific points in your code. Using a flag variable does not eliminate the race condition and does not eliminate the need forpselect(), though.Remember: whenever you need to wait on some file descriptors or for the delivery of a signal, you must use
pselect()(orppoll(), for the systems that support it).Edit: nothing better than a code example to illustrate the usage.