Problem with subprocess.Popen and EINTR

Cameron Simpson cs at cskk.id.au
Sat Oct 28 19:11:04 EDT 2017


On 28Oct2017 23:56, Piet van Oostrum <piet-l at vanoostrum.org> wrote:
>I am using Python 2.7.14 on MacOS Sierra.
>
>I have a small Python program that calls a shell script in a loop with a time.sleep() in it.
>The shell script is called with subprocess.Popen(), followed by a subprocess.wait().
>No information is exchanged with the shell script.
>
>Once in a while I send a SIGINT to the program to cancel the sleep. I don't know if the sleep is active at the time of the SIGINT, but most of the time it will be as it takes much more time than the shell script.
>
>I do this by having a handler for the SIGINT which does nothing. It is just there to have the SIGINT silently cancel the sleep.
>
>Now after weeks of running correctly it crashed. It appears that the SIGINT came during the Popen. This causes a system call in the Popen to be terminated with EINTR and Popen then retries that system call, but unfortunately it fails. It seems to me that this could be a bug.

It may be a bug. Or it may be a system call which cannot be meaningfulling 
retried. But had you considered only activating the handler around the sleep?  
You still need to copy with SIGINT single I infer that you send this from 
outside the program.  What if you did this:

  os.signal(SIGINT, SIG_IGN)
  ... code code code, including the Popen/wait ...
  old_handler = os.signal(SIGINT, do_nothing_handler)
  sleep(...)
  os.signal(SIGINT, old_handler)

SIG_IGN is different from a do-nothing handler; it prevents the process seeing 
the signal at all, and therefore prevents the signal interrupting system calls.

So you activate your dummy-quit-sleeping function only around the sleep itself.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)



More information about the Python-list mailing list