Mailing List Archive

subprocess: TTYs and preexec_fn
Hello!

I'm trying to run a subprocess (actually several), and control
their terminals (not just stdin and stdout). I have a use case,
but I won't bore everyone with those details.

I'd rather not use pexpect or ptyprocess, because those expose a
very different interface than Popen. I've mostly acheived my
goals with the following wrapper around subprocess:


> import subprocess, pty, fcntl, termios, os
> TTY = 'termyTTY'
>
> def Popen(cmd, **kwargs):
> tty = kwargs.pop('tty', None)
> if tty is not None:
> if tty is True:
> tty = pty.openpty()
> master_fd, slave_fd = tty
> old_preexec = kwargs.get('preexec_fn')
> def preexec_fn():
> if old_preexec:
> old_preexec()
> fcntl.ioctl(slave_fd, termios.TIOCSCTTY)
> kwargs['preexec_fn'] = preexec_fn
> kwargs['start_new_session'] = True
> for stkind in ('stdin', 'stdout', 'stderr'):
> if kwargs.get(stkind, None) != TTY:
> continue
> kwargs[stkind] = slave_fd
>
> proc = subprocess.Popen(cmd, **kwargs)
> if tty is not None:
> proc.tty = master_fd
> os.close(slave_fd)
> return proc


This adds a tty keyword argument that spawns a new controlling TTY
and switches the new process to it. It also allows setting stdin/etc.
separately. You can, for instance, run ssh and send it a password through
the tty channel, and separately receive piped output from the remote ssh
command.

My questions:

1. Is this already available in a simple way somewhere else, preferably with a
Popen-compatible interface?

2. Is this preexec_fn sufficiently simple that it does not run afoul of the
big, scary threading warning of _posixsubprocess.fork_exec ? I.e., I'm
not touching any locks (besides the GIL... but I'm assuming that would be properly
handled?). CAN this be made safe? I do plan to use threads and locks.

3. Does this seem widely useful enough to be worth trying to get into Python
itself? It would be nice if this specific behavior, which probably has even
more nuances than I already am aware of, were safely achievable out of the
box.

Best,
Antonio
--
https://mail.python.org/mailman/listinfo/python-list