[gedit] Improved external tool process handling
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Subject: [gedit] Improved external tool process handling
- Date: Thu, 21 May 2009 22:03:42 -0400 (EDT)
commit fe96f29b9c1500b707a39d25316dab60114d2729
Author: Jesse van den Kieboom <jesse icecrew nl>
Date: Thu May 21 22:14:18 2009 +0200
Improved external tool process handling
No longer use shell. This ensures that when the tool is cancelled/terminated, there is
no child process left running. Bind STDERR to STDOUT if both should be used (this will ensure
more consistent output). Lastly, if killing the tool cleanly does not work, a second cancellation
will end the process with SIGKILL.
---
plugins/externaltools/tools/capture.py | 32 +++++++++++++++++++++++---------
1 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/plugins/externaltools/tools/capture.py b/plugins/externaltools/tools/capture.py
index f5bd846..be0fe3f 100644
--- a/plugins/externaltools/tools/capture.py
+++ b/plugins/externaltools/tools/capture.py
@@ -66,19 +66,29 @@ class Capture(gobject.GObject):
# Initialize pipe
popen_args = {
'cwd' : self.cwd,
- 'shell': True,
+ 'shell': False,
'env' : self.env
}
-
+
if self.input_text is not None:
popen_args['stdin'] = subprocess.PIPE
if self.flags & self.CAPTURE_STDOUT:
popen_args['stdout'] = subprocess.PIPE
if self.flags & self.CAPTURE_STDERR:
- popen_args['stderr'] = subprocess.PIPE
-
- self.pipe = subprocess.Popen(self.command, **popen_args)
+ if self.flags & self.CAPTURE_STDOUT:
+ popen_args['stderr'] = subprocess.STDOUT
+ else:
+ popen_args['stderr'] = subprocess.PIPE
+ self.tried_killing = False
+
+ try:
+ self.pipe = subprocess.Popen(self.command, **popen_args)
+ except OSError, e:
+ self.pipe = None
+ self.emit('stderr-line', _('Could not execute command: %s') % (e, ))
+ return
+
# Signal
self.emit('begin-execute')
@@ -90,7 +100,7 @@ class Capture(gobject.GObject):
gobject.io_add_watch(self.pipe.stdout,
gobject.IO_IN | gobject.IO_HUP,
self.on_output)
- if self.flags & self.CAPTURE_STDERR:
+ elif self.flags & self.CAPTURE_STDERR:
gobject.io_add_watch(self.pipe.stderr,
gobject.IO_IN | gobject.IO_HUP,
self.on_output)
@@ -101,7 +111,7 @@ class Capture(gobject.GObject):
def on_output(self, source, condition):
line = source.readline()
- if len(line) > 0:
+ if self.pipe and len(line) > 0:
try:
line = unicode(line, 'utf-8')
except:
@@ -119,12 +129,16 @@ class Capture(gobject.GObject):
def stop(self, error_code = -1):
if self.pipe is not None:
- os.kill(self.pipe.pid, signal.SIGTERM)
- self.pipe = None
+ if not self.tried_killing:
+ os.kill(self.pipe.pid, signal.SIGTERM)
+ self.tried_killing = True
+ else:
+ os.killpg(self.pipe.pid, sigal.SIGKILL)
def on_child_end(self, pid, error_code):
# In an idle, so it is emitted after all the std*-line signals
# have been intercepted
gobject.idle_add(self.emit, 'end-execute', error_code)
+ self.pipe = None
# ex:ts=4:et:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]