2015-05-17 79 views
1

我正在读wayland/weston代码,设置tty部分。我发现它试图获得一个可用的tty来完成KMS并启动Windows。如何打开/ dev/console在C

这是怎么回事呢:

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 /韦斯顿launch.c。

它试图打开('/ dev/tty0')并找到一个可用的tty,如果没有指定tty的话。

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

你们知道这个魔法是如何完成的吗?感谢您的帮助:)

回答

2

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

$ tty 
/dev/pts/2 

有可能的,你也有一个设备命名为 “TTY”,例如,

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

你不能打开刚才任何 tty设备,因为他们大多是由国有(或他们已被分配到的其他用户)。

有关/dev/console/dev/tty等TTY设备之间的差异进一步讨论,参见Cannot open /dev/console

按照console_codes(4)手册页:

VT_OPENQRY

返回第一个可用的(未开通)控制台。 argp指向一个int,它被设置为vt的数量(1 < = * argp 01​​= MAX_NR_CONSOLES)。

,并在/dev例如Linux系统中我看到这样的:

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设备为我所用开根拥有的控制台会话。为了能够登录到其中,程序(如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 

注意getty运行为。这使其有权根据需要更改tty设备的所有权。也就是说,虽然ioctl 可能会在标识一个未使用的tty,但您需要提升特权才能真正打开它。Linux(像任何其他类似Unix的系统)没有办法提供确保一个进程真正独占访问终端的途径。所以它使用设备所有权和权限来确保访问。

+0

但我可以通过'ioctl(fd,VT_OPENQRY,#)知道一个可用的tty'。如果我无法控制终端,为什么linux提供这个ioctl? – Xeechem

+0

您可以读取和写入的任何tty都是“可用的”。示例代码假设它是一个特定的名称 - 这看起来很奇怪,因为大多数系统最终使用至少两个字符,而不是单个字符。 –

+0

顺便说一句,我怎么才能知道当前tty除了'ttyname(STDIN_FILENO)' – Xeechem

3

如果你不是超级用户,那么你应该只尝试访问/dev/tty。对于任何tty控制当前过程而言,这是一个特殊的设备同义词。

+1

是啊,我昨天调试了weston的代码,'open('dev/tty0')'永远不会运行。如果它运行,它也会失败。 – Xeechem