> You can siglongjump out of a signal handler [1]. If you sigsetjump right before doing a blocking call, you can reliably detect signals.
The problem with that approach is that if the system call has already returned by the time the signal handler runs and jumps, the system call's return gets clobbered. So if for example you're doing blocking reads/writes, you don't know how many bytes you read or wrote.
If your only blocking syscall is level-driven polling this approach is fine but the self-pipe trick is easier.
I wrote (10 years ago) a library to do something similar reliably. It required custom wrappers for every system call of interest so I could know by the instruction pointer in the ucontext_t whether the system call had actually run yet or not. http://www.slamb.org/projects/sigsafe/ The library's a bit stale now; it doesn't do the vsyscall thing for example.
Duh! You are right, losing the results of partial read/writes is not acceptable. I guess on x86, completely unportably, you could check whether the current ip is pointing to a syscall/int instruction.
The problem with that approach is that if the system call has already returned by the time the signal handler runs and jumps, the system call's return gets clobbered. So if for example you're doing blocking reads/writes, you don't know how many bytes you read or wrote.
If your only blocking syscall is level-driven polling this approach is fine but the self-pipe trick is easier.
I wrote (10 years ago) a library to do something similar reliably. It required custom wrappers for every system call of interest so I could know by the instruction pointer in the ucontext_t whether the system call had actually run yet or not. http://www.slamb.org/projects/sigsafe/ The library's a bit stale now; it doesn't do the vsyscall thing for example.