Skip to content

Implement SA_RESTART #1974

@sporksmith

Description

@sporksmith

We currently ignore the SA_RESTART flag when handling signals.

From signals(7):

If a blocked call to one of the following interfaces is interrupted by
a signal handler, then the call is automatically restarted after the
signal handler returns if the SA_RESTART flag was used; otherwise the
call fails with the error EINTR:

This is fairly straightforward to implement. In the shim, after handling all pending signals, if all of the handed signals' actions has SA_RESTART set, and the syscall originally returned EINTR, and the syscall is one of the ones eligible to be restarted, we can just re-execute the syscall.

The main potentially tricky parts are:

  • Validating that the syscall is one of those eligible to be restarted. This is documented in signals(7), but sometimes depends on parameters to the syscall, not just the syscall number. It might be though that we can delegate such logic to the syscall handlers themselves, such that they don't return EINTR in the first place in such cases.
  • There are a few restartable syscalls that have relative timeouts, which should be updated appropriately to account for elapsed time when restarted. From restart_syscall(2) these are poll, nanosleep, clock_nanosleep, and futex with FUTEX_WAIT.

Metadata

Metadata

Assignees

Labels

Type: BugError or flaw producing unexpected results

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions