創建一個偽裝成TTY 的程式
在許多情況下,程式會仔細檢查stdin 的性質,辨別它是否是終端( TTY)或使用特殊功能(如isatty)的管道。這種區別促使程式以不同的方式產生輸出。為了應對這項挑戰,我們將探索如何建立一個能夠偽裝成 TTY 的計畫。
適用於 Linux 和 macOS 的解決方案
下面的程式碼片段舉例說明適用於 Linux 和 macOS 的可行解決方案。它利用pty 接口,提供在偽終端中運行命令的功能,有效地欺騙程序將輸入解釋為來自TTY:
#include <signal.h> #include <stdlib.h> #include <sysexits.h> #include <unistd.h> #include <util.h> pid_t child = 0; void sighandler(int signum) { if (child > 0) { killpg(child, signum); exit(signum); } } int main(int argc, char *argv[]) { if (argc < 2) { return EX_USAGE; } int master; child = forkpty(&master, NULL, NULL, NULL); // Forkpty setup: master (parent) and child (command execution) if (child == -1) { perror("failed to fork pty"); return EX_OSERR; } if (child == 0) { execvp(argv[1], argv + 1); // Execute the specified command within the pty } signal(SIGHUP, sighandler); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); // Trap signals and forward them to the child const int buf_size = 1024; char buf[buf_size]; fd_set fds; ssize_t bytes_read; // I/O management variables while (1) { FD_ZERO(&fds); FD_SET(master, &fds); // Set up file descriptor set and monitor master (pty) if (select(master + 1, &fds, NULL, NULL, NULL) > 0 && FD_ISSET(master, &fds)) { bytes_read = read(master, buf, buf_size); if (bytes_read <= 0) { return EXIT_SUCCESS; } if (write(STDOUT_FILENO, buf, bytes_read) != bytes_read) { perror("failed to write to stdout"); return EX_OSERR; } } } }
此代碼在父進程之間建立通信通道和一個在pty 中運行的子進程。父進程不斷地從 pty 讀取並將其內容轉發到 stdout,從而有效地模擬常規 TTY 的行為。
實作此方法可讓您的程式繞過需要來自 TTY 輸入的程式所施加的潛在約束。它使您的程式能夠操作和轉換輸入,同時仍保留終端的外觀。
以上是如何在 Linux 和 macOS 上建立模擬終端機 (TTY) 的程式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!