code: def interruptable_popen(*args, **kwargs):
      
      kwargs["preexec_fn"] = os.setsid
  
      p = subprocess.Popen(*args, **kwargs)
  
      try:
          out, err = p.communicate()
      except KeyboardInterrupt:
          os.killpg(os.getpgid(p.pid), signal.SIGTERM)
          raise
  
      if six.PY3:
          if out is not None:
              out = out.decode("utf-8")
          if err is not None:
              err = err.decode("utf-8")
  
      return p.returncode, out, err
docs: Shorthand to :py:class:`Popen` followed by :py:meth:`Popen.communicate`. All *args* and *kwargs*
      are forwatded to the :py:class:`Popen` constructor. The return code, standard output and
      standard error are returned in a tuple. The call :py:meth:`Popen.communicate` is interruptable
      by the user.