Trong Unix như hệ điều hành, đầu vào, đầu ra và báo lỗi dòng tiêu chuẩn được xác định bởi các file descriptor 0
, 1
, 2
. Trên Linux, chúng được hiển thị dưới proc
hệ thống tập tin trong /proc/[pid]/fs/{0,1,2}
. Những tập tin này thực sự là các liên kết tượng trưng cho một pseudoterminal thiết bị theo các /dev/pts
thư mục.
Pseudoterminal (PTY) là một cặp thiết bị ảo, một chủ giả giả (PTM) và một nô lệ giả da (PTS) (gọi chung là cặp giả ngẫu nhiên ), cung cấp một kênh IPC, giống như một ống hai chiều được kết nối với thiết bị đầu cuối và chương trình trình điều khiển sử dụng mã giả để gửi đầu vào và nhận đầu vào từ chương trình cũ.
Một điểm quan trọng là nô lệ giả xuất hiện giống như một thiết bị đầu cuối thông thường, ví dụ: nó có thể được chuyển đổi giữa chế độ phi núi và chính tắc (mặc định), trong đó nó diễn giải một số ký tự đầu vào, như tạo SIGINT
tín hiệu khi một ký tự ngắt (thường được tạo bằng cách nhấn Ctrl+ Ctrên bàn phím) được ghi vào bản gốc giả hoặc khiến phần tiếp theo read()
quay trở lại 0
khi gặp ký tự cuối tệp (thường được tạo bởi Ctrl+ D). Các hoạt động khác được hỗ trợ bởi các thiết bị đầu cuối đang bật hoặc tắt tiếng vang, thiết lập nhóm quy trình tiền cảnh, v.v.
Giả hành có một số cách sử dụng:
Chúng cho phép các chương trình muốn ssh
vận hành các chương trình định hướng đầu cuối trên một máy chủ khác được kết nối qua mạng. Một chương trình định hướng thiết bị đầu cuối có thể là bất kỳ chương trình nào, thường sẽ được chạy trong phiên thiết bị đầu cuối tương tác. Đầu vào, đầu ra và lỗi tiêu chuẩn của một chương trình như vậy không thể được kết nối trực tiếp với ổ cắm, vì các ổ cắm không hỗ trợ các chức năng liên quan đến thiết bị đầu cuối nói trên.
Chúng cho phép các chương trình muốn expect
lái một chương trình định hướng đầu cuối tương tác từ một tập lệnh.
Chúng được sử dụng bởi các trình giả lập thiết bị đầu cuối như xterm
để cung cấp chức năng liên quan đến thiết bị đầu cuối.
Chúng được sử dụng bởi các chương trình như screen
ghép kênh một thiết bị đầu cuối vật lý duy nhất giữa nhiều quy trình.
Chúng được sử dụng bởi các chương trình như script
để ghi lại tất cả đầu vào và đầu ra xảy ra trong một phiên shell.
Các PTY kiểu Unix98 , được sử dụng trong Linux, được thiết lập như sau:
Chương trình trình điều khiển mở bộ ghép kênh chính giả thiết bị đầu cuối tại dev/ptmx
, tại đó nó nhận được một mô tả tệp aa cho PTM, và một thiết bị PTS được tạo trong /dev/pts
thư mục. Mỗi mô tả tệp thu được bằng cách mở /dev/ptmx
là một PTM độc lập với PTS được liên kết riêng.
Các chương trình điều khiển gọi fork()
để tạo một tiến trình con, lần lượt thực hiện các bước sau:
Đứa trẻ gọi setsid()
để bắt đầu một phiên mới, trong đó đứa trẻ là người lãnh đạo phiên. Điều này cũng khiến đứa trẻ mất thiết bị đầu cuối kiểm soát của nó .
Đứa trẻ tiến hành mở thiết bị PTS tương ứng với PTM được tạo bởi chương trình trình điều khiển. Vì đứa trẻ là người lãnh đạo phiên, nhưng không có thiết bị đầu cuối kiểm soát, PTS trở thành thiết bị đầu cuối kiểm soát trẻ em.
Đứa trẻ sử dụng dup()
để sao chép bộ mô tả tệp cho thiết bị nô lệ trên đầu vào, đầu ra và lỗi tiêu chuẩn.
Cuối cùng, đứa trẻ gọi exec()
để bắt đầu chương trình định hướng thiết bị đầu cuối được kết nối với thiết bị giả.
Tại thời điểm này, bất cứ điều gì chương trình trình điều khiển ghi vào PTM, sẽ xuất hiện dưới dạng đầu vào cho chương trình định hướng đầu cuối trên PTS và ngược lại.
Khi hoạt động ở chế độ chính tắc, đầu vào của PTS được đệm theo từng dòng. Nói cách khác, giống như với các thiết bị đầu cuối thông thường, chương trình đọc từ PTS chỉ nhận được một dòng đầu vào khi một ký tự dòng mới được ghi vào PTM. Khi hết dung lượng bộ đệm, write()
khối cuộc gọi tiếp tục cho đến khi một số đầu vào đã được sử dụng.
Trong hạt nhân Linux, các tập tin liên quan đến các cuộc gọi hệ thống open()
, read()
, write()
stat()
vv được thực hiện trong hệ thống tập tin (VFS) lớp ảo, cung cấp một giao diện hệ thống tập tin thống nhất cho các chương trình không gian người dùng. VFS cho phép các cài đặt hệ thống tệp khác nhau cùng tồn tại trong nhân. Khi các chương trình không gian người dùng gọi các cuộc gọi hệ thống đã nói ở trên, VFS sẽ chuyển hướng cuộc gọi đến việc thực hiện hệ thống tệp thích hợp.
Các thiết bị PTS bên dưới /dev/pts
được quản lý bởi việc devpts
triển khai hệ thống tệp được xác định trong /fs/devpts/inode.c
, trong khi trình điều khiển TTY cung cấp ptmx
thiết bị kiểu Unix98 được xác định trong drivers/tty/pty.c
.
Việc đệm giữa các thiết bị TTY và các quy tắc dòng TTY , chẳng hạn như giả, được cung cấp cấu trúc bộ đệm được duy trì cho mỗi thiết bị tty, được xác định tronginclude/linux/tty.h
Trước phiên bản kernel 3.7, bộ đệm là bộ đệm lật :
#define TTY_FLIPBUF_SIZE 512
struct tty_flip_buffer {
struct tq_struct tqueue;
struct semaphore pty_sem;
char *char_buf_ptr;
unsigned char *flag_buf_ptr;
int count;
int buf_num;
unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
char flag_buf[2*TTY_FLIPBUF_SIZE];
unsigned char slop[4];
};
Cấu trúc chứa lưu trữ được chia thành hai bộ đệm kích thước bằng nhau. Các bộ đệm được đánh số 0
(nửa đầu char_buf/flag_buf
) và 1
(nửa sau). Trình điều khiển lưu dữ liệu vào bộ đệm được xác định bởi buf_num
. Các bộ đệm khác có thể được tuôn ra theo kỷ luật dòng.
Bộ đệm đã được 'lật' bằng cách chuyển đổi buf_num
giữa 0
và 1
. Khi được buf_num
thay đổi char_buf_ptr
và flag_buf_ptr
được đặt thành phần đầu của bộ đệm được xác định bởi buf_num
và count
được đặt thành 0
.
Kể từ phiên bản kernel 3.7, bộ đệm lật TTY đã được thay thế bằng các đối tượng được phân bổ thông qua kmalloc()
tổ chức theo vòng . Trong một tình huống bình thường đối với một cổng nối tiếp điều khiển IRQ ở tốc độ điển hình, hành vi của chúng khá giống với bộ đệm lật cũ; hai bộ đệm cuối cùng được phân bổ và các chu kỳ kernel giữa chúng như trước đây. Tuy nhiên, khi có độ trễ hoặc tốc độ tăng, việc thực hiện bộ đệm mới hoạt động tốt hơn vì vùng đệm có thể tăng lên một chút.