From owner-freebsd-python@FreeBSD.ORG  Sat Jul  9 17:58:39 2011
Return-Path: <owner-freebsd-python@FreeBSD.ORG>
Delivered-To: freebsd-python@FreeBSD.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 8DA3E106564A
	for <freebsd-python@FreeBSD.org>; Sat,  9 Jul 2011 17:58:39 +0000 (UTC)
	(envelope-from nox@jelal.kn-bremen.de)
Received: from smtp.kn-bremen.de (gelbbaer.kn-bremen.de [78.46.108.116])
	by mx1.freebsd.org (Postfix) with ESMTP id 503F28FC0A
	for <freebsd-python@FreeBSD.org>; Sat,  9 Jul 2011 17:58:39 +0000 (UTC)
Received: by smtp.kn-bremen.de (Postfix, from userid 10)
	id 4815C1E0011C; Sat,  9 Jul 2011 19:43:27 +0200 (CEST)
Received: from triton8.kn-bremen.de (noident@localhost [127.0.0.1])
	by triton8.kn-bremen.de (8.14.4/8.14.3) with ESMTP id p69Hg2g9097479;
	Sat, 9 Jul 2011 19:42:02 +0200 (CEST)
	(envelope-from nox@triton8.kn-bremen.de)
Received: (from nox@localhost)
	by triton8.kn-bremen.de (8.14.4/8.14.3/Submit) id p69Hg1As097478;
	Sat, 9 Jul 2011 19:42:01 +0200 (CEST) (envelope-from nox)
From: Juergen Lock <nox@jelal.kn-bremen.de>
Date: Sat, 9 Jul 2011 19:42:01 +0200
To: freebsd-python@FreeBSD.org
Message-ID: <20110709174201.GA96487@triton8.kn-bremen.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.5.21 (2010-09-15)
Cc: Duncan Findlay <duncan@duncf.ca>,
	Olivier Cochard-Labbe <olivier@cochard.me>,
	Benjamin Epitech <mlspirat42@gmail.com>
Subject: Re: ports/153167: Problem with signals, threads, and subprocesses in
 lang/python
X-BeenThere: freebsd-python@freebsd.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: FreeBSD-specific Python issues <freebsd-python.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-python>, 
	<mailto:freebsd-python-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/freebsd-python>
List-Post: <mailto:freebsd-python@freebsd.org>
List-Help: <mailto:freebsd-python-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-python>,
	<mailto:freebsd-python-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Sat, 09 Jul 2011 17:58:39 -0000

Hi!  (please Cc me with followups, I'm not subscribed)

 Has anyone looked at this problem again yet?  I found the PR after
debugging the same issue in the emulators/gns3 port, I'm not that
good at python but maybe the workaround I came up with (patch to
gns3's qemuwrapper.py, this is for an updated version of the port
that Olivier is working on) still is useful as a starting point,
maybe something like it could be added to subprocess.py, or
the more portable C equivalent at the appropriate place?  (or even
generally in exec*()?)

--- qemuwrapper/qemuwrapper.py.orig
+++ qemuwrapper/qemuwrapper.py
@@ -45,6 +45,7 @@ import SocketServer
 import time
 import random
 import pemubin
+import ctypes
 
 
 __author__ = 'Thomas Pani and Jeremy Grossmann'
@@ -118,6 +119,33 @@ class xEMUInstance(object):
     def unbase_disk(self):
         pass
 
+    def preexec(self):
+        # FreeBSD preexec_fn hack to unblock signals in child processes
+        # to work around the bug in this PR:
+        #        http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/153167
+        # inspired by:
+        #        http://stackoverflow.com/questions/3791398/how-to-stop-python-from-propagating-signals-to-subprocesses
+
+        # Get the size of the array used to
+        # represent the signal mask
+        SIGSET_NWORDS = 1024 / (8 * ctypes.sizeof(ctypes.c_uint))
+
+        # Define the sigset_t structure
+        class SIGSET(ctypes.Structure):
+            _fields_ = [
+                ('val', ctypes.c_uint * SIGSET_NWORDS)
+            ]
+
+        # Create a new sigset_t to mask out SIGINT
+        sigs = (ctypes.c_uint * SIGSET_NWORDS)()
+        mask = SIGSET(sigs)
+
+        SIG_SETMASK = 3
+        libc = ctypes.CDLL('libc.so')
+
+        # Unblock all signals
+        libc.sigprocmask(SIG_SETMASK, ctypes.pointer(mask), 0)
+
     def start(self):
         command = self._build_command()
 
@@ -125,6 +152,7 @@ class xEMUInstance(object):
         try:
             self.process = subprocess.Popen(command,
                                             stdin=subprocess.PIPE,
+                                            preexec_fn=self.preexec,
                                             cwd=self.workdir)
         except OSError, e:
             print >> sys.stderr, "Unable to start instance", self.name, "of", self.__class__