~xubuntu-dev/ubuntu-cdimage/xubuntu-base

« back to all changes in this revision

Viewing changes to lib/cdimage/osextras.py

  • Committer: Sean Davis
  • Date: 2018-03-28 10:32:07 UTC
  • mfrom: (1559.1.156 ubuntu-cdimage)
  • Revision ID: smd.seandavis@gmail.com-20180328103207-o6s9d6h0hxxh8eqc
Merge lp:ubuntu-cdimage rev 1715

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
import errno
19
19
import os
20
 
import re
 
20
try:
 
21
    from shlex import quote as shell_quote
 
22
except ImportError:
 
23
    from pipes import quote as shell_quote
21
24
import shutil
22
 
import signal
23
25
import subprocess
24
26
 
25
 
from cdimage.log import logger
26
27
from cdimage.proxy import proxy_call
27
28
 
28
29
 
93
94
                raise
94
95
 
95
96
 
96
 
def run_bounded(seconds, command, **kwargs):
97
 
    # Fork first, to make sure that the controlling process only has a
98
 
    # single child to worry about.
99
 
    control_pid = os.fork()
100
 
    if control_pid:
101
 
        waitpid_retry(control_pid, 0)
102
 
        return
103
 
 
104
 
    def sigchld_handler(signum, frame):
105
 
        _, status = os.waitpid(-1, 0)
106
 
        if os.WIFEXITED(status):
107
 
            os._exit(status)
108
 
        else:
109
 
            logger.error("child exited with signal %d" % os.WTERMSIG(status))
110
 
            os._exit(os.WTERMSIG(status) + 128)
111
 
 
112
 
    old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler)
113
 
 
114
 
    def preexec():
115
 
        signal.signal(signal.SIGCHLD, old_sigchld)
116
 
        os.setpgid(0, 0)
117
 
 
118
 
    subp = subprocess.Popen(command, preexec_fn=preexec, **kwargs)
119
 
 
120
 
    # prevent race by setting process group on either side; cf. Stevens 1993
121
 
    try:
122
 
        os.setpgid(subp.pid, 0)
123
 
    except OSError:
124
 
        pass  # may fail if the child has already execed
125
 
 
126
 
    def sigalrm_handler(signum, frame):
127
 
        logger.error("%s took too long, terminating ..." % command[0])
128
 
        os.kill(-subp.pid, signal.SIGTERM)
129
 
 
130
 
    signal.signal(signal.SIGALRM, sigalrm_handler)
131
 
    signal.setitimer(signal.ITIMER_REAL, seconds)
132
 
    while True:
133
 
        signal.pause()
134
 
    os._exit(0)
135
 
 
136
 
 
137
97
class FetchError(Exception):
138
98
    """An attempt to fetch a file from a remote system failed."""
139
99
 
167
127
        raise FetchError("%s returned %d" % (command_str, ret))
168
128
 
169
129
 
170
 
def shell_escape(arg):
171
 
    if re.match(r"^[a-zA-Z0-9+,./:=@_-]+$", arg):
172
 
        return arg
173
 
    else:
174
 
        return "'%s'" % arg.replace("'", "'\\''")
175
 
 
176
 
 
177
130
def _read_nullsep_output(command):
178
131
    raw = subprocess.Popen(
179
132
        command, stdout=subprocess.PIPE,
191
144
def read_shell_config(config_path=None, whitelisted_keys=[]):
192
145
    commands = []
193
146
    if config_path is not None:
194
 
        commands.append(". %s" % shell_escape(config_path))
 
147
        commands.append(". %s" % shell_quote(config_path))
195
148
    commands.append("cat /proc/self/environ")
196
149
    for key in whitelisted_keys:
197
150
        commands.append(
200
153
    env = _read_nullsep_output(["sh", "-c", "; ".join(commands)])
201
154
    for key, value in env.items():
202
155
        yield key, value
 
156
 
 
157
 
 
158
def pid_exists(pid):
 
159
    try:
 
160
        os.kill(pid, 0)
 
161
        return True
 
162
    except OSError as e:
 
163
        if e.errno == errno.ESRCH:
 
164
            return False
 
165
        raise