Thiết bị đầu cuối ảo nào là một quy trình X đã cho chạy?


8

Khi X bắt đầu, nó tìm kiếm VT không sử dụng thấp nhất và gắn vào nó. Vấn đề của tôi là khi có một số quy trình X đang chạy, tôi cần có khả năng xác định cái nào đang hoạt động.

Đây là một câu hỏi * BSD, bởi vì trên linux thật dễ dàng: X đặt thiết bị đầu cuối kiểm soát của nó thành ttyN, hoặc, trên các bản phân phối rất cũ, nó được chỉ định trên dòng lệnh như vtN. Vì vậy, tôi đang chạy một dịch vụ và tôi thấy rằng VT hiện đang hoạt động tty7và có hai máy chủ X đang chạy, thật dễ dàng để biết cái nào tương ứng với thiết bị đầu cuối hiện tại. (Đây là một trường hợp hợp lý: có lẽ người dùng sử dụng chức năng 'người sử dụng chuyển đổi' GNOME / KDE hoặc chạy hai máy chủ sử dụng startx.) Một ứng dụng ví dụ mà có thể muốn làm theo các máy chủ X hoạt động là x11vnc(được chia hai từ phần mềm tôi đang phát triển ).

Mặc dù trên FreeBSD, thiết bị đầu cuối kiểm soát không cho bạn biết bất cứ điều gì. Khi X được bắt đầu từ ttyv1, đó vẫn là thiết bị đầu cuối kiểm soát.

Cập nhật

Tôi đã thực hiện thẩm định và đọc mã X. Sau một số cuộc săn lùng xung quanh, bây giờ nó rõ ràng hơn với tôi những gì đang diễn ra.

Trong lnx_init.c , máy chủ X sẽ setsidtự tạo một phiên mới, sau đó mở một fd để ttyNngay sau đó để thực hiện một VT_ACTIVATEioctl trên đó. Khá chuẩn; mở fd cho thiết bị đầu cuối không có quá trình kiểm soát từ quy trình không có thiết bị đầu cuối kiểm soát liên kết cả hai và máy chủ giữ fd mở, do đó đảm bảo rằng thiết bị đầu cuối sẽ vẫn là thiết bị đầu cuối kiểm soát cho máy chủ X.

Bây giờ, trong bsd_init.c , việc mở fd cho tty sẽ được sử dụng làm bộ đệm khung không biến nó thành thiết bị đầu cuối kiểm soát (và trên thực tế, không setsid, BSD Xserver bắt đầu từ xinittrên ttyv2 sẽ giữ ttyv2 làm ctty của nó!).

Câu hỏi tiếp tục được cập nhật và làm sạch vào ngày 2012-04-09.

Câu trả lời:


3

Có một cách tổng quát hơn. Trên tất cả các nền tảng có thiết bị đầu cuối ảo, bao gồm cả linux và BSD, Xserver vẫn giữ một fd mở cho thiết bị đầu cuối mà nó đang chạy. Trên linux, nó vẫn là một giải pháp tốt để kiểm tra thiết bị đầu cuối kiểm soát của quy trình X để phân biệt giữa nhiều quy trình X (sử dụng trường thứ bảy của /proc/<..>/stat). Mặc dù vậy, nhìn chung hơn, hãy xem qua danh sách các fds mở của quy trình X và nó chỉ cần một số bộ lọc đơn giản để thoát khỏi thiết bị đầu cuối mà Xserver đang chạy. (Thật không may, việc nhận danh sách các fds mở lại phụ thuộc vào nền tảng ...) Đối với các sysctlnền tảng như BSD, mã sẽ trông giống như thế này, cộng với một số xử lý lỗi:

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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.