2010-07-06 28 views
5

Vì vậy, tôi có một tty (giả sử/dev/tty5) và muốn biết liệu nó hiện là một nhóm kiểm soát của một nhóm hoặc phiên xử lý hay không hiện không được công nhận. POSIX có hai hàm API tự đề xuất ở đây: tcgetpgrp() và tcgetsid(), cả hai đều chỉ hoạt động nếu người gọi có tty như kiểm soát tty - mà trong trường hợp này làm cho chúng hầu như vô dụng (và trên thực tế tôi don ' t thấy điểm của tcgetsid() ở tất cả).Làm thế nào để tìm ra liệu một TTY Linux có đang kiểm soát một nhóm quá trình

Bất kỳ ai có đề xuất làm cách nào tôi có thể phát hiện theo cách sane, từ C, cho dù thiết bị đầu cuối hiện có là thiết bị đầu cuối điều khiển của quy trình không? Tôi chỉ quan tâm đến Linux, do đó, nếu các API cụ thể của Linux là cần thiết thì tốt với tôi.

Trả lời

1

BSD: int ioctl (int tty, TIOCGETPGRP, int * foreground_group);

Linux: int tcgetpgrp (int tty, int * foreground_group);

Linux chỉ hoạt động nếu bạn cấp quyền cho thiết bị đầu cuối không thuộc sở hữu, tức là bạn là người chủ. Đây là một thực hiện an ninh có chủ ý. BSD ioctl() cho phép bất kỳ tty nào đưa vào bất kỳ nhóm tiến trình nào (hoặc thậm chí cả các nhóm quá trình không tồn tại) như là tty tiền cảnh của nó. POSIX cho phép truy cập chỉ để xử lý các nhóm có tty như tty kiểm soát của chúng. Giới hạn này không cho phép một số trường hợp không rõ ràng và bảo mật phá hoại hiện diện trong BSD ioctl.

Bạn đang cố gắng làm gì? Bạn chỉ nên lo lắng về quá trình kiểm soát tty nếu bạn là hạt nhân cung cấp tín hiệu.

Edit: Tôi quên/proc
Từ www.die.net: /proc/[số]/fd Đây là một thư mục con có chứa một mục nhập cho mỗi tập tin mà quá trình này có mở, được đặt tên bởi mô tả tập tin của mình và là liên kết tượng trưng cho tệp thực. Do đó, 0 là đầu vào tiêu chuẩn, 1 đầu ra tiêu chuẩn, 2 lỗi tiêu chuẩn, v.v.

+0

Trong câu hỏi ban đầu của tôi, tôi đã cố gắng giải thích tại sao tcgetpgrp() hầu như là vô dụng. Lý do tôi muốn điều này chỉ đơn giản là để tìm ra cho dù một getty hoặc như vậy đã hoạt động trên một thiết bị đầu cuối. Tôi không quan tâm đến các quá trình khác có TTY mở để viết (có thể xảy ra cho việc đăng nhập, yadda yadda), tôi muốn biết liệu có ai đó đang đọc/kiểm soát nó không. Và thông qua/proc a la lsof không phải là những gì tôi gọi là "sane" ... – user175104

+0

Tất cả điều này có. Trừ khi bạn truy cập dữ liệu chế độ hạt nhân, hoặc bạn là người chủ, bạn không thể làm những gì bạn mô tả với các cuộc gọi chế độ người dùng. Không phải trong Linux. Lý do: bảo mật. Và tôi xin lỗi nếu nó xúc phạm định nghĩa của bạn về lành mạnh. Đưa nó lên với Ulrich Drepper. –

0

Thực hiện điều này dưới dạng gọi hệ thống "ps au> tempfile.txt" và phân tích cú pháp tệp.

0

Không chắc nếu điều này chính xác bắt nhu cầu của bạn, dù sao ở đây nó là:

#include <stdlib.h> 
#include <stdio.h> 

int main() 
{ 
    int status = system("fuser /dev/tty1 >/dev/null 2>/dev/null") >> 8; 
    printf("%s", 
     status ? 
      "tty not in use as a text terminal.\n" : 
      "tty in use as a text terminal.\n"); 
    return 0; 
} 
+0

rằng quá trình 'fuser' có thể gọi một số chức năng thư viện C một lần nữa .. Tại sao không gọi hàm đó trực tiếp trong chương trình của bạn? : p – vdboor

+0

@ 'vbdoor': một hàm thư viện C tương đương với' fuser' không tồn tại. 'fuser' là một chương trình Linux thực hiện nhiều cuộc gọi thư viện:' sed -n 's/^ \ (. * \) (. */\ 1/g; p' <<(ltrace fuser/dev/tty1 2) > & 1) | Sắp xếp -u' đầu ra trên máy tính của tôi là: 'bindtextdomain close closedir fclose fgets fopen64 miễn phí __fxstat64 getpid __libc_start_main malloc opendir readdir64 setlocale __snprintf_chk socket sscanf strchr __strdup strtol textdomain __xstat64'. :) –

0

bạn có thể sử dụng hệ thống tập tin proc để truy vấn tty kiểm soát của một quá trình, nếu bạn biết PID của tiến trình.

/proc // fd/0 là liên kết tượng trưng đến tty (nói/dev/pts/4).

Vì vậy, tất cả các bạn cần làm là tạo ra một con đường proc với PID (ví dụ:/proc/7834/fd/0, nơi 7834 là PID) và sau đó gọi các cuộc gọi hệ thống readlink để có được những tty

Xem đoạn mã C bên dưới

sprintf(procPath, "/proc/%s/fd/0", pid); 
int ret = readlink(procPath, buffer, MAX_LEN); 
buffer[ret] = '\0'; 
Các vấn đề liên quan