gpt4 book ai didi

c - pipe2(...) vs pipe() + fcntl(...),为什么不同?

转载 作者:太空宇宙 更新时间:2023-11-04 02:32:00 25 4
gpt4 key购买 nike

我正在尝试构建一个可再分发的二进制文件以放置在只有 glibc 2.3 的旧 NAS 上。所以pipe2()该机器上不可用,但我尝试构建的代码包含以下行:

if (pipe2(info_pipe, O_CLOEXEC | O_NONBLOCK) < 0)
goto info_pipe_err;

我的理解是 pipe2() 存在的原因是通过采用 O_CLOEXEC | 来避免竞争条件。 O_NONBLOCK 在打开时与分两步进行。但是我正在查看的案例中没有线程,所以我想我可以替换为:

if (pipe(info_pipe) < 0)
goto info_pipe_err;

int direction; // 0=READ, 1=WRITE
for (direction = 0; direction < 2; ++direction) {
int oldflags;
oldflags = fcntl(info_pipe[direction], F_GETFL);

if (oldflags < 0)
goto info_pipe_err;

if (fcntl(info_pipe[direction],
F_SETFL, oldflags | O_NONBLOCK | O_CLOEXEC) < 0)
goto info_pipe_err;
}

但它似乎不可互换,因为代码不起作用。为什么这不等价?

最佳答案

(回答我自己的问题,因为我想通了,只是在这里发布以供后代使用。)

如果您在较新的编译器上为较旧的系统构建二进制文件,该运行时可能不知道 O_CLOEXEC 的值,因为该标志是通过 pipe2()< 引入的。如果它知道什么,它就知道 FD_CLOEXEC。并且您不使用 F_SETFL 进行设置,而是使用 F_SETFD,这是一个单独的 fcntl() 调用。

以下替换应该有效:

if (pipe(info_pipe) < 0)
goto info_pipe_err;

int direction; // 0=READ, 1=WRITE
for (direction = 0; direction < 2; ++direction) {
int oldflags;
oldflags = fcntl(info_pipe[direction], F_GETFL);

if (oldflags < 0)
goto info_pipe_err;

if (fcntl(info_pipe[direction],
F_SETFL, oldflags | O_NONBLOCK) < 0)
goto info_pipe_err;

oldflags = fcntl(info_pipe[direction], F_GETFD);
if (oldflags < 0)
goto info_pipe_err;

if (fcntl(info_pipe[direction],
F_SETFD, oldflags | FD_CLOEXEC) < 0)
goto info_pipe_err;
}

如前所述,这没有 pipe2() 提供的线程安全方面允许所有这些同时完成。

关于c - pipe2(...) vs pipe() + fcntl(...),为什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41976446/

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