[kupfer] Extend AsyncCommand to capture stderr
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] Extend AsyncCommand to capture stderr
- Date: Wed, 5 May 2010 21:39:29 +0000 (UTC)
commit b6123eacff498f96196a395054417353f69090f3
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Wed May 5 22:50:17 2010 +0200
Extend AsyncCommand to capture stderr
(And fix 'signal' module errors, and make all methods private)
kupfer/plugin/commands.py | 4 ++--
kupfer/utils.py | 42 ++++++++++++++++++++----------------------
2 files changed, 22 insertions(+), 24 deletions(-)
---
diff --git a/kupfer/plugin/commands.py b/kupfer/plugin/commands.py
index c1edbb8..83c2b63 100644
--- a/kupfer/plugin/commands.py
+++ b/kupfer/plugin/commands.py
@@ -44,9 +44,9 @@ class GetOutput (Action):
acom = utils.AsyncCommand(argv, self.finish_callback, 15)
acom.token = token
- def finish_callback(self, acommand, output):
+ def finish_callback(self, acommand, stdout, stderr):
ctx = commandexec.DefaultActionExecutionContext()
- leaf = TextLeaf(kupferstring.fromlocale(output))
+ leaf = TextLeaf(kupferstring.fromlocale(stdout))
ctx.register_late_result(acommand.token, leaf)
def get_description(self):
diff --git a/kupfer/utils.py b/kupfer/utils.py
index 69bd5b4..b1c3e1b 100644
--- a/kupfer/utils.py
+++ b/kupfer/utils.py
@@ -2,6 +2,7 @@ import itertools
import os
from os import path as os_path
import locale
+import signal
import gobject
import glib
@@ -76,8 +77,6 @@ def _argv_to_locale(argv):
for A in argv]
class AsyncCommand (object):
- # the maximum input (bytes) we'll read in one shot (one io_callback)
- max_input_buf = 512 * 1024
"""
Run a command asynchronously (using the GLib mainloop)
@@ -85,11 +84,14 @@ class AsyncCommand (object):
when command is killed after @timeout_s seconds, whichever
comes first.
- finish_callback -> (AsyncCommand, stdout_output)
+ finish_callback -> (AsyncCommand, stdout_output, stderr_output)
"""
+ # the maximum input (bytes) we'll read in one shot (one io_callback)
+ max_input_buf = 512 * 1024
def __init__(self, argv, finish_callback, timeout_s):
self.stdout = []
+ self.stderr = []
self.timeout = False
self.killed = False
self.finished = False
@@ -98,40 +100,36 @@ class AsyncCommand (object):
argv = _argv_to_locale(argv)
pretty.print_debug(__name__, "AsyncCommand:", argv)
- flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_STDERR_TO_DEV_NULL |
- glib.SPAWN_DO_NOT_REAP_CHILD)
+ flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
pid, stdin_fd, stdout_fd, stderr_fd = \
glib.spawn_async(argv, standard_output=True, standard_input=True,
- child_setup=self.child_setup, flags=flags)
+ standard_error=True, flags=flags)
os.close(stdin_fd)
- glib.io_add_watch(stdout_fd, glib.IO_IN | glib.IO_ERR |
- glib.IO_HUP | glib.IO_NVAL,
- self.io_callback)
+ io_flags = glib.IO_IN | glib.IO_ERR | glib.IO_HUP | glib.IO_NVAL
+ glib.io_add_watch(stdout_fd, io_flags, self._io_callback, self.stdout)
+ glib.io_add_watch(stderr_fd, io_flags, self._io_callback, self.stderr)
self.pid = pid
- glib.child_watch_add(pid, self.child_callback)
- glib.timeout_add_seconds(timeout_s, self.timeout_callback)
-
- def child_setup(self):
- pass
+ glib.child_watch_add(pid, self._child_callback)
+ glib.timeout_add_seconds(timeout_s, self._timeout_callback)
- def io_callback(self, sourcefd, condition):
+ def _io_callback(self, sourcefd, condition, databuf):
if condition & glib.IO_IN:
- self.stdout.append(os.read(sourcefd, self.max_input_buf))
+ databuf.append(os.read(sourcefd, self.max_input_buf))
return True
return False
- def child_callback(self, pid, condition):
+ def _child_callback(self, pid, condition):
self.finished = True
- self.finish_callback(self, "".join(self.stdout))
+ self.finish_callback(self, "".join(self.stdout), "".join(self.stderr))
- def timeout_callback(self):
+ def _timeout_callback(self):
"send term signal on timeout"
if not self.finished:
self.timeout = True
- os.kill(self.pid, 15)
- glib.timeout_add_seconds(2, self.kill_callback)
+ os.kill(self.pid, signal.SIGTERM)
+ glib.timeout_add_seconds(2, self._kill_callback)
- def kill_callback(self):
+ def _kill_callback(self):
"Last resort, send kill signal"
if not self.finished:
self.killed = True
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]