NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

posix_spawn(), openpty(), and login_tty()



Python 3.8 adds a shiny new toy - a binding to posix_spawn().  I
figured I'd try it as a more robust way of creating a child process
attached to a terminal.  While I happened to use Python, this is
really about NetBSD (and even apply to other code bases such as
GLIBC).  Forgive my pseudo Python/C ...

I'm trying to mimic something like:

    pty, tty = openpty()
    pid = fork()
    if pid is child:
       close stray fd's by magic, or set them CLOEXEC
       login_tty(tty) as in:
           setsid()
           ioctl(tty, TIOCSCTTY, NULL)
           redirect stdin, stdout, stderr, to tty and close tty
       exec ...
   close tty

In a program that has lots of threads and forks ....

The first problem I hit was with openpty(3) and "close stray fd's by
magic, or set them CLOEXEC":
openpty() returns descriptors that aren't CLOEXEC.  This means that,
even if my program was somehow 100% perfect and opened everything
CLOEXEC (Python seems to be trying to do this), I still need some sort
of "close stray FD's magic" so that a parallel fork() doesn't inherit
the pty/tty.  The magic I used was to wrap the openpty() call in a
lock and then force CLOEXEC on the FDs .....  Is there, or should
there be, something better?

The remaining problems are with emulating login_tty():

- posix_spawn() does setpgid(), not setsid(); at least not officially
Apparently setsid() both creates a new Session ID and then sets the
process group; while setpgid() only sets the process group.
Since setsid() has been "the new and preferred method for programs to
lose their controlling terminal" (tty(4)TIOCNOTTY) since the early
90's and GLIBC does support it I filed a bug suggesting it be added.

- posix_spawn() doesn't do ioctl(tty, TIOCSCTTY, NULL) at all
Per above, setsid() looses the old controlling terminal, and then this
call makes tty the new one.
But is this really needed, i.e.,  if it is missing what breaks?  I'm
guessing that sub-shells trying to do job control would fail, but
since I'm not doing that I'm not going to see problems ....
Should this be added as an extension to posix_spawn() as well?

Andrew


Home | Main Index | Thread Index | Old Index