Search code examples
linuxprocessfile-descriptorioctlpty

File descriptor for ioctl call to make a controlling terminal


On linux to be able to control lifetime of processes forked off of my main process I'm making the main process be the session and group leader by calling setsid(). Then it looks like I need to have the main process make a controlling terminal for the process group, and then, once the main process terminates, all other processes in the process group will receive a SIGHUP. I tried calling open() for a regular file on the filesystem, but ioctl() refuses to accept this fd with 'Inappropriate file descriptor'. Is posix_openpt() what I should be using instead? The man page says that it'll create a pseudo-terminal and return a file descriptor for it. Do I even need an ioctl(fd, TIOCSCTTY, 0) call after posix_openpt(), or not using O_NOCTTY is all I really need? Thanks!


Solution

  • Do I even need an ioctl(fd, TIOCSCTTY, 0) call after posix_openpt(), or not using O_NOCTTY is all I really need?

    I just tried on Ubuntu 18.04.5:

    If you don't do that and the controlling process is closed, the systemd process becomes the new controlling process of the child process and the child process does not receive SIGHUP.

    I'm not sure if this behavior is the same for other Linux distributions, too.

    Is posix_openpt() what I should be using instead?

    Try the following code:

    int master, tty;
    
    master = posix_openpty(O_RDWR);
    grantpt(master);
    unlockpt(master);
    tty = open(ptsname(master), O_RDWR);
    ioctl(tty, TIOCSCTTY, 0);
    

    This must be done in the same process that called setsid().

    Note: As soon as you completely close the master file, the processes will receive a SIGHUP.

    ("Completely" means: When you close all copies created by dup() or by creating a child process inheriting the handle.)

    If you really want to use the pseudo-TTY, you should not inherit the master handle to child processes (or close() the handle in a child process. However, in your case you only want to use the pseudo-TTY as "workaround", so this is not that important.