Blocking calls are not the problem - you simply block on select({stdin, signalfd}) instead of blocking on read(stdin). The problem rather is slow IO calls that nonetheless never block - the canonical example being a read() from a disk file. In this case (eg. /bin/tar) you would have to poll your signalfd after every read() - but this breaks the file abstraction for programs like /bin/cat that don't care whether the file descriptor they're reading from is the blockable type or not, so they'd have to do both.
This is now starting to look considerably inelegant, and we haven't even talked about implementing the equivalent of synchronous signals provoked by a program's own action (SIGILL, SIGFPE, SIGSEGV, SIGBUS...).
This is now starting to look considerably inelegant, and we haven't even talked about implementing the equivalent of synchronous signals provoked by a program's own action (SIGILL, SIGFPE, SIGSEGV, SIGBUS...).