29 import subprocess |
29 import subprocess |
30 import ctypes |
30 import ctypes |
31 from threading import Timer, Lock, Thread, Semaphore |
31 from threading import Timer, Lock, Thread, Semaphore |
32 import signal |
32 import signal |
33 |
33 |
|
34 _debug = os.path.exists("BEREMIZ_DEBUG") |
34 |
35 |
35 class outputThread(Thread): |
36 class outputThread(Thread): |
36 """ |
37 """ |
37 Thread is used to print the output of a command to the stdout |
38 Thread is used to print the output of a command to the stdout |
38 """ |
39 """ |
75 def __init__(self, logger, Command, finish_callback=None, |
76 def __init__(self, logger, Command, finish_callback=None, |
76 no_stdout=False, no_stderr=False, no_gui=True, |
77 no_stdout=False, no_stderr=False, no_gui=True, |
77 timeout=None, outlimit=None, errlimit=None, |
78 timeout=None, outlimit=None, errlimit=None, |
78 endlog=None, keyword=None, kill_it=False, cwd=None, |
79 endlog=None, keyword=None, kill_it=False, cwd=None, |
79 encoding=None, output_encoding=None): |
80 encoding=None, output_encoding=None): |
|
81 assert(logger) |
80 self.logger = logger |
82 self.logger = logger |
81 if not isinstance(Command, list): |
83 if not isinstance(Command, list): |
82 self.Command_str = Command |
84 self.Command_str = Command |
83 self.Command = [] |
85 self.Command = [] |
84 for i, word in enumerate(Command.replace("'", '"').split('"')): |
86 for i, word in enumerate(Command.replace("'", '"').split('"')): |
172 self.logger.write_warning(v) |
174 self.logger.write_warning(v) |
173 if self.errlimit and self.errlen > self.errlimit: |
175 if self.errlimit and self.errlen > self.errlimit: |
174 self.endlog() |
176 self.endlog() |
175 |
177 |
176 def log_the_end(self, ecode, pid): |
178 def log_the_end(self, ecode, pid): |
177 self.logger.write(self.Command_str + "\n") |
179 if self.logger is not None: |
178 self.logger.write_warning(_("exited with status {a1} (pid {a2})\n").format(a1=str(ecode), a2=str(pid))) |
180 self.logger.write(self.Command_str + "\n") |
|
181 self.logger.write_warning(_("exited with status {a1} (pid {a2})\n").format(a1=str(ecode), a2=str(pid))) |
179 |
182 |
180 def finish(self, pid, ecode): |
183 def finish(self, pid, ecode): |
181 # avoid running function before start is finished |
184 # avoid running function before start is finished |
182 self.startsem.acquire() |
185 self.startsem.acquire() |
183 self.startsem.release() |
186 self.startsem.release() |
184 if self.timeout: |
187 if self.timeout: |
185 self.timeout.cancel() |
188 self.timeout.cancel() |
186 self.exitcode = ecode |
189 self.exitcode = ecode |
187 if self.exitcode != 0: |
190 if _debug or self.exitcode != 0: |
188 self.log_the_end(ecode, pid) |
191 self.log_the_end(ecode, pid) |
189 if self.finish_callback is not None: |
192 if self.finish_callback is not None: |
190 self.finish_callback(self, ecode, pid) |
193 self.finish_callback(self, ecode, pid) |
191 self.errt.join() |
194 self.errt.join() |
192 self.finishsem.release() |
195 self.finishsem.release() |