Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
glibc“login_tty()”函数的代码解释:“open(ttyname)”紧接着“close()”_C_Linux_Glibc_Tty_Pts - Fatal编程技术网

glibc“login_tty()”函数的代码解释:“open(ttyname)”紧接着“close()”

glibc“login_tty()”函数的代码解释:“open(ttyname)”紧接着“close()”,c,linux,glibc,tty,pts,C,Linux,Glibc,Tty,Pts,我正在阅读glibc代码,特别是login_tty函数,我发现一段代码对我来说意义不大: newfd = open (fdname, O_RDWR); (void) close (newfd); 这会打开一个文件并立即关闭,我想知道原因 : 我不能给出一个明确的答案,但不知何故,它试图使与fd关联的终端成为进程的控制终端 如果您看一下代码的第一个备选方案,它将使用ioctl:TIOCSCTTY。这一个被记录为使给定终端成为呼叫过程的控制终端。[…],参见示例 如果TIOCSCTTY ioctl

我正在阅读glibc代码,特别是login_tty函数,我发现一段代码对我来说意义不大:

newfd = open (fdname, O_RDWR);
(void) close (newfd);
这会打开一个文件并立即关闭,我想知道原因

:


我不能给出一个明确的答案,但不知何故,它试图使与fd关联的终端成为进程的控制终端

如果您看一下代码的第一个备选方案,它将使用ioctl:TIOCSCTTY。这一个被记录为使给定终端成为呼叫过程的控制终端。[…],参见示例

如果TIOCSCTTY ioctl不可用,您不理解的代码将出现在替代部分中。我只能猜测,在关闭所有标准文件描述符0到2之后,打开一个tty文件可能会产生副作用,使其成为控制终端。

根据2005年第二版第9.6节-控制终端:

POSIX.1将用于分配一个控制终端的机制的选择留给每个用户 个别实施。我们将在第19.4节中展示实际步骤

从UNIX System V派生的系统在以下情况下为会话分配控制终端: 会话引导程序打开尚未与会话关联的第一个终端设备。这 假定会话负责人对open的调用未指定O_NOCTTY标志 第3.3节

基于BSD的系统在会话负责人呼叫时为会话分配控制终端 请求参数为TIOCSCTTY的ioctl第三个参数是空指针。这个 会话不能已经有控制终端,此调用才能成功。通常,这个电话 to ioctl紧跟着对setsid的调用,这保证了进程是一个会话领导者 没有控制终端。要打开的POSIX.1 O_NOCTTY标志未被使用 基于BSD的系统,其他系统的兼容模式支持除外


也许碰一下,我。E将其文件时间设置为现在?我想这与将fd作为控制终端有关,如前所述,因为这正是ioctl调用试图做的。请尝试使您的问题独立,这包括引用所有相关代码,只要它合理简短-我在这里为您做的。
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);
}