18

This is a followup question to Is a successful send() "atomic"?, as I think it actually concerns system calls in general, not just sends on sockets.

Which system calls can be interrupted, and when they are, where is the interruption handled? I've learned about SA_RESTART, but don't exactly understand what is going on.

  • If I make a system call without SA_RESTART, can the call be interrupted by any kind of interrupts (e.g. user input) that don't concern my application, but require the OS to abort my call and do something else? Or is it only interrupted by signals that directly concern my process (CTRL+C, socket closed, ...)?

  • When setting SA_RESTART, what are the semantics of a send() or any other "slow" syscall? Will it always block until all of my data is transmitted or the socket goes down, or can it return with a number smaller than the count in send()'s parameter?

  • Where is restarting implemented? Does the OS know that I want the call to be restarted upon any interrupts, or is some signal sent to my process and then handled by library code? Or do I have to do it myself, e.g. wrap the call in a while loop and retry as often as necessary?

Community
  • 1
  • 1
lxgr
  • 3,719
  • 7
  • 31
  • 46

1 Answers1

13

System calls can be interrupted by any signal, this includes such signals as SIGINT (generated by CTRL-C), SIGHUP, etc.

When SA_RESTART is set, a send() will return (with the sent count) if any data was transmitted before the signal was received, it will return an error EINTR if a send timeout was set (as those can't be restarted), otherwise the send() will be restarted.

System call restarting is implemented in the kernel's signal handling code. The system call internally returns -ERESTARTSYS upon detecting a pending signal (or having a wait interrupted by a signal), which causes the signal handling code to restore the instruction pointer and relevant registers to the state before the call, making the syscall repeat.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • 1
    This only means signals sent to my process, right? I somehow assumed that ANY interruption of the kernel handling my interrupt (a key press, mouse move, timer interrupt,...) would cause my call to return and the signal to be sent. A context switch during the system call should not interfere with my process in any way besides time, right? – lxgr Nov 08 '11 at 13:55
  • 1
    @lxgr, that's correct, context switching does not abort system calls. – Brian Cain Nov 08 '11 at 14:06
  • Signals are delivered to a process only on the next context switch, so if system call is interrupted by signal means, system call will not return immediately but only after context switch and then signal is delivered. Not very clear to me. – Haswell Aug 16 '23 at 04:41