On Wed, Jul 15, 2020 at 2:45 AM Jeff King <peff@xxxxxxxx> wrote: > On Thu, Jul 02, 2020 at 09:07:46AM +0200, R. Diez wrote: > > I do not understand why Git is getting these interruptions due to SIGALRM, because SA_RESTART is in place. It really shouldn't -- that's the whole point of SA_RESTART. > Delivering EINTR on a non-blocking call seems even more confusing, > though. I think the "if it can block" is just "you won't even get a > signal if it's not blocking". > > This really _seems_ like a kernel bug, either: > > - openat() does not get the same SA_RESTART treatment as open(); or > > - open() on a network file can get EINTR even with SA_RESTART > > But it's quite possible that I'm missing some corner case or historical > reason that it would need to behave the way you're seeing. It might be > worth reporting to kernel folks. > > -Peff Right. This goes way back to pre-v7-Unix signals, as a sort of a side effect of the implementation. In ancient times, the kernel code for the internal wait-for-some-event took a priority number, and anything below a cutoff value meant "not interrupted by signals" while anything above it meant "interrupted by signals". Disk operations were all at PRIBIO which was never interrupted. This is all quite different in modern systems and hence it's all adjustable, but in general we like to distinguish between "operations that will definitely complete fairly quickly" (normally not interrupted) and "operations that might take significant amounts of time" (normally interrupted with the option of restarting the system call). *Restarting*, though, means exactly that: not *resuming*, but *restarting*. So whatever system call is to be interrupted by the signal *must* be one that can simply be started over from the beginning. That means, for instance, that read() or write() can only be restarted if no data have yet moved. So if you're in a read() on a device (e.g., serial port, or tape drive, or whatever) and have gotten a few bytes, but not yet all you wanted, and then the system call is to be interrupted by a signal, the read() must return with a short count. An open() can be restarted on the assumption that no path names have been changed. That's not necessarily a good assumption, but it's traditional. The openat() can be restarted for the same reason (and in fact correct use of openat() can protect against some pathname issues). It's up to the programmer to decide whether to use SA_RESTART, and hence allow this, or not. Chris