]> git.decadent.org.uk Git - dak.git/blob - daklib/daksubprocess.py
Add by-hash support
[dak.git] / daklib / daksubprocess.py
1 """subprocess management for dak
2
3 @copyright: 2013, Ansgar Burchardt <ansgar@debian.org>
4 @license: GPL-2+
5 """
6
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21 import signal
22 import subprocess
23
24 #
25 def fix_signal_handlers():
26     """reset signal handlers to default action.
27
28     Python changes the signal handler to SIG_IGN for a few signals which
29     causes unexpected behaviour in child processes. This function resets
30     them to their default action.
31
32     Reference: http://bugs.python.org/issue1652
33     """
34     for signal_name in ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ'):
35         try:
36             signal_number = getattr(signal, signal_name)
37             signal.signal(signal_number, signal.SIG_DFL)
38         except AttributeError:
39             pass
40
41 def _generate_preexec_fn(other_preexec_fn=None):
42     def preexec_fn():
43         fix_signal_handlers()
44         if other_preexec_fn is not None:
45             other_preexec_fn()
46     return preexec_fn
47
48 def call(*args, **kwargs):
49     """wrapper around subprocess.call that fixes signal handling"""
50     preexec_fn = _generate_preexec_fn(kwargs.get('preexec_fn'))
51     kwargs['preexec_fn'] = preexec_fn
52     return subprocess.call(*args, **kwargs)
53
54 def check_call(*args, **kwargs):
55     """wrapper around subprocess.check_call that fixes signal handling"""
56     preexec_fn = _generate_preexec_fn(kwargs.get('preexec_fn'))
57     kwargs['preexec_fn'] = preexec_fn
58     return subprocess.check_call(*args, **kwargs)
59
60 def check_output(*args, **kwargs):
61     """wrapper around subprocess.check_output that fixes signal handling"""
62     preexec_fn = _generate_preexec_fn(kwargs.get('preexec_fn'))
63     kwargs['preexec_fn'] = preexec_fn
64     return subprocess.check_output(*args, **kwargs)
65
66 def Popen(*args, **kwargs):
67     """wrapper around subprocess.Popen that fixes signal handling"""
68     preexec_fn = _generate_preexec_fn(kwargs.get('preexec_fn'))
69     kwargs['preexec_fn'] = preexec_fn
70     return subprocess.Popen(*args, **kwargs)