给定的X进程在哪个虚拟终端上运行?


8

X启动时,它将搜索未使用的最低VT并将其附加。我的问题是,当有多个正在运行的X进程时,我需要能够确定哪个进程是当前活动的进程。

这是一个* BSD问题,因为在Linux上很容易:X将其控制终端设置为ttyN,或者在非常旧的发行版中,将其在命令行上指定为vtN。因此,我正在运行一项服务,并且看到当前处于活动状态的VT为tty7,并且有两个正在运行的X服务器,很容易分辨出哪个与当前终端相对应。(这是一个合理的情况:也许用户使用了GNOME / KDE的“切换用户”功能,或者使用来运行两个服务器startx。)一个可能想要关注活动X服务器的示例应用程序是x11vnc(从我正在开发的软件中派生的) )。

但是在FreeBSD上,控制终端不会告诉您任何信息。当X从ttyv1启动时,它仍然是控制终端。

更新资料

我已经完成了尽职调查并阅读了X代码。经过一番摸索后,现在对我而言更清楚了。

lnx_init.c中,X服务器确实setsid为其进行了一个新的会话,然后打开一个fd以ttyN直接对其执行VT_ACTIVATEioctl。相当标准;从没有控制终端的进程向没有控制进程的终端打开fd会使两者关联,并且服务器使fd保持打开状态,因此可以确保终端将保留X服务器的控制终端。

现在,在bsd_init.c中,向要用作帧缓冲区的tty打开fd并不能使其成为控制终端(实际上,如果没有setsid,则从xinitttyv2 启动的BSD Xserver 会将ttyv2保留为其ctty!)。

问题已于2012-04-09进一步更新和清理。

Answers:


3

有更通用的方法。在所有带有虚拟终端的平台(包括linux和BSD)上,Xserver都会为其运行的终端保留一个开放的fd。在linux上,检查X进程的控制终端以区分多个X进程(使用的第七字段/proc/<..>/stat)仍然是一个很好的解决方案。不过,更一般而言,请查看X进程的打开的fds列表,它只需要进行一些简单的过滤即可了解运行Xserver的终端。(不幸的是,获取打开的fds的列表再次依赖于sysctl平台...)对于像BSD这样的平台,代码看起来与此类似,并加上一些错误处理:

int ttyByOpenFds(int curPid) {
    int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, curPid };
    size_t sizeGuess = 50*sizeof(kinfo_file);
    char* buf = malloc(sizeGuess);
    int rv = sysctl(ctl, 4, buf, &sizeGuess, 0, 0);
    if (rv < 0 && errno == ESRCH) return 0;
    else if (rv < 0 && errno == ENOMEM) { /* try again */ }
    else if (rv < 0) throw SystemException("unexpected error getting args", errno);

    char* position = buf;
    while (position < buf + sizeGuess) {
      kinfo_file* kfp = reinterpret_cast<kinfo_file*>(position);
      position += kfp->kf_structsize;
      if (kfp->kf_type != KF_TYPE_VNODE) continue;
      if (kfp->kf_vnode_type != KF_VTYPE_VCHR) continue;
      if (kfp->kf_fd < 0) continue;
      char* name = devname(kfp->kf_un.kf_file.kf_file_rdev, S_IFCHR);
      if (!name) continue;
      unsigned int ttynum = 0;
      if (sscanf(name, "ttyv%u", &ttynum) != 1) continue;
      if (ttynum < 8 && kfp->kf_fd <= 2) continue; // stderr going to a console
      return ttynum;
    }
    return 0;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.