将文件描述符从“open_memstream”传递到“dup2”
Passing a file descriptor from `open_memstream` to `dup2`
我正在尝试将 exec()
ed 函数的输出重定向到缓冲区,所以我会尝试使用 open_memstream
来处理动态缓冲
我把这个放在一起测试一下:
#include <stdio.h>
#include <unistd.h>
int main() {
char* buffer;
size_t buffer_len;
FILE* stream = open_memstream(&buffer, &buffer_len);
if(!stream) perror("Something went wrong with `open_memstream`!");
fflush(stream);
puts("Start");
if(dup2(fileno(stream), STDOUT_FILENO) == -1) perror("Something went wrong!");
puts("Internal");
fclose(stream);
FILE* f = fopen("out.txt", "w+");
fputs(buffer, f);
fclose(f);
}
但是 运行 它在 dup2
上给了我错误 bad file descriptor
,这不应该是这样的,因为 open_memstream
没有 return NULL
它应该在错误时执行的操作。
关于 open_memstream
的实现是否有一些东西使得操纵其底层描述符变得不可行?还是我只是愚蠢而错误地使用了一个函数?
提前为任何帮助干杯,如果 不可能用 open_memstream
做,有没有办法用 FILE*
处理它而不是直接使用 fds?
您应该在 每个 可能出错的操作之后检查 return 值(以及随后的 errno
)。在这里,您缺少对 fileno(stream)
return 值的检查。
FILE* stream = open_memstream(&buffer, &buffer_len);
if(!stream) perror("Failed to open_memstream");
int fd = fileno(stream);
if (fd == -1) {
perror("Failed to get memstream fileno");
exit(1);
}
当您添加以上内容时,您的程序将失败并显示消息
Failed to get memstream fileno: Bad file descriptor
问题的评论中已经解释了失败的原因。
查看带有 O_TMPFILE
参数的 open
,或查看 memfd_create
,它与 open_memstream
相似,但 return 是一个文件描述符。
这些方法迫使您放弃 &buffer
、&buffer_len
带来的便利。但实际上什么都没有丢失。可以使用 lseek
了解 tmp 文件大小,然后 mmap
将其作为内存缓冲区进行访问,从而恢复所有便利。
我正在尝试将 exec()
ed 函数的输出重定向到缓冲区,所以我会尝试使用 open_memstream
来处理动态缓冲
我把这个放在一起测试一下:
#include <stdio.h>
#include <unistd.h>
int main() {
char* buffer;
size_t buffer_len;
FILE* stream = open_memstream(&buffer, &buffer_len);
if(!stream) perror("Something went wrong with `open_memstream`!");
fflush(stream);
puts("Start");
if(dup2(fileno(stream), STDOUT_FILENO) == -1) perror("Something went wrong!");
puts("Internal");
fclose(stream);
FILE* f = fopen("out.txt", "w+");
fputs(buffer, f);
fclose(f);
}
但是 运行 它在 dup2
上给了我错误 bad file descriptor
,这不应该是这样的,因为 open_memstream
没有 return NULL
它应该在错误时执行的操作。
关于 open_memstream
的实现是否有一些东西使得操纵其底层描述符变得不可行?还是我只是愚蠢而错误地使用了一个函数?
提前为任何帮助干杯,如果 不可能用 open_memstream
做,有没有办法用 FILE*
处理它而不是直接使用 fds?
您应该在 每个 可能出错的操作之后检查 return 值(以及随后的 errno
)。在这里,您缺少对 fileno(stream)
return 值的检查。
FILE* stream = open_memstream(&buffer, &buffer_len);
if(!stream) perror("Failed to open_memstream");
int fd = fileno(stream);
if (fd == -1) {
perror("Failed to get memstream fileno");
exit(1);
}
当您添加以上内容时,您的程序将失败并显示消息
Failed to get memstream fileno: Bad file descriptor
问题的评论中已经解释了失败的原因。
查看带有 O_TMPFILE
参数的 open
,或查看 memfd_create
,它与 open_memstream
相似,但 return 是一个文件描述符。
这些方法迫使您放弃 &buffer
、&buffer_len
带来的便利。但实际上什么都没有丢失。可以使用 lseek
了解 tmp 文件大小,然后 mmap
将其作为内存缓冲区进行访问,从而恢复所有便利。