我正在尝试使用forkpty
来execvp
less
分页程序,然后从父进程中写入一些文本,这样子 less
进程将其作为其输入的方式。
我一直在研究如何实现这一点,但我无法使用 forkpty
来实现某些功能,而我却使用 pipe
和 > fork
。
发生的情况是我看不到任何输出,然后程序正常退出。
编辑:我注意到,如果我在 forkpty
之后从 master
读取内容,我会看到 less 中的“缺少文件名(“less --help”寻求帮助)”
,但是怎么会$ echo test | less
,那么工作正常吗?更改 exec_argv
以将 "-"
传递给 less
仍然存在相同的原始问题(无输出)。
我是否遗漏了一些明显的东西?
使用pipe
和fork
的工作代码
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
int read_write_fds[2];
if (pipe(read_write_fds) == -1) {
perror("pipe");
return EXIT_FAILURE;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return EXIT_FAILURE;
}
if (!pid) {
if (close(read_write_fds[1]) == -1) {
perror("CHILD: close write");
return EXIT_FAILURE;
}
if (dup2(read_write_fds[0], STDIN_FILENO) == -1) {
perror("CHILD: dup2 read STDIN_FILENO");
return EXIT_FAILURE;
}
if (close(read_write_fds[0]) == -1) {
perror("CHILD: close read");
return EXIT_FAILURE;
}
char* exec_argv[] = {"less", NULL};
execvp(exec_argv[0], exec_argv);
perror("CHILD: execvp");
return EXIT_FAILURE;
}
if (close(read_write_fds[0]) == -1) {
perror("PARENT: close read");
return EXIT_FAILURE;
}
char text[] = "Hello, world!\n";
char* text_ptr = text;
size_t bytes_left = sizeof(text) - 1;
while (bytes_left > 0) {
ssize_t bytes_written = write(read_write_fds[1], text_ptr, bytes_left);
if (bytes_written == -1) {
perror("PARENT: write");
return EXIT_FAILURE;
}
bytes_left -= bytes_written;
text_ptr += bytes_written;
}
if (close(read_write_fds[1]) == -1) {
perror("PARENT: close write");
return EXIT_FAILURE;
}
if (waitpid(pid, NULL, 0) == -1) {
perror("PARENT: waitpid");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
使用forkpty
的非工作代码
#include <sys/types.h>
#include <pty.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
int master;
pid_t pid = forkpty(&master, NULL, NULL, NULL);
if (pid == -1) {
perror("forkpty");
return EXIT_FAILURE;
}
if (!pid) {
char* exec_argv[] = {"less", NULL};
execvp(exec_argv[0], exec_argv);
perror("CHILD: execvp");
return EXIT_FAILURE;
}
char text[] = "Hello, world!\n";
char* text_ptr = text;
size_t bytes_left = sizeof(text) - 1;
while (bytes_left > 0) {
ssize_t bytes_written = write(master, text_ptr, bytes_left);
if (bytes_written == -1) {
perror("PARENT: write");
return EXIT_FAILURE;
}
bytes_left -= bytes_written;
text_ptr += bytes_written;
}
if (close(master) == -1) {
perror("PARENT: close");
return EXIT_FAILURE;
}
if (waitpid(pid, NULL, 0) == -1) {
perror("PARENT: waitpid");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
最佳答案
(小问题:在 fork()
之后的子进程中,您应该使用 _exit()
。)
您在此处看不到输出的原因是因为子进程的 stdin、stdout 和 stderr 都附加到新的 PTY。您需要从 master 读取数据并对数据执行某些操作。
关于c - 写入 `forkpty`子进程: `less` pager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42881519/