--- /dev/null
+#!/usr/bin/env python
+
+# This software is copyright Neil Brown 2009.
+# It is licensed to you under the terms of the
+# GNU General Public License version 2.
+#
+# run a program given on args.
+#
+# TODO:
+# Make it easier to scroll.
+# Maybe don't require 'sh -c' for scripts
+# Kill off children on exit
+
+import os,sys,fcntl
+import gtk,pango, gobject
+from subprocess import Popen, PIPE
+
+class Runit(gtk.Window):
+ def __init__(self, args):
+ gtk.Window.__init__(self)
+ self.set_default_size(480, 640)
+ self.create_ui()
+ self.show()
+ self.args = args
+ if args[0] == 'sh' and args[1] == '-c':
+ self.set_title(args[2])
+ else:
+ self.set_title(args[0])
+ self.run()
+
+
+ def run(self):
+ self.pipe = Popen(self.args,
+ stdout=PIPE, stderr=PIPE,
+ close_fds = True)
+
+ def set_noblock(f):
+ flg = fcntl.fcntl(f, fcntl.F_GETFL, 0)
+ fcntl.fcntl(f, fcntl.F_SETFL, flg | os.O_NONBLOCK)
+ set_noblock(self.pipe.stdout)
+ set_noblock(self.pipe.stderr)
+ self.wc = gobject.child_watch_add(self.pipe.pid, self.done)
+ self.wout = gobject.io_add_watch(self.pipe.stdout, gobject.IO_IN, self.read)
+ self.werr = gobject.io_add_watch(self.pipe.stderr, gobject.IO_IN, self.read)
+
+ def create_ui(self):
+ v = gtk.VBox()
+ self.add(v)
+ v.show()
+
+ h = gtk.HBox(); h.show()
+ v.pack_end(h, expand=False)
+
+ b = gtk.Button('EXIT');
+ fd = pango.FontDescription('sans 20')
+ fd.set_absolute_size(19 * pango.SCALE)
+ b.child.modify_font(fd)
+ h.add(b)
+ b.connect('clicked', self.close)
+ b.show()
+
+ b = gtk.Button('RERUN');
+ b.child.modify_font(fd)
+ h.add(b)
+ b.connect('clicked', self.rerun)
+
+ self.rerunb = b
+
+ sw = gtk.ScrolledWindow(); sw.show()
+ sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ v.add(sw)
+
+ tv = gtk.TextView()
+ sw.add(tv)
+ tv.modify_font(fd)
+ tv.set_wrap_mode(gtk.WRAP_CHAR)
+
+ self.buff = tv.get_buffer()
+
+ tv.show()
+
+ def read(self, f, dir):
+ l = f.read()
+ self.buff.insert(self.buff.get_end_iter(), l)
+ if l == "":
+ return False
+ return True
+
+ def done(self, *a):
+ self.rerunb.show()
+ def set_block(f):
+ flg = fcntl.fcntl(f, fcntl.F_GETFL, 0)
+ fcntl.fcntl(f, fcntl.F_SETFL, flg & ~ os.O_NONBLOCK)
+ self.read(self.pipe.stdout, None)
+ self.read(self.pipe.stderr, None)
+ gobject.source_remove(self.wout)
+ gobject.source_remove(self.werr)
+ self.pipe.stdout.close()
+ self.pipe.stderr.close()
+ self.pipe = None
+
+ def close(self, *a):
+ gtk.main_quit()
+
+ def rerun(self, *a):
+ self.rerunb.hide()
+ self.buff.insert(self.buff.get_end_iter(), "------------------------------------------------------------------\n")
+ self.run()
+
+
+def main(args):
+ Runit(args[1:])
+ gtk.main()
+
+if __name__ == '__main__':
+ main(sys.argv)
+
+