如何在不更改标准输入缓冲的情况下 fork-then-execve?

Posted

技术标签:

【中文标题】如何在不更改标准输入缓冲的情况下 fork-then-execve?【英文标题】:How do you fork-then-execve without changing buffering on stdin? 【发布时间】:2021-07-18 13:29:13 【问题描述】:

我正在构建一个应用程序,它使用 replxx 或 libedit 从终端读取一行,以及制表符完成。为了使 replxx 和 libedit 工作,每个库都将 stdio 置于原始无缓冲模式,以便键绑定工作。

在制表符补全期间,工具以类似于 bash 补全的方式执行。在 fork 和 execve 之后,父应用程序通过管道与工具通信,这一切正常。

一旦工具完成执行,就会出现问题 - 在父应用程序中,stdin 已丢失其原始无缓冲设置并恢复为行缓冲。这会破坏 replxx 和 libedit,它们在按下 enter 之前一直保持冻结状态,然后赶上所有行缓冲的按键。

代码需要做什么(或避免做什么)来分叉,然后执行,以使父级中的标准输入保持不变?

最具体地说,在子进程中关闭标准输入是否对父进程中的标准输入在缓冲方面有任何影响?

代码在 Linux/MacOS 上使用 Apache Portable Runtime,如下所示:

apr_procattr_create(&procattr, first->pool);
apr_file_pipe_create_ex(&ioread, &iowrite, APR_FULL_BLOCK,
            first->pool);
apr_procattr_child_in_set(procattr, NULL, NULL);
apr_procattr_child_out_set(procattr, NULL, NULL);
apr_procattr_child_err_set(procattr, NULL, NULL);
apr_procattr_dir_set(procattr, command->r.sysconf);
apr_procattr_cmdtype_set(procattr, APR_PROGRAM);
proc = apr_pcalloc(first->pool, sizeof(apr_proc_t));
apr_proc_create(proc, command->r.libexec, (const char* const*) argv->elts,
               device_environment_make(d), procattr, first->pool);
apr_file_close(proc->in);
apr_file_close(proc->err);

[do stuff that reads proc->out]

apr_file_close(proc->out);
apr_proc_wait(proc, NULL, NULL, APR_WAIT);

【问题讨论】:

您可以谈论两种不同类型的缓冲:您是指流的类型(块、行或无),还是终端的类型(熟/规范或原始/非规范)? 不知道,所以是这个问题。 replxx 使用 tcsetattr() 将其描述为原始模式,而 APR 使用文件描述符(打开/读取/关闭)而不是 FILE*。不确定他们会如何互动。 【参考方案1】:

当前replxx 在每次回调返回后重置原始模式终端设置。

【讨论】:

以上是关于如何在不更改标准输入缓冲的情况下 fork-then-execve?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改输入内容的情况下更改输入值

HTML:如何在不缓冲所有声音数据的情况下从 URL 中间文件开始声音播放

Excel 2010:如何在不修改其输入值的情况下跨多个单元格更改公式?

如何在不读取标准输入的情况下使用“npm login”设置 npm 凭据?

如何在不更改选择框值的情况下选择选择框时更改html中的输入框值

如何在不知道小部件的字体系列/大小的情况下更改小部件的字体样式?