import os
import sys
import string
from Tkinter import *
from ScrolledText import ScrolledText
from Dialog import Dialog
import signal

BUFSIZE = 512

class ShellWindow(ScrolledText):

    def __init__(self, master=None, shell=None, **cnf):
        if not shell:
            try:
                shell = os.environ['SHELL']
            except KeyError:
                shell = '/bin/sh'
            shell = shell + ' -i'
        args = string.split(shell)
        shell = args[0]

        apply(ScrolledText.__init__, (self, master), cnf)
        self.pos = '1.0'
        self.bind('<Return>', self.inputhandler)
        self.bind('<Control-c>', self.sigint)
        self.bind('<Control-t>', self.sigterm)
        self.bind('<Control-k>', self.sigkill)
        self.bind('<Control-d>', self.sendeof)

        self.pid, self.fromchild, self.tochild = spawn(shell, args)
        self.tk.createfilehandler(self.fromchild, READABLE,
                                  self.outputhandler)

    def outputhandler(self, file, mask):
        data = os.read(file, BUFSIZE)
        if not data:
            self.tk.deletefilehandler(file)
            pid, sts = os.waitpid(self.pid, 0)
            print 'pid', pid, 'status', sts
            self.pid = None
            detail = sts>>8
            cause = sts & 0xff
            if cause == 0:
                msg = "exit status %d" % detail
            else:
                msg = "killed by signal %d" % (cause & 0x7f)
                if cause & 0x80:
                    msg = msg + " -- core dumped"
            Dialog(self.master,
                   text=msg,
                   title="Exit status",
                   bitmap='warning',
                   default=0,
                   strings=('OK',))
            return
        self.insert(END, data)
        self.pos = self.index("end - 1 char")
        self.yview_pickplace(END)

    def inputhandler(self, *args):
        if not self.pid:
            self.no_process()
            return "break"
        self.insert(END, "\n")
        line = self.get(self.pos, "end - 1 char")
        self.pos = self.index(END)
        os.write(self.tochild, line)
        return "break"

    def sendeof(self, *args):
        if not self.pid:
            self.no_process()
            return "break"
        os.close(self.tochild)
        return "break"

    def sendsig(self, sig):
        if not self.pid:
            self.no_process()
            return "break"
        os.kill(self.pid, sig)
        return "break"

    def sigint(self, *args):
        return self.sendsig(signal.SIGINT)

    def sigquit(self, *args):
        return self.sendsig(signal.SIGQUIT)

    def sigterm(self, *args):
        return self.sendsig(signal.SIGTERM)

    def sigkill(self, *args):
        return self.sendsig(signal.SIGKILL)

    def no_process(self):
        Dialog(self.master,
               text="No active process",
               title="No process",
               bitmap='error',
               default=0,
               strings=('OK',))

MAXFD = 100     # Max number of file descriptors (os.getdtablesize()???)

def spawn(prog, args):
    p2cread, p2cwrite = os.pipe()
    c2pread, c2pwrite = os.pipe()
    pid = os.fork()
    if pid == 0:
        # Child
        for i in 0, 1, 2:
            try:
                os.close(i)
            except os.error:
                pass
        if os.dup(p2cread) <> 0:
            sys.stderr.write('popen2: bad read dup\n')
        if os.dup(c2pwrite) <> 1:
            sys.stderr.write('popen2: bad write dup\n')
        if os.dup(c2pwrite) <> 2:
            sys.stderr.write('popen2: bad write dup\n')
        for i in range(3, MAXFD):
            try:
                os.close(i)
            except:
                pass
        try:
            os.execvp(prog, args)
        finally:
            sys.stderr.write('execvp failed\n')
            os._exit(1)
    os.close(p2cread)
    os.close(c2pwrite)
    return pid, c2pread, p2cwrite

def test():
    shell = string.join(sys.argv[1:])
    root = Tk()
    root.minsize(1, 1)
    if shell:
        w = ShellWindow(root, shell=shell)
    else:
        w = ShellWindow(root)
    w.pack(expand=1, fill=BOTH)
    w.focus_set()
    w.tk.mainloop()

if __name__ == '__main__':
    test()
