#!/usr/bin/env python
import os,popen2,fcntl,sys,select,threading,time

BUFLEN = 8192

def makeNonBlocking(fd):
    """ Make a file descriptor non-blocking """
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

def runCommand(cmd):
    """ 
    Internal function to run a specific command using Popen3
    """
    prc = popen2.Popen3(cmd,BUFLEN)
    inFd  = prc.tochild.fileno()
    outFd = prc.fromchild.fileno()
    errFd = prc.childerr.fileno()
    makeNonBlocking(inFd)
    makeNonBlocking(outFd)
    makeNonBlocking(errFd)
    inChunk = ""
    inWaits = [inFd,]
    outWaits = [outFd, errFd]
    while outWaits:
        ready = select.select(outWaits,inWaits,[])
        if inFd in ready[1]:
            inChunk += sys.stdin.read(BUFLEN)
            if inChunk == '':
                prc.tochild.close()
                inWaits.remove(inFd)
            else:
                count = os.write(inFd,inChunk)
                inChunk = inChunk[count:]
        if outFd in ready[0]:
            outChunk = os.read(outFd,BUFLEN)
            if outChunk == '':
                prc.fromchild.close()
                outWaits.remove(outFd)
            else:
                sys.stdout.write(outChunk)
        if errFd in ready[0]:
            errChunk = os.read(errFd,BUFLEN)
            if errChunk == '':
                prc.childerr.close()
                outWaits.remove(errFd)
            else:
                sys.stderr.write(errChunk)
    xcode = prc.wait()
    sys.stderr.write("'%s' returned %d.\n" % (cmd,os.WEXITSTATUS(xcode)))

cmd = ' '.join(sys.argv[1:])
#runCommand(cmd)
threading.Thread(target=runCommand,args=(cmd,)).start()
