6

我希望能够将内存映射到文件描述符,这样我就可以使用一些需要文件描述符的现有函数。这基本上是我正在寻找的东西:

void do_operation1(int fd);

char data[DATA_MAX] = { /* embedded binary data */ };
int fd = addr_to_fd(data, DATA_MAX);

do_operation1(fd);
/* ... operate on fd ... */

我可以使用什么系统调用或调用来完成此操作?

4

4 回答 4

7

一些实现具有fmemopen(). (那么当然你必须打电话fileno())。

如果您没有,您可以使用fork()and自己构建它pipe()

于 2010-05-12T19:23:33.427 回答
3

你应该检查出来shm_open()

于 2010-10-01T05:24:09.813 回答
2

当然,只需open(argv[0], ...)扫描文件以查找二进制数据的开始位置、lseek()完成位置。该文件当然不会有您的二进制数据的长度。

于 2011-11-08T17:24:20.593 回答
1

您不能将“一些现有的内存缓冲区”映射到文件描述符。正如上面评论中所说,该fmemopen()函数将内存缓冲区与“FILE *”流指针相关联,该指针可以使用 libc 提供的流函数进行操作。未分配文件描述符:“FILE *”流是高级抽象,与作为低级句柄的文件描述符不兼容。

相反,您可能希望分配一个新的共享内存缓冲区并将其映射到文件描述符。这被广泛使用,在 Linux 术语中被称为“内存映射文件”。

您可以使用通过open()引用文件获得的文件描述符或通过shm_open()引用共享内存对象获得的文件描述符。任何文件描述符句柄都可以完成这项工作。然后,您可以调用mmap()以将文件描述符映射到共享内存缓冲区。

注意:mmap()如果文件描述符引用非常规文件,例如管道、套接字或字符设备文件(例如,/dev/ttys001),则会失败。因此,您通常无法为 STDIN、STDOUT 或 STDERR 文件描述符创建内存映射文件。

您可以以类似数组的方式操作内存缓冲区,并将对内存映射文件的修改提交到磁盘。反之亦然,对文件所做的任何修改(例如,使用write()系统调用)也会提交到内存。


以下代码段打开您选择的文件并将其映射到内存中。它将打印前 256 个字符并将它们替换为原始文件中的“*”。cc mmap_test.c -o mmap_test在符合 POSIX 的系统上编译它。

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int main(int ac, char *av[])
{
    int pagesize, fd;
    unsigned char *data;

    if ( ac < 2 ) {
        printf("Usage: %s <filepath>\n", av[0]);
        return 1;
    }

    pagesize = getpagesize();

    if ( (fd = open(av[1], O_RDWR)) == -1 ) {
        perror("Error: cannot open file for reading");
        return 1;
    }

    if ( (data = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED ) {
        perror("Error: cannot create memory-mapped file");
        return 1;
    }

    write(1, data, 256);
    memset(data, '*', 256);

    return 0;
}
于 2021-11-16T18:32:13.837 回答