Terminal virtual mana yang merupakan proses X yang dijalankan?


8

Ketika X dimulai, ia mencari VT terendah yang tidak terpakai, dan menempel padanya. Masalah saya adalah ketika ada beberapa proses X yang sedang berjalan, saya harus dapat mengidentifikasi yang mana yang sedang aktif.

Ini adalah * pertanyaan BSD, karena di linux itu mudah: X mengatur terminal pengendali menjadi ttyN, atau, pada distribusi yang sangat lama, itu ditentukan pada commandline sebagai vtN. Jadi, saya menjalankan layanan dan saya melihat bahwa VT yang saat ini aktif adalah tty7, dan ada dua server X yang berjalan, mudah untuk mengetahui mana yang sesuai dengan terminal saat ini. (Ini adalah kasus yang masuk akal: mungkin pengguna menggunakan fungsionalitas 'pengguna beralih' GNOME / KDE atau menjalankan dua server menggunakan startx.) Contoh aplikasi yang mungkin ingin mengikuti server X aktif adalah x11vnc(yang bercabang dari perangkat lunak yang saya kembangkan ).

Pada FreeBSD, terminal pengendali tidak memberi tahu Anda apa-apa. Ketika X dimulai dari ttyv1, itu tetap merupakan terminal pengendali.

Memperbarui

Saya telah melakukan uji tuntas dan membaca kode X. Setelah beberapa berburu, sekarang lebih jelas bagi saya apa yang terjadi.

Di lnx_init.c , server X tidak setsidmembuat sesi baru untuk dirinya sendiri, kemudian membuka fd untuk ttyNlangsung setelah melakukan VT_ACTIVATEioctl di atasnya. Cukup standar; membuka fd ke terminal tanpa proses pengontrolan dari proses tanpa terminal pengontrol menghubungkan keduanya, dan server membuat fd tetap terbuka, sehingga dijamin bahwa terminal akan tetap menjadi terminal pengendali untuk server X.

Sekarang, di bsd_init.c , membuka fd ke tty untuk digunakan sebagai framebuffer tidak menjadikannya terminal pengendali (dan bahkan, tanpa setsid, BSD Xserver mulai dari xinitttyv2 akan menjadikan ttyv2 sebagai ctty!).

Pertanyaan selanjutnya diperbarui dan dibersihkan pada 2012-04-09.

Jawaban:


3

Ada cara yang lebih umum. Pada semua platform dengan terminal virtual, termasuk linux dan BSD, Xserver mempertahankan fd terbuka ke terminal yang sedang berjalan. Di linux, tetap merupakan solusi yang baik untuk memeriksa terminal pengendali proses X untuk membedakan antara beberapa proses X (gunakan bidang ketujuh /proc/<..>/stat). Lebih umum lagi, lihatlah daftar fds terbuka dari proses X, dan hanya perlu beberapa penyaringan sederhana untuk keluar dari terminal yang dijalankan oleh Xserver. (Sayangnya, mendapatkan daftar open fds lagi tergantung pada platform ...) Untuk sysctlplatform seperti BSD, kode akan terlihat mirip dengan ini, ditambah beberapa penanganan kesalahan:

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;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.