glibc "login_tty()" 函数的代码解释: "open(ttyname)" 紧接着 "close()"
code explanation for glibc "login_tty()" function: "open(ttyname)" immediately followed by "close()"
我正在阅读 glibc 代码,特别是 login_tty 函数,我发现了一段对我来说意义不大的代码:
newfd = open (fdname, O_RDWR);
(void) close (newfd);
这个打开一个文件马上就关闭了,我想知道为什么
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);
}
我无法给出明确的答案,但它以某种方式试图使与 fd
关联的终端成为进程的 控制终端 。
如果您查看代码的第一个替代方案,它使用 ioctl
:TIOCSCTTY
。这一个记录为“使给定终端成为调用进程的控制终端。[...]”,例如参见this manpage。
您不理解的代码位于 TIOCSCTTY
ioctl 不可用时使用的替代部分。我只能猜测,在关闭所有标准文件描述符(0
到 2
)之后,打开一个 tty 文件可能会产生 副作用 控制终端。
根据 APUE(2005 年第 2 版)第 9.6 节 - 控制终端:
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.
我正在阅读 glibc 代码,特别是 login_tty 函数,我发现了一段对我来说意义不大的代码:
newfd = open (fdname, O_RDWR);
(void) close (newfd);
这个打开一个文件马上就关闭了,我想知道为什么
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);
}
我无法给出明确的答案,但它以某种方式试图使与 fd
关联的终端成为进程的 控制终端 。
如果您查看代码的第一个替代方案,它使用 ioctl
:TIOCSCTTY
。这一个记录为“使给定终端成为调用进程的控制终端。[...]”,例如参见this manpage。
您不理解的代码位于 TIOCSCTTY
ioctl 不可用时使用的替代部分。我只能猜测,在关闭所有标准文件描述符(0
到 2
)之后,打开一个 tty 文件可能会产生 副作用 控制终端。
根据 APUE(2005 年第 2 版)第 9.6 节 - 控制终端:
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 theO_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 ofTIOCSCTTY
(the third argument is a null pointer). The session cannot already have a controlling terminal for this call to succeed. (Normally, this call toioctl
follows a call tosetsid
, which guarantees that the process is a session leader without a controlling terminal.) The POSIX.1O_NOCTTY
flag to open is not used by BSD-based systems, except in compatibility-mode support for other systems.