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 中国語 Web サイトの他の関連記事を参照してください。