创建一个伪装成 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中文网其他相关文章!