Каким виртуальным терминалом является данный X-процесс?

Когда X запускается, он ищет самый низкий неиспользованный VT и присоединяется к нему. Моя проблема в том, что, когда есть несколько запущенных X-процессов, мне нужно определить, какой из них является активным в настоящий момент.

Это вопрос * BSD, потому что на linux легко: X устанавливает свой управляющий терминал как ttyN , или, в очень старых дистрибутивах, он указан в командной строке как vtN . Итак, я запускаю службу, и я вижу, что tty7 активный VT – tty7 , и есть два сервера X, и легко определить, какой из них соответствует текущему терминалу. (Это разумный случай: возможно, пользователь использовал функцию «переключить пользователя» GNOME / KDE или запустил два сервера с использованием startx .) Примерным приложением, которое может хотеть следить за активным X-сервером, является x11vnc (который x11vnc из программного обеспечения I ' м).

  • Предоставление разговора FreeBSD. Как произносится rc.conf?
  • Запуск нескольких xserver отображает «вне экрана» или «безголовый»
  • Как активировать режим AP в файлах конфигурации?
  • Не удается смонтировать USB на FreeBSD: неверный аргумент
  • BSD Books - Лучшие книги для OpenBSD и FreeBSD
  • Как использовать SSH-ключи для SSH без пароля через приложения X11 (например, nautilus)?
  • Однако на FreeBSD контрольный терминал ничего не говорит. Когда X запускается из ttyv1, это остается управляющим терминалом.

    Обновить

    Я сделал должную осмотрительность и прочитал код Х. После некоторой охоты, теперь стало яснее, что происходит.

    В lnx_init.c сервер X делает setsid для создания нового сеанса для себя, а затем открывает fd to ttyN прямо после того, как на нем будет VT_ACTIVATE ioctl. Довольно стандартный; открытие fd на терминал без управления процессом из процесса без управляющего терминала связывает два, и сервер держит fd открытым, поэтому гарантируется, что терминал останется управляющим терминалом для X-сервера.

    Теперь, в bsd_init.c , открытие fd в tty, которое будет использоваться в качестве фреймбуфера, не делает его управляющим терминалом (и, фактически, без setsid , BSD Xserver, запущенный с xinit на ttyv2, сохранит ttyv2 как его ctty! ).

    Вопрос уточнен и уточнен в 2012-04-09.

  • Как отключить определенные комбинации нажатий клавиш
  • настройка устройств ввода Xorg без udev
  • скопировал папку - получив различное используемое пространство в пункте назначения (используя FreeBSD и UFS)
  • xrandr не обнаруживает монитор на портах hdmi
  • Доступ к зашифрованному Luks диску от FreeBSD
  • Приложение получает SIGKILL при выключениях системы, почему не SIGTERM?
  • One Solution collect form web for “Каким виртуальным терминалом является данный X-процесс?”

    Существует более общий путь. На всех платформах с виртуальными терминалами, включая linux и BSD, Xserver сохраняет открытую fd для терминала, на котором он запущен. В linux остается хорошим решением проверить управляющий терминал процесса X на различение нескольких процессов X (используйте седьмое поле /proc/<..>/stat ). В более общем плане, просмотрите список открытых fds процесса X, и ему нужна только простая фильтрация, чтобы выйти из терминала, на котором работает 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; } 
    Linux и Unix - лучшая ОС в мире.