"Hijack" other programs stdin & stdout

Hi,
I'm working on an address book program in python (pycarddav) for use with mail/mutt, which has the ability to add email address directly from mutt. I use devel/py-urwid, an ncurses like console UI kit which needs to write to stdout. On Linux we use the /proc fs to walk up the program's parents until we find one that is connected to a TTY and than use its stdin, stdout and stderr.

I would also like to do this on FreeBSD. How could we:
  1. find the parent process which is connected to a TTY? (Is there anything better than parsing ps's output?)
  2. use this process's stdin etc?

For reference purposes I'm attaching the relevant Linux centric code.

Thanks for your input!


Code:
def capture_tty():                                                                 
    """Walk the parent processes until a TTY is found.                             
                                                                                   
    See http://stackoverflow.com/questions/1728330/how-to-get-processs-grandparent-id
    """                                                                            
    pid = 'self'                                                                   
    input_file = sys.stdin                                                         
    while not input_file.isatty():                                                 
        with open('/proc/%s/status' % pid) as f:                                   
            for line in f:                                                         
                if line.startswith('PPid:'):                                       
                    _, _, pid = line.rpartition("\t")                              
                    pid = pid.rstrip()                                             
                    input_file = open('/proc/%s/fd/0' % pid)                       
                    break                                                          
            else:                                                                  
                raise RuntimeError('cannot find parent of %s' % pid)               
                                                                                   
    if pid != 'self':                                                              
        sys.stdin = input_file                                                     
        sys.stdout = open('/proc/%s/fd/1' % pid, 'wb')                             
        sys.stderr = open('/proc/%s/fd/2' % pid, 'wb')                             
                                                                                   
        os.dup2(sys.stdin.fileno(), 0)                                             
        os.dup2(sys.stdout.fileno(), 1)                                            
        os.dup2(sys.stderr.fileno(), 2)                                            
        print sys.stdout.fileno()                                                  
                                                                                   
                                                                                   
                                                                                   
def release_tty():                                                                 
    sys.stdin.close()                                                              
    sys.stdout.close()                                                             
    sys.stderr.close()
 
Try sysutils/py-psutil.
Code:
$ sleep 99999 &
[1] 14884

$ python2
>>> import psutil
>>> psutil.Process(pid=14884).ppid
1159
>>> psutil.Process(pid=14884).terminal
'/dev/pts/5'
>>> psutil.Process(pid=14884).get_open_files()
[openfile(path='/bin/sleep', fd=-5)]
 
oops said:
Try sysutils/py-psutil.
Code:
$ sleep 99999 &
[1] 14884

$ python2
>>> import psutil
>>> psutil.Process(pid=14884).ppid
1159
>>> psutil.Process(pid=14884).terminal
'/dev/pts/5'
>>> psutil.Process(pid=14884).get_open_files()
[openfile(path='/bin/sleep', fd=-5)]
This looks awesome, looks like we only need one implementation after all.

Thanks! I'll let you guys know how it works out.
 
Thanks, psutils does the trick perfectly and platform independent (only tested FreeBSD & Linux).
 
Am I misunderstanding something or can you just open /dev/tty instead of doing complicated process tree walks?
 
jilles@ said:
Am I misunderstanding something or can you just open /dev/tty instead of doing complicated process tree walks?

But how do I know which /dev/ttyX is the right one?
 
Back
Top