clinuxglibcttypts

code explanation for glibc "login_tty()" function: "open(ttyname)" immediately followed by "close()"


I was reading the glibc code, specifically the login_tty function, and I found a piece of code that did not make much sense to me:

newfd = open (fdname, O_RDWR);
(void) close (newfd);

this opens a file and closes it immediately, I want to know why

complete function code:

int
login_tty (int fd)
{
        (void) setsid();
#ifdef TIOCSCTTY
        if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
                return (-1);
#else
        {
          /* This might work.  */
          char *fdname = ttyname (fd);
          int newfd;
          if (fdname)
            {
              if (fd != 0)
                (void) close (0);
              if (fd != 1)
                (void) close (1);
              if (fd != 2)
                (void) close (2);
              newfd = open (fdname, O_RDWR);
              (void) close (newfd);
            }
        }
#endif
        while (dup2(fd, 0) == -1 && errno == EBUSY)
          ;
        while (dup2(fd, 1) == -1 && errno == EBUSY)
          ;
        while (dup2(fd, 2) == -1 && errno == EBUSY)
          ;
        if (fd > 2)
                (void) close(fd);
        return (0);
}

Solution

  • According to APUE (2nd edition, 2005), Section 9.6 - Controlling Terminal:

    POSIX.1 leaves the choice of the mechanism used to allocate a controlling terminal up to each individual implementation. We’ll show the actual steps in Section 19.4.

    Systems derived from UNIX System V allocate the controlling terminal for a session when the session leader opens the first terminal device that is not already associated with a session. This assumes that the call to open by the session leader does not specify the O_NOCTTY flag (Section 3.3).

    BSD-based systems allocate the controlling terminal for a session when the session leader calls ioctl with a request argument of TIOCSCTTY (the third argument is a null pointer). The session cannot already have a controlling terminal for this call to succeed. (Normally, this call to ioctl follows a call to setsid, which guarantees that the process is a session leader without a controlling terminal.) The POSIX.1 O_NOCTTY flag to open is not used by BSD-based systems, except in compatibility-mode support for other systems.