|
32 | 32 | import logging
|
33 | 33 | import os
|
34 | 34 | import signal
|
| 35 | +import threading |
35 | 36 |
|
36 | 37 |
|
37 | 38 | logging.NOTICE = 60
|
@@ -78,39 +79,48 @@ def pipeopen(command, important=True, logger=log, allowfork=False, quiet=False):
|
78 | 79 | close_fds=False, preexec_fn=preexec_fn)
|
79 | 80 |
|
80 | 81 |
|
81 |
| -def run(command, important=True, logger=log, allowfork=False, quiet=False, timeout=-1): |
82 |
| - class run_alarm: |
83 |
| - pass |
84 |
| - def run_alarm_handler(sig, frame): |
85 |
| - raise run_alarm |
| 82 | +class Command(object): |
| 83 | + def __init__(self, command): |
| 84 | + self.command = command |
| 85 | + self.process = None |
| 86 | + self.stdout = None |
| 87 | + self.stderr = None |
86 | 88 |
|
87 |
| - stdout = stderr = None |
| 89 | + @property |
| 90 | + def returncode(self): |
| 91 | + ret = -1 |
| 92 | + if self.process: |
| 93 | + ret = self.process.returncode |
| 94 | + return ret |
88 | 95 |
|
89 |
| - try: |
90 |
| - timeout = long(timeout) |
91 |
| - except: |
92 |
| - timeout = -1 |
| 96 | + def run(self, important=True, logger=log, allowfork=False, quiet=False, timeout=None): |
| 97 | + def target(): |
| 98 | + self.process = pipeopen(self.command, important, logger, allowfork, quiet) |
| 99 | + (self.stdout, self.stderr) = self.process.communicate() |
93 | 100 |
|
94 |
| - p = pipeopen(command, important, logger, allowfork, quiet) |
95 |
| - if timeout != -1: |
96 |
| - signal.signal(signal.SIGALRM, run_alarm_handler) |
97 |
| - signal.alarm(timeout) |
| 101 | + thread = threading.Thread(target=target) |
| 102 | + thread.start() |
98 | 103 |
|
99 |
| - try: |
100 |
| - (stdout, stderr) = p.communicate() |
101 |
| - if timeout != -1: |
102 |
| - signal.alarm(0) |
| 104 | + thread.join(timeout) |
| 105 | + if thread.is_alive(): |
| 106 | + self.process.terminate() |
| 107 | + thread.join() |
103 | 108 |
|
104 |
| - except run_alarm: |
105 |
| - try: |
106 |
| - os.kill(p.pid, signal.SIGKILL) |
| 109 | + return (self.returncode, self.stdout, self.stderr) |
107 | 110 |
|
108 |
| - except OSError: |
109 |
| - pass |
110 | 111 |
|
111 |
| - return (-9, None, None) |
| 112 | +def run(command, important=True, logger=log, allowfork=False, quiet=False, timeout=-1): |
| 113 | + try: |
| 114 | + timeout = float(timeout) |
| 115 | + except: |
| 116 | + timeout = 0 |
| 117 | + |
| 118 | + if timeout <= 0: |
| 119 | + timeout = None |
| 120 | + |
| 121 | + c = Command(command) |
112 | 122 |
|
113 |
| - return (p.returncode, stdout, stderr) |
| 123 | + return c.run(important, logger, allowfork, quiet, timeout) |
114 | 124 |
|
115 | 125 |
|
116 | 126 | def system(command, important=True, logger=log):
|
|
0 commit comments