1 #!/usr/bin/env python |
1 #!/usr/bin/env python |
2 # -*- coding: utf-8 -*- |
2 # -*- coding: utf-8 -*- |
3 |
3 |
4 #This file is part of Beremiz, a Integrated Development Environment for |
4 #This file is part of Beremiz, a Integrated Development Environment for |
5 #programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
5 #programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
6 # |
6 # |
7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
8 # |
8 # |
9 #See COPYING file for copyrights details. |
9 #See COPYING file for copyrights details. |
10 # |
10 # |
29 from threading import Timer, Lock, Thread, Semaphore |
29 from threading import Timer, Lock, Thread, Semaphore |
30 import os, sys |
30 import os, sys |
31 if os.name == 'posix': |
31 if os.name == 'posix': |
32 from signal import SIGTERM, SIGKILL |
32 from signal import SIGTERM, SIGKILL |
33 |
33 |
34 |
34 |
35 class outputThread(Thread): |
35 class outputThread(Thread): |
36 """ |
36 """ |
37 Thread is used to print the output of a command to the stdout |
37 Thread is used to print the output of a command to the stdout |
38 """ |
38 """ |
39 def __init__(self, Proc, fd, callback=None, endcallback=None): |
39 def __init__(self, Proc, fd, callback=None, endcallback=None): |
64 err = self.Proc.wait() |
64 err = self.Proc.wait() |
65 except: |
65 except: |
66 err = self.retval |
66 err = self.retval |
67 self.finished = True |
67 self.finished = True |
68 self.endcallback(self.Proc.pid, err) |
68 self.endcallback(self.Proc.pid, err) |
69 |
69 |
70 class ProcessLogger: |
70 class ProcessLogger: |
71 def __init__(self, logger, Command, finish_callback = None, |
71 def __init__(self, logger, Command, finish_callback = None, |
72 no_stdout = False, no_stderr = False, no_gui = True, |
72 no_stdout = False, no_stderr = False, no_gui = True, |
73 timeout = None, outlimit = None, errlimit = None, |
73 timeout = None, outlimit = None, errlimit = None, |
74 endlog = None, keyword = None, kill_it = False, cwd = None): |
74 endlog = None, keyword = None, kill_it = False, cwd = None): |
75 self.logger = logger |
75 self.logger = logger |
76 if not isinstance(Command, list): |
76 if not isinstance(Command, list): |
77 self.Command_str = Command |
77 self.Command_str = Command |
84 else: |
84 else: |
85 self.Command.append(word) |
85 self.Command.append(word) |
86 else: |
86 else: |
87 self.Command = Command |
87 self.Command = Command |
88 self.Command_str = subprocess.list2cmdline(self.Command) |
88 self.Command_str = subprocess.list2cmdline(self.Command) |
89 |
89 |
90 self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()), |
90 self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()), |
91 self.Command) |
91 self.Command) |
92 |
92 |
93 self.finish_callback = finish_callback |
93 self.finish_callback = finish_callback |
94 self.no_stdout = no_stdout |
94 self.no_stdout = no_stdout |
95 self.no_stderr = no_stderr |
95 self.no_stderr = no_stderr |
96 self.startupinfo = None |
96 self.startupinfo = None |
97 self.errlen = 0 |
97 self.errlen = 0 |
103 self.errdata = [] |
103 self.errdata = [] |
104 self.keyword = keyword |
104 self.keyword = keyword |
105 self.kill_it = kill_it |
105 self.kill_it = kill_it |
106 self.finishsem = Semaphore(0) |
106 self.finishsem = Semaphore(0) |
107 self.endlock = Lock() |
107 self.endlock = Lock() |
108 |
108 |
109 popenargs= { |
109 popenargs= { |
110 "cwd":os.getcwd() if cwd is None else cwd, |
110 "cwd":os.getcwd() if cwd is None else cwd, |
111 "stdin":subprocess.PIPE, |
111 "stdin":subprocess.PIPE, |
112 "stdout":subprocess.PIPE, |
112 "stdout":subprocess.PIPE, |
113 "stderr":subprocess.PIPE} |
113 "stderr":subprocess.PIPE} |
114 |
114 |
115 if no_gui == True and wx.Platform == '__WXMSW__': |
115 if no_gui == True and wx.Platform == '__WXMSW__': |
116 self.startupinfo = subprocess.STARTUPINFO() |
116 self.startupinfo = subprocess.STARTUPINFO() |
117 self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW |
117 self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW |
118 popenargs["startupinfo"] = self.startupinfo |
118 popenargs["startupinfo"] = self.startupinfo |
119 elif wx.Platform == '__WXGTK__': |
119 elif wx.Platform == '__WXGTK__': |
120 popenargs["shell"] = False |
120 popenargs["shell"] = False |
121 |
121 |
122 self.Proc = subprocess.Popen( self.Command, **popenargs ) |
122 self.Proc = subprocess.Popen( self.Command, **popenargs ) |
123 |
123 |
124 self.outt = outputThread( |
124 self.outt = outputThread( |
125 self.Proc, |
125 self.Proc, |
126 self.Proc.stdout, |
126 self.Proc.stdout, |
127 self.output, |
127 self.output, |
128 self.finish) |
128 self.finish) |
129 self.outt.start() |
129 self.outt.start() |
130 |
130 |
131 self.errt = outputThread( |
131 self.errt = outputThread( |
132 self.Proc, |
132 self.Proc, |
133 self.Proc.stderr, |
133 self.Proc.stderr, |
145 self.outlen += 1 |
145 self.outlen += 1 |
146 if not self.no_stdout: |
146 if not self.no_stdout: |
147 self.logger.write(v) |
147 self.logger.write(v) |
148 if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit): |
148 if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit): |
149 self.endlog() |
149 self.endlog() |
150 |
150 |
151 def errors(self,v): |
151 def errors(self,v): |
152 self.errdata.append(v) |
152 self.errdata.append(v) |
153 self.errlen += 1 |
153 self.errlen += 1 |
154 if not self.no_stderr: |
154 if not self.no_stderr: |
155 self.logger.write_warning(v) |
155 self.logger.write_warning(v) |
193 if self.endlock.acquire(False): |
193 if self.endlock.acquire(False): |
194 self.finishsem.release() |
194 self.finishsem.release() |
195 if not self.outt.finished and self.kill_it: |
195 if not self.outt.finished and self.kill_it: |
196 self.kill() |
196 self.kill() |
197 |
197 |
198 |
198 |
199 def spin(self): |
199 def spin(self): |
200 self.finishsem.acquire() |
200 self.finishsem.acquire() |
201 return [self.exitcode, "".join(self.outdata), "".join(self.errdata)] |
201 return [self.exitcode, "".join(self.outdata), "".join(self.errdata)] |
202 |
202 |