使用 fcntl 从 stdout 创建新文件描述符在文件中失败

标签 c raku openbsd nativecall

我有一个简单的测试文件,如下所示:

use v6.c;
use NativeCall;

sub fcntl(int32, int32 --> int32) is native { * }
sub close(int32 --> int32) is native { * }

my $fd := fcntl($*OUT.native-descriptor, 0);
say $fd;
close($fd);

返回的文件描述符是-1,这不是我想要的。但是当我在 REPL 中运行相同的代码时,我得到了我要找的东西:

> use NativeCall
Nil
> sub fcntl(int32, int32 --> int32) is native { * }
sub fcntl (int32 $, int32 $ --> int32) { #`(Sub+{Callable[int32]}+{NativeCall::Native[Sub+{Callable[int32]},Str]}|17126514527616) ... }
> sub close(int32 --> int32) is native { * }
sub close (int32 $ --> int32) { #`(Sub+{Callable[int32]}+{NativeCall::Native[Sub+{Callable[int32]},Str]}|17126514527904) ... }
> my $fd := fcntl($*OUT.native-descriptor, 0)
15
> say $fd
15
> close($fd)
0

为什么 fcntl 不像在 REPL 中那样在文件中创建一个新的文件描述符?

编辑:我正在运行 OpenBSD 6.2,Rakudo 2018.02

最佳答案

使用 F_DUPFD flag 时对于 fcntl(为 0),OpenBSD 要求将原始文件描述符的状态标志也传递给新文件描述符。所以这会起作用:

use v6.c;
use NativeCall;

constant F_DUPFD = 0;
constant F_GETFD = 1;

sub fcntl(int32, int32, int32 --> int32) is native { * }
sub close(int32 --> int32) is native { * }

sub MAIN() {
    my $out-fd := $*OUT.native-descriptor;
    my $flags  := fcntl($out-fd, F_GETFD, 0);
    my $fd     := fcntl($out-fd, F_DUPFD, $flags);
    say $fd; # 15
    close($fd);
}

关于使用 fcntl 从 stdout 创建新文件描述符在文件中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49574786/

相关文章:

concurrency - .race 或 .hyper 何时优于非数据并行化版本?

java - openbsd:限制网络带宽

c - 如何在 OpenBSD 5.8 中使用 makefile

c - 哪些特定的优化标志负责优化变量

c - 为什么fwrite写的东西很奇怪?

看不到指针的实际值

c - scanf() 的返回值

raku - Perl 6 的 DEFINITE 和定义的方法有什么区别?

MoarVM 中的字符串和链

sockets - IPv6:为什么 IPv4 映射地址存在安全风险?