内存映射文件时“fd无法读取或写入”

问题描述 投票:1回答:1

我正在尝试将数据写入Rust中的内存映射文件,但它不会对指定文件进行内存映射,因为它表明给定的fd不可用。

我可以在文件系统上看到它,因此它确实存在正确的权限。我怀疑这是一个错误,或者我没有以正确的方式使用新的IO API。

mmap err = fd not available for reading or writing

这是代码

use std::fs::File;
use std::os::MemoryMap;
use std::os::unix::prelude::AsRawFd;
use std::os::MapOption::{MapFd, MapWritable, MapReadable};

fn main() {
    let f = File::create("test.dat").unwrap();
    f.set_len(n as u64);

    let fd = f.as_raw_fd();

    let mmap = MemoryMap::new(n, &[MapReadable, MapWritable, MapFd(fd)]);

    match mmap {
        Ok(_) => println!("mmap success"),
        Err(ref err) => println!("mmap err = {}", err),
    }
}
rust
1个回答
2
投票

使用File::create创建的文件处于只写模式,但您尝试映射文件以进行读取和写入。使用OpenOptions获取两种模式的文件:

#![feature(os, std_misc)]

use std::fs::OpenOptions;
use std::os::MemoryMap;
use std::os::unix::prelude::AsRawFd;
use std::os::MapOption::{MapFd, MapReadable, MapWritable};

fn main() {
    let n = 100;

    let f = OpenOptions::new()
        .read(true)
        .write(true)
        .truncate(true)
        .create(true)
        .open("test.dat")
        .unwrap();

    f.set_len(n as u64).unwrap();

    let fd = f.as_raw_fd();

    let mmap = MemoryMap::new(n, &[MapReadable, MapWritable, MapFd(fd)]);

    match mmap {
        Ok(_) => println!("mmap success"),
        Err(err) => println!("mmap err = {}", err),
    }
}

我想通了

  1. 将“fd无法读取或写入”的代码打包,导致this line,与ErrFdNotAvail对齐(也可以将mmap err = {}更改为mmap err = {:?})。
  2. 搜索该枚举变量会导致this line,它会映射底层的libc::EACCES错误。
  3. 检查了man page for mmap,看看EACCES说的是什么:

标志PROT_READ被指定为prot参数的一部分,fd未打开以供阅读。标志MAP_SHARED和PROT_WRITE被指定为flags和prot参数的一部分,fd未打开以进行写入。

© www.soinside.com 2019 - 2024. All rights reserved.