【问题标题】:how to open /dev/console in C如何在 C 中打开 /dev/console
【发布时间】:2015-05-17 08:44:04
【问题描述】:

我正在阅读 Wayland/weston 代码,即设置 tty 部分。我发现它试图获取一个可用的 tty 来执行 KMS 并启动 windows。

它是这样做的:

    if (!wl->new_user) {
            wl->tty = STDIN_FILENO;
    } else if (tty) {
            t = ttyname(STDIN_FILENO);
            if (t && strcmp(t, tty) == 0)
                    wl->tty = STDIN_FILENO;
            else
                    wl->tty = open(tty, O_RDWR | O_NOCTTY);
    } else {
            int tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
            char filename[16];

            if (tty0 < 0)
                    error(1, errno, "could not open tty0");

            if (ioctl(tty0, VT_OPENQRY, &wl->ttynr) < 0 || wl->ttynr == -1)
                    error(1, errno, "failed to find non-opened console"); 

            snprintf(filename, sizeof filename, "/dev/tty%d", wl->ttynr);
            wl->tty = open(filename, O_RDWR | O_NOCTTY);
            close(tty0);
    }

在 src/weston-launch.c.

它会尝试open('/dev/tty0') 并在未指定 tty 时找到可用的 tty。

但你不能那样做,/dev/tty0 和 'available tty' 都不属于你。我用我更简单的版本进行了测试。当然我打不开/dev/tty0

你们知道这个魔法是怎么做到的吗?

【问题讨论】:

    标签: c tty


    【解决方案1】:

    tty 的实际可用 设备取决于系统。在大多数交互式 Unix/类 Unix 系统上,您将拥有一个“tty”,其名称可以从命令行程序 tty 中找到。例如:

    $ tty
    /dev/pts/2
    

    您可能还有一个名为“tty”的设备,例如,

    $ ls -l /dev/tty
    lrwxrwxrwx   1 root     other         26 Feb  9  2014 /dev/tty -> ../devices/pseudo/sy@0:tty
    $ ls -lL /dev/tty
    crw-rw-rw-   1 root     tty       22,  0 Feb  9  2014 /dev/tty
    

    您不能只打开 任何 tty 设备,因为它们中的大多数都归 root(或分配给他们的其他用户)所有。

    如需进一步讨论/dev/console/dev/tty 和其他 tty 设备之间的区别,请参阅Cannot open /dev/console

    根据console_codes(4)手册页:

    VT_OPENQRY

    返回第一个可用(未打开)的控制台。 argp 指向一个 int,它设置为 vt 的编号 (1

    例如在 Linux 系统上,我在 /dev 中看到了这一点:

    crw-rw-rw-   1 root        5,  0 Mon 04:20:13   tty
    crw-------   1 root        4,  0 Mon 03:58:52   tty0
    crw-------   1 root        4,  1 Mon 04:00:41   tty1  
    crw-------   1 tom         4,  2 Mon 04:30:31   tty2
    crw-------   1 root        4,  3 Mon 04:00:41   tty3
    crw-------   1 root        4,  4 Mon 04:00:41   tty4
    crw-------   1 root        4,  5 Mon 04:00:41   tty5
    crw-------   1 root        4,  6 Mon 04:00:41   tty6
    crw-------   1 root        4,  7 Mon 03:58:52   tty7
    crw-------   1 root        4,  8 Mon 03:58:52   tty8
    crw-------   1 root        4,  9 Mon 03:58:52   tty9
    crw-------   1 root        4, 10 Mon 03:58:52   tty10  
    crw-------   1 root        4, 11 Mon 03:58:52   tty11
    

    所有这些tty 设备除了我已经打开控制台会话的设备都归root所有。为了能够登录到其中,getty 之类的程序会临时更改其所有权。例如,在我的机器上执行ps 显示

    root      2977     1  0 04:00 tty1     00:00:00 /sbin/getty 38400 tty1          
    root      2978     1  0 04:00 tty2     00:00:00 /bin/login --                   
    root      2979     1  0 04:00 tty3     00:00:00 /sbin/getty 38400     tty3          
    root      2980     1  0 04:00 tty4     00:00:00 /sbin/getty 38400 tty4          
    root      2981     1  0 04:00 tty5     00:00:00 /sbin/getty 38400 tty5          
    root      2982     1  0 04:00 tty6     00:00:00 /sbin/getty 38400 tty6
    

    请注意,gettyroot 身份运行。这使它有权根据需要更改 tty 设备的所有权。也就是说,虽然 ioctl 可能 识别未使用的 tty,但您需要提升权限才能真正打开它。 Linux(与任何其他类 Unix 系统一样)无法确保一个进程真正独占访问终端。所以它使用设备所有权和权限来确保这种访问。

    【讨论】:

    • 但是我可以通过ioctl(fd, VT_OPENQRY, &amp;num) 了解一个可用的 tty。如果我不能控制终端,为什么linux提供这个ioctl?
    • 任何可以读写的 tty 都是“可用的”。示例代码假定它是一个特定的名称——这看起来很奇怪,因为大多数系统最后使用至少两个字符,而不是一个字符。
    • 顺便问一下,除了ttyname(STDIN_FILENO)之外,我怎样才能知道C中的当前tty呢
    • 对不起,误用了“可用”,我的意思是“未被其他人使用”。
    【解决方案2】:

    如果您不是超级用户,那么您应该只尝试访问/dev/tty。这是控制当前进程的任何 tty 的特殊设备同义词。

    【讨论】:

    • 是的,我昨天调试了韦斯顿的代码,open('dev/tty0') 永远不会运行。如果它运行它也会失败。
    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2022-07-27
    • 2021-06-26
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多