wxPopen.py
author etisserant
Sun, 24 Feb 2008 02:06:42 +0100
changeset 110 a05e8b30c024
parent 89 0ab2868c6aa6
child 111 e2e498333fbc
permissions -rw-r--r--
Fixed way apps are launched in parralel with single log window... Tested in win32 only.
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     1
#!/usr/bin/env python
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     2
# -*- coding: utf-8 -*-
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     3
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     4
#This file is part of Beremiz, a Integrated Development Environment for
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     5
#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. 
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     6
#
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     7
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     8
#
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
     9
#See COPYING file for copyrights details.
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    10
#
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    11
#This library is free software; you can redistribute it and/or
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    12
#modify it under the terms of the GNU General Public
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    13
#License as published by the Free Software Foundation; either
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    14
#version 2.1 of the License, or (at your option) any later version.
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    15
#
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    16
#This library is distributed in the hope that it will be useful,
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    17
#but WITHOUT ANY WARRANTY; without even the implied warranty of
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    18
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    19
#General Public License for more details.
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    20
#
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    21
#You should have received a copy of the GNU General Public
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    22
#License along with this library; if not, write to the Free Software
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    23
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    24
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    25
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    26
import time
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    27
import wx
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    28
import subprocess, ctypes
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    29
import threading
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    30
import os
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    31
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    32
    
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    33
class outputThread(threading.Thread):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    34
    """
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    35
    Thread is used to print the output of a command to the stdout
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    36
    """
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    37
    def __init__(self, Proc, fd, callback=None, endcallback=None):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    38
        threading.Thread.__init__(self)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    39
        self.killed = False
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    40
        self.finished = False
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    41
        self.retval = None
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    42
        self.Proc = Proc
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    43
        self.callback = callback
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    44
        self.endcallback = endcallback
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    45
        self.fd = fd
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    46
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    47
    def run(self):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    48
        outeof = False
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    49
        self.retval = self.Proc.poll()
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    50
        while not self.retval and not self.killed and not outeof:   
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    51
            outchunk = self.fd.readline()
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    52
            if outchunk == '': outeof = True
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    53
            if self.callback :
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    54
                wx.CallAfter(self.callback,outchunk)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    55
            self.retval=self.Proc.poll()
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    56
        if self.endcallback:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    57
            err = self.Proc.wait()
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    58
            self.finished = True
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    59
            wx.CallAfter(self.endcallback, self.Proc.pid, self.retval)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    60
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    61
class ProcessLogger:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    62
    def __init__(self, logger, Command, finish_callback=None, no_stdout=False, no_stderr=False):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    63
        self.logger = logger
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    64
        self.Command = Command
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    65
        self.finish_callback = finish_callback
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    66
        self.no_stdout = no_stdout
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    67
        self.no_stderr = no_stderr
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    68
        self.errlen = 0
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    69
        self.outlen = 0
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    70
        self.exitcode = None
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    71
        self.outdata = ""
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    72
        self.errdata = ""
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    73
        self.finished = False
89
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
    74
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    75
        self.Proc = subprocess.Popen(self.Command, 
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    76
                                   cwd = os.getcwd(),
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    77
                                   stdin = subprocess.PIPE, 
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    78
                                   stdout = subprocess.PIPE, 
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    79
                                   stderr = subprocess.STDOUT)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    80
#                                   stderr = subprocess.PIPE)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    81
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    82
        self.outt = outputThread(
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    83
                      self.Proc,
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    84
                      self.Proc.stdout,
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    85
                      self.output,
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    86
                      self.finish)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    87
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    88
        self.outt.start()
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    89
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    90
#        self.errt = outputThread(
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    91
#                      self.Proc,
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    92
#                      self.Proc.stderr,
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    93
#                      self.errors)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    94
#
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    95
#        self.errt.start()
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
    96
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    97
    def output(self,v):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    98
        self.outdata += v
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
    99
        self.outlen += 1
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   100
        if not self.no_stdout:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   101
            self.logger.write(v)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
   102
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   103
    def errors(self,v):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   104
        self.errdata += v
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   105
        self.errlen += 1
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   106
        if not self.no_stderr:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   107
            self.logger.write_warning(v)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
   108
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   109
    def finish(self, pid,ecode):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   110
        self.finished = True
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   111
        self.exitcode = ecode
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   112
        if self.exitcode != 0:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   113
            self.logger.write(self.Command + "\n")
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   114
            self.logger.write_warning("exited with status %s (pid %s)\n"%(str(ecode),str(pid)))
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   115
        if self.finish_callback is not None:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   116
            self.finish_callback(self,ecode,pid)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
   117
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
   118
    def kill(self):
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   119
        self.outt.killed = True
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   120
#        self.errt.killed = True
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   121
        if wx.Platform == '__WXMSW__':
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   122
            PROCESS_TERMINATE = 1
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   123
            handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.Proc.pid)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   124
            ctypes.windll.kernel32.TerminateProcess(handle, -1)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   125
            ctypes.windll.kernel32.CloseHandle(handle)
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   126
        else:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   127
            os.kill(self.Proc.pid)
79
ae06c2da83f7 Some window related enhancements
etisserant
parents: 70
diff changeset
   128
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   129
    def spin(self, timeout=None, out_limit=None, err_limit=None, keyword = None, kill_it = True):
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   130
        count = 0
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   131
        while not self.finished:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   132
            if err_limit and self.errlen > err_limit:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   133
                break
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   134
            if out_limit and self.outlen > out_limit:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   135
                break
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   136
            if timeout:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   137
                if count > timeout:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   138
                    break
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   139
                count += 1
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   140
            if keyword and self.outdata.find(keyword)!=-1:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   141
                    break
89
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
   142
            wx.Yield()
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
   143
            time.sleep(0.01)
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
   144
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   145
        if not self.outt.finished and kill_it:
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   146
            self.kill()
89
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
   147
110
a05e8b30c024 Fixed way apps are launched in parralel with single log window... Tested in win32 only.
etisserant
parents: 89
diff changeset
   148
        return [self.exitcode, self.outdata, self.errdata]
89
0ab2868c6aa6 Added right aligment of parameteres blocks
etisserant
parents: 79
diff changeset
   149