gpt4 book ai didi

c - 写入 `forkpty`子进程: `less` pager

转载 作者:行者123 更新时间:2023-11-30 14:59:18 27 4
gpt4 key购买 nike

我正在尝试使用forkptyexecvpless分页程序,然后从父进程中写入一些文本,这样子 less 进程将其作为其输入的方式。

我一直在研究如何实现这一点,但我无法使用 forkpty 来实现某些功能,而我却使用 pipe > fork

发生的情况是我看不到任何输出,然后程序正常退出。

编辑:我注意到,如果我在 forkpty 之后从 master 读取内容,我会看到 less 中的“缺少文件名(“less --help”寻求帮助)” ,但是怎么会$ echo test | less,那么工作正常吗?更改 exec_argv 以将 "-" 传递给 less 仍然存在相同的原始问题(无输出)。

我是否遗漏了一些明显的东西?

使用pipefork的工作代码

#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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com